diff --git a/packages/uni-app-plus/build.json b/packages/uni-app-plus/build.json index aa560aa164aaba3365da5e199c47b8f090f65d52..600cbd8e3a3f7ea93a671f5a0589d5c0f1c5cc60 100644 --- a/packages/uni-app-plus/build.json +++ b/packages/uni-app-plus/build.json @@ -13,19 +13,9 @@ "src/service/index.ts": "dist/uni.runtime.esm.js" }, "output": { - "freeze": false, - "name": "serviceContext", - "format": "iife", - "banner": "export function createServiceContext(weex, plus, instanceContext){\nconst Vue = instanceContext.Vue;\nlet setTimeout = instanceContext.setTimeout;\nlet clearTimeout = instanceContext.clearTimeout;\nlet setInterval = instanceContext.setInterval;\nlet clearInterval = instanceContext.clearInterval;\nconst __uniConfig = instanceContext.__uniConfig;\nconst __uniRoutes = instanceContext.__uniRoutes;\nconst VueShared = instanceContext.VueShared;\n", - "footer": "const uni = serviceContext.uni;\nconst getApp = serviceContext.getApp;\nconst getCurrentPages = serviceContext.getCurrentPages;\nconst UniServiceJSBridge = serviceContext.UniServiceJSBridge;\nreturn serviceContext;\n}", - "globals": { - "vue": "Vue", - "@vue/shared": "VueShared" - }, - "inlineDynamicImports": true + "freeze": false }, "replacements": { - "__NVUE__": "false", "__PLATFORM__": "'app'", "__APP_VIEW__": "false", "__VUE_OPTIONS_API__": "true", @@ -38,7 +28,7 @@ "__UNI_FEATURE_I18N_ZH_HANS__": "true", "__UNI_FEATURE_I18N_ZH_HANT__": "true" }, - "external": ["vue", "@vue/shared"], + "external": ["vue", "@vue/shared", "@dcloudio/uni-shared"], "replaceAfterBundled": { "__VUE__": "vue" } @@ -52,5 +42,25 @@ "format": "umd" }, "external": false + }, + { + "input": { + "src/service/vue.ts": "dist/uni.vue.js" + }, + "output": {}, + "replacements": { + "__PLATFORM__": "'app'", + "__APP_VIEW__": "false", + "__VUE_OPTIONS_API__": "true", + "__VUE_PROD_DEVTOOLS__": "false", + "__UNI_FEATURE_WX__": "true", + "__UNI_FEATURE_PROMISE__": "false", + "__UNI_FEATURE_I18N_EN__": "true", + "__UNI_FEATURE_I18N_ES__": "true", + "__UNI_FEATURE_I18N_FR__": "true", + "__UNI_FEATURE_I18N_ZH_HANS__": "true", + "__UNI_FEATURE_I18N_ZH_HANT__": "true" + }, + "external": ["@dcloudio/uni-shared", "@vue/shared", "vue"] } ] diff --git a/packages/uni-app-plus/dist/uni.runtime.esm.js b/packages/uni-app-plus/dist/uni.runtime.esm.js index e913f951736018a949a3d0d88d5884e158687095..15fff4ad1b2e09099b3e0682b069ad3ec555c16b 100644 --- a/packages/uni-app-plus/dist/uni.runtime.esm.js +++ b/packages/uni-app-plus/dist/uni.runtime.esm.js @@ -1,4937 +1,4359 @@ -export function createServiceContext(weex, plus, instanceContext){ -const Vue = instanceContext.Vue; -let setTimeout = instanceContext.setTimeout; -let clearTimeout = instanceContext.clearTimeout; -let setInterval = instanceContext.setInterval; -let clearInterval = instanceContext.clearInterval; -const __uniConfig = instanceContext.__uniConfig; -const __uniRoutes = instanceContext.__uniRoutes; -const VueShared = instanceContext.VueShared; - -var serviceContext = (function (shared, vue) { - 'use strict'; +import { isArray as isArray$1, hasOwn as hasOwn$1, isString, isPlainObject, isObject as isObject$1, toRawType, capitalize, makeMap, isFunction, isPromise, extend, toTypeString } from '@vue/shared'; +import { LINEFEED, once, I18N_JSON_DELIMITERS, addLeadingSlash, resolveComponentInstance, invokeArrayFns, ON_RESIZE, ON_APP_ENTER_FOREGROUND, ON_APP_ENTER_BACKGROUND, ON_SHOW, ON_HIDE, ON_PAGE_SCROLL, ON_REACH_BOTTOM, SCHEME_RE, DATA_RE, cacheStringFunction, parseQuery, ON_ERROR, callOptions, ON_LAUNCH, PRIMARY_COLOR, removeLeadingSlash, getLen, formatLog, TABBAR_HEIGHT, NAVBAR_HEIGHT, ON_THEME_CHANGE, ON_KEYBOARD_HEIGHT_CHANGE, ON_LOAD, RENDERJS_MODULES, WXS_PROTOCOL, WXS_MODULES, UniLifecycleHooks, ON_TAB_ITEM_TAP, ACTION_TYPE_EVENT, BACKGROUND_COLOR, ON_NAVIGATION_BAR_BUTTON_TAP, stringifyQuery as stringifyQuery$1, debounce, ON_PULL_DOWN_REFRESH, ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, UniNode, NODE_TYPE_PAGE, ACTION_TYPE_PAGE_CREATE, ACTION_TYPE_PAGE_CREATED, ACTION_TYPE_PAGE_SCROLL, ACTION_TYPE_INSERT, ACTION_TYPE_CREATE, ACTION_TYPE_REMOVE, ACTION_TYPE_ADD_EVENT, ACTION_TYPE_ADD_WXS_EVENT, ACTION_TYPE_REMOVE_EVENT, ACTION_TYPE_SET_ATTRIBUTE, ACTION_TYPE_REMOVE_ATTRIBUTE, ACTION_TYPE_SET_TEXT, ON_READY, ON_UNLOAD, EventChannel, ON_REACH_BOTTOM_DISTANCE, parseUrl, createUniEvent, ON_WXS_INVOKE_CALL_METHOD, WEB_INVOKE_APPSERVICE, ON_BACK_PRESS } from '@dcloudio/uni-shared'; +import { ref, injectHook, nextTick, createVNode, render, queuePostFlushCb, getCurrentInstance, onMounted, onBeforeUnmount } from 'vue'; + +/* + * base64-arraybuffer + * https://github.com/niklasvh/base64-arraybuffer + * + * Copyright (c) 2012 Niklas von Hertzen + * Licensed under the MIT license. + */ + +var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +// Use a lookup table to find the index. +var lookup = /*#__PURE__*/ (function () { + const lookup = new Uint8Array(256); + for (var i = 0; i < chars.length; i++) { + lookup[chars.charCodeAt(i)] = i; + } + return lookup +})(); + +function encode$2(arraybuffer) { + var bytes = new Uint8Array(arraybuffer), + i, + len = bytes.length, + base64 = ''; + + for (i = 0; i < len; i += 3) { + base64 += chars[bytes[i] >> 2]; + base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; + base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; + base64 += chars[bytes[i + 2] & 63]; + } - /* - * base64-arraybuffer - * https://github.com/niklasvh/base64-arraybuffer - * - * Copyright (c) 2012 Niklas von Hertzen - * Licensed under the MIT license. - */ + if (len % 3 === 2) { + base64 = base64.substring(0, base64.length - 1) + '='; + } else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + '=='; + } - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + return base64 +} - // Use a lookup table to find the index. - var lookup = /*#__PURE__*/ (function () { - const lookup = new Uint8Array(256); - for (var i = 0; i < chars.length; i++) { - lookup[chars.charCodeAt(i)] = i; - } - return lookup - })(); - - function encode$3(arraybuffer) { - var bytes = new Uint8Array(arraybuffer), - i, - len = bytes.length, - base64 = ''; - - for (i = 0; i < len; i += 3) { - base64 += chars[bytes[i] >> 2]; - base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; - base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; - base64 += chars[bytes[i + 2] & 63]; +function decode(base64) { + var bufferLength = base64.length * 0.75, + len = base64.length, + i, + p = 0, + encoded1, + encoded2, + encoded3, + encoded4; + + if (base64[base64.length - 1] === '=') { + bufferLength--; + if (base64[base64.length - 2] === '=') { + bufferLength--; } + } - if (len % 3 === 2) { - base64 = base64.substring(0, base64.length - 1) + '='; - } else if (len % 3 === 1) { - base64 = base64.substring(0, base64.length - 2) + '=='; - } + var arraybuffer = new ArrayBuffer(bufferLength), + bytes = new Uint8Array(arraybuffer); - return base64 + for (i = 0; i < len; i += 4) { + encoded1 = lookup[base64.charCodeAt(i)]; + encoded2 = lookup[base64.charCodeAt(i + 1)]; + encoded3 = lookup[base64.charCodeAt(i + 2)]; + encoded4 = lookup[base64.charCodeAt(i + 3)]; + + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); } - function decode$1(base64) { - var bufferLength = base64.length * 0.75, - len = base64.length, - i, - p = 0, - encoded1, - encoded2, - encoded3, - encoded4; - - if (base64[base64.length - 1] === '=') { - bufferLength--; - if (base64[base64.length - 2] === '=') { - bufferLength--; - } - } + return arraybuffer +} - var arraybuffer = new ArrayBuffer(bufferLength), - bytes = new Uint8Array(arraybuffer); +const CHOOSE_SIZE_TYPES = ['original', 'compressed']; +const CHOOSE_SOURCE_TYPES = ['album', 'camera']; +const HTTP_METHODS = [ + 'GET', + 'OPTIONS', + 'HEAD', + 'POST', + 'PUT', + 'DELETE', + 'TRACE', + 'CONNECT', + 'PATCH', +]; +function elemInArray(str, arr) { + if (!str || arr.indexOf(str) === -1) { + return arr[0]; + } + return str; +} +function elemsInArray(strArr, optionalVal) { + if (!isArray$1(strArr) || + strArr.length === 0 || + strArr.find((val) => optionalVal.indexOf(val) === -1)) { + return optionalVal; + } + return strArr; +} +function validateProtocolFail(name, msg) { + console.warn(`${name}: ${msg}`); +} +function validateProtocol(name, data, protocol, onFail) { + if (!onFail) { + onFail = validateProtocolFail; + } + for (const key in protocol) { + const errMsg = validateProp(key, data[key], protocol[key], !hasOwn$1(data, key)); + if (isString(errMsg)) { + onFail(name, errMsg); + } + } +} +function validateProtocols(name, args, protocol, onFail) { + if (!protocol) { + return; + } + if (!isArray$1(protocol)) { + return validateProtocol(name, args[0] || Object.create(null), protocol, onFail); + } + const len = protocol.length; + const argsLen = args.length; + for (let i = 0; i < len; i++) { + const opts = protocol[i]; + const data = Object.create(null); + if (argsLen > i) { + data[opts.name] = args[i]; + } + validateProtocol(name, data, { [opts.name]: opts }, onFail); + } +} +function validateProp(name, value, prop, isAbsent) { + if (!isPlainObject(prop)) { + prop = { type: prop }; + } + const { type, required, validator } = prop; + // required! + if (required && isAbsent) { + return 'Missing required args: "' + name + '"'; + } + // missing but optional + if (value == null && !required) { + return; + } + // type check + if (type != null) { + let isValid = false; + const types = isArray$1(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) { + return getInvalidTypeMessage(name, value, expectedTypes); + } + } + // custom validator + if (validator) { + return validator(value); + } +} +const isSimpleType = /*#__PURE__*/ makeMap('String,Number,Boolean,Function,Symbol'); +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$1(value); + } + else if (expectedType === 'Array') { + valid = isArray$1(value); + } + else { + { + // App平台ArrayBuffer等参数跨实例传输,无法通过 instanceof 识别 + valid = value instanceof type || toRawType(value) === getType(type); + } + } + return { + valid, + expectedType, + }; +} +function getInvalidTypeMessage(name, value, expectedTypes) { + let message = `Invalid args: type check failed for args "${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; +} +function getType(ctor) { + const match = ctor && ctor.toString().match(/^\s*function (\w+)/); + return match ? match[1] : ''; +} +function styleValue(value, type) { + if (type === 'String') { + return `"${value}"`; + } + else if (type === 'Number') { + return `${Number(value)}`; + } + else { + return `${value}`; + } +} +function isExplicable(type) { + const explicitTypes = ['string', 'number', 'boolean']; + return explicitTypes.some((elem) => type.toLowerCase() === elem); +} +function isBoolean(...args) { + return args.some((elem) => elem.toLowerCase() === 'boolean'); +} - for (i = 0; i < len; i += 4) { - encoded1 = lookup[base64.charCodeAt(i)]; - encoded2 = lookup[base64.charCodeAt(i + 1)]; - encoded3 = lookup[base64.charCodeAt(i + 2)]; - encoded4 = lookup[base64.charCodeAt(i + 3)]; +function tryCatch(fn) { + return function () { + try { + return fn.apply(fn, arguments); + } + catch (e) { + // TODO + console.error(e); + } + }; +} - bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); - bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); - bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); - } +let invokeCallbackId = 1; +const invokeCallbacks = {}; +function addInvokeCallback(id, name, callback, keepAlive = false) { + invokeCallbacks[id] = { + name, + keepAlive, + callback, + }; + return id; +} +// onNativeEventReceive((event,data)=>{}) 需要两个参数,目前写死最多两个参数 +function invokeCallback(id, res, extras) { + if (typeof id === 'number') { + const opts = invokeCallbacks[id]; + if (opts) { + if (!opts.keepAlive) { + delete invokeCallbacks[id]; + } + return opts.callback(res, extras); + } + } + return res; +} +function findInvokeCallbackByName(name) { + for (const key in invokeCallbacks) { + if (invokeCallbacks[key].name === name) { + return true; + } + } + return false; +} +function removeKeepAliveApiCallback(name, callback) { + for (const key in invokeCallbacks) { + const item = invokeCallbacks[key]; + if (item.callback === callback && item.name === name) { + delete invokeCallbacks[key]; + } + } +} +function offKeepAliveApiCallback(name) { + UniServiceJSBridge.off('api.' + name); +} +function onKeepAliveApiCallback(name) { + UniServiceJSBridge.on('api.' + name, (res) => { + for (const key in invokeCallbacks) { + const opts = invokeCallbacks[key]; + if (opts.name === name) { + opts.callback(res); + } + } + }); +} +function createKeepAliveApiCallback(name, callback) { + return addInvokeCallback(invokeCallbackId++, name, callback, true); +} +const API_SUCCESS = 'success'; +const API_FAIL = 'fail'; +const API_COMPLETE = 'complete'; +function getApiCallbacks(args) { + const apiCallbacks = {}; + for (const name in args) { + const fn = args[name]; + if (isFunction(fn)) { + apiCallbacks[name] = tryCatch(fn); + delete args[name]; + } + } + return apiCallbacks; +} +function normalizeErrMsg$1(errMsg, name) { + if (!errMsg || errMsg.indexOf(':fail') === -1) { + return name + ':ok'; + } + return name + errMsg.substring(errMsg.indexOf(':fail')); +} +function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = {}) { + if (!isPlainObject(args)) { + args = {}; + } + const { success, fail, complete } = getApiCallbacks(args); + const hasSuccess = isFunction(success); + const hasFail = isFunction(fail); + const hasComplete = isFunction(complete); + const callbackId = invokeCallbackId++; + addInvokeCallback(callbackId, name, (res) => { + res = res || {}; + res.errMsg = normalizeErrMsg$1(res.errMsg, name); + isFunction(beforeAll) && beforeAll(res); + if (res.errMsg === name + ':ok') { + isFunction(beforeSuccess) && beforeSuccess(res, args); + hasSuccess && success(res); + } + else { + hasFail && fail(res); + } + hasComplete && complete(res); + }); + return callbackId; +} - return arraybuffer - } +const HOOK_SUCCESS = 'success'; +const HOOK_FAIL = 'fail'; +const HOOK_COMPLETE = 'complete'; +const globalInterceptors = {}; +const scopedInterceptors = {}; +function wrapperHook(hook) { + return function (data) { + return hook(data) || data; + }; +} +function queue(hooks, data) { + let promise = false; + for (let i = 0; i < hooks.length; i++) { + const hook = hooks[i]; + if (promise) { + promise = Promise.resolve(wrapperHook(hook)); + } + else { + const res = hook(data); + if (isPromise(res)) { + promise = Promise.resolve(res); + } + if (res === false) { + return { + then() { }, + catch() { }, + }; + } + } + } + return (promise || { + then(callback) { + return callback(data); + }, + catch() { }, + }); +} +function wrapperOptions(interceptors, options = {}) { + [HOOK_SUCCESS, HOOK_FAIL, HOOK_COMPLETE].forEach((name) => { + const hooks = interceptors[name]; + if (!isArray$1(hooks)) { + return; + } + const oldCallback = options[name]; + options[name] = function callbackInterceptor(res) { + queue(hooks, res).then((res) => { + return (isFunction(oldCallback) && oldCallback(res)) || res; + }); + }; + }); + return options; +} +function wrapperReturnValue(method, returnValue) { + const returnValueHooks = []; + if (isArray$1(globalInterceptors.returnValue)) { + returnValueHooks.push(...globalInterceptors.returnValue); + } + const interceptor = scopedInterceptors[method]; + if (interceptor && isArray$1(interceptor.returnValue)) { + returnValueHooks.push(...interceptor.returnValue); + } + returnValueHooks.forEach((hook) => { + returnValue = hook(returnValue) || returnValue; + }); + return returnValue; +} +function getApiInterceptorHooks(method) { + const interceptor = Object.create(null); + Object.keys(globalInterceptors).forEach((hook) => { + if (hook !== 'returnValue') { + interceptor[hook] = globalInterceptors[hook].slice(); + } + }); + const scopedInterceptor = scopedInterceptors[method]; + if (scopedInterceptor) { + Object.keys(scopedInterceptor).forEach((hook) => { + if (hook !== 'returnValue') { + interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]); + } + }); + } + return interceptor; +} +function invokeApi(method, api, options, params) { + const interceptor = getApiInterceptorHooks(method); + if (interceptor && Object.keys(interceptor).length) { + if (isArray$1(interceptor.invoke)) { + const res = queue(interceptor.invoke, options); + return res.then((options) => { + return api(wrapperOptions(interceptor, options), ...params); + }); + } + else { + return api(wrapperOptions(interceptor, options), ...params); + } + } + return api(options, ...params); +} - const LINEFEED = '\n'; - const NAVBAR_HEIGHT = 44; - const TABBAR_HEIGHT = 50; - const ON_REACH_BOTTOM_DISTANCE = 50; - const I18N_JSON_DELIMITERS = ['%', '%']; - const PRIMARY_COLOR = '#007aff'; - const BACKGROUND_COLOR = '#f7f7f7'; // 背景色,如标题栏默认背景色 - const SCHEME_RE = /^([a-z-]+:)?\/\//i; - const DATA_RE = /^data:.*,.*/; - const WEB_INVOKE_APPSERVICE = 'WEB_INVOKE_APPSERVICE'; - const WXS_PROTOCOL = 'wxs://'; - const WXS_MODULES = 'wxsModules'; - const RENDERJS_MODULES = 'renderjsModules'; - // lifecycle - // App and Page - const ON_SHOW = 'onShow'; - const ON_HIDE = 'onHide'; - //App - const ON_LAUNCH = 'onLaunch'; - const ON_ERROR = 'onError'; - const ON_THEME_CHANGE = 'onThemeChange'; - const ON_KEYBOARD_HEIGHT_CHANGE = 'onKeyboardHeightChange'; - const ON_PAGE_NOT_FOUND = 'onPageNotFound'; - const ON_UNHANDLE_REJECTION = 'onUnhandledRejection'; - //Page - const ON_LOAD = 'onLoad'; - const ON_READY = 'onReady'; - const ON_UNLOAD = 'onUnload'; - const ON_RESIZE = 'onResize'; - const ON_BACK_PRESS = 'onBackPress'; - const ON_PAGE_SCROLL = 'onPageScroll'; - const ON_TAB_ITEM_TAP = 'onTabItemTap'; - const ON_REACH_BOTTOM = 'onReachBottom'; - const ON_PULL_DOWN_REFRESH = 'onPullDownRefresh'; - const ON_SHARE_TIMELINE = 'onShareTimeline'; - const ON_ADD_TO_FAVORITES = 'onAddToFavorites'; - const ON_SHARE_APP_MESSAGE = 'onShareAppMessage'; - // navigationBar - const ON_NAVIGATION_BAR_BUTTON_TAP = 'onNavigationBarButtonTap'; - const ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED = 'onNavigationBarSearchInputClicked'; - const ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED = 'onNavigationBarSearchInputChanged'; - const ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED = 'onNavigationBarSearchInputConfirmed'; - const ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED = 'onNavigationBarSearchInputFocusChanged'; - // framework - const ON_APP_ENTER_FOREGROUND = 'onAppEnterForeground'; - const ON_APP_ENTER_BACKGROUND = 'onAppEnterBackground'; - const ON_WXS_INVOKE_CALL_METHOD = 'onWxsInvokeCallMethod'; - - function isComponentInternalInstance(vm) { - return !!vm.appContext; - } - function resolveComponentInstance(instance) { - return (instance && - (isComponentInternalInstance(instance) ? instance.proxy : instance)); - } - - let lastLogTime = 0; - function formatLog(module, ...args) { - const now = Date.now(); - const diff = lastLogTime ? now - lastLogTime : 0; - lastLogTime = now; - return `[${now}][${diff}ms][${module}]:${args - .map((arg) => JSON.stringify(arg)) - .join(' ')}`; - } +function hasCallback(args) { + if (isPlainObject(args) && + [API_SUCCESS, API_FAIL, API_COMPLETE].find((cb) => isFunction(args[cb]))) { + return true; + } + return false; +} +function handlePromise(promise) { + // if (false) { + // return promise + // .then((data) => { + // return [null, data] + // }) + // .catch((err) => [err]) + // } + return promise; +} +function promisify(name, fn) { + return (args = {}, ...rest) => { + if (hasCallback(args)) { + return wrapperReturnValue(name, invokeApi(name, fn, args, rest)); + } + return wrapperReturnValue(name, handlePromise(new Promise((resolve, reject) => { + invokeApi(name, fn, extend(args, { success: resolve, fail: reject }), rest); + }))); + }; +} - const encode$2 = encodeURIComponent; - function stringifyQuery$1(obj, encodeStr = encode$2) { - const res = obj - ? Object.keys(obj) - .map((key) => { - let val = obj[key]; - if (typeof val === undefined || val === null) { - val = ''; - } - else if (shared.isPlainObject(val)) { - val = JSON.stringify(val); - } - return encodeStr(key) + '=' + encodeStr(val); - }) - .filter((x) => x.length > 0) - .join('&') - : null; - return res ? `?${res}` : ''; - } - /** - * Decode text using `decodeURIComponent`. Returns the original text if it - * fails. - * - * @param text - string to decode - * @returns decoded string - */ - function decode(text) { - try { - return decodeURIComponent('' + text); - } - catch (err) { } - return '' + text; - } - const PLUS_RE = /\+/g; // %2B - /** - * https://github.com/vuejs/vue-router-next/blob/master/src/query.ts - * @internal - * - * @param search - search string to parse - * @returns a query object - */ - function parseQuery(search) { - const query = {}; - // avoid creating an object with an empty key and empty value - // because of split('&') - if (search === '' || search === '?') - return query; - const hasLeadingIM = search[0] === '?'; - const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&'); - for (let i = 0; i < searchParams.length; ++i) { - // pre decode the + into space - const searchParam = searchParams[i].replace(PLUS_RE, ' '); - // allow the = character - let eqPos = searchParam.indexOf('='); - let key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos)); - let value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1)); - if (key in query) { - // an extra variable for ts types - let currentValue = query[key]; - if (!shared.isArray(currentValue)) { - currentValue = query[key] = [currentValue]; - } - currentValue.push(value); - } - else { - query[key] = value; - } - } - return query; - } +function formatApiArgs(args, options) { + const params = args[0]; + if (!options || + (!isPlainObject(options.formatArgs) && isPlainObject(params))) { + return; + } + const formatArgs = options.formatArgs; + const keys = Object.keys(formatArgs); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + const formatterOrDefaultValue = formatArgs[name]; + if (isFunction(formatterOrDefaultValue)) { + const errMsg = formatterOrDefaultValue(args[0][name], params); + if (isString(errMsg)) { + return errMsg; + } + } + else { + // defaultValue + if (!hasOwn$1(params, name)) { + params[name] = formatterOrDefaultValue; + } + } + } +} +function invokeSuccess(id, name, res) { + return invokeCallback(id, extend(res || {}, { errMsg: name + ':ok' })); +} +function invokeFail(id, name, errMsg, errRes) { + return invokeCallback(id, extend({ errMsg: name + ':fail' + (errMsg ? ' ' + errMsg : '') }, errRes)); +} +function beforeInvokeApi(name, args, protocol, options) { + if ((process.env.NODE_ENV !== 'production')) { + validateProtocols(name, args, protocol); + } + if (options && options.beforeInvoke) { + const errMsg = options.beforeInvoke(args); + if (isString(errMsg)) { + return errMsg; + } + } + const errMsg = formatApiArgs(args, options); + if (errMsg) { + return errMsg; + } +} +function checkCallback(callback) { + if (!isFunction(callback)) { + throw new Error('Invalid args: type check failed for args "callback". Expected Function'); + } +} +function wrapperOnApi(name, fn, options) { + return (callback) => { + checkCallback(callback); + const errMsg = beforeInvokeApi(name, [callback], undefined, options); + if (errMsg) { + throw new Error(errMsg); + } + // 是否是首次调用on,如果是首次,需要初始化onMethod监听 + const isFirstInvokeOnApi = !findInvokeCallbackByName(name); + createKeepAliveApiCallback(name, callback); + if (isFirstInvokeOnApi) { + onKeepAliveApiCallback(name); + fn(); + } + }; +} +function wrapperOffApi(name, fn, options) { + return (callback) => { + checkCallback(callback); + const errMsg = beforeInvokeApi(name, [callback], undefined, options); + if (errMsg) { + throw new Error(errMsg); + } + name = name.replace('off', 'on'); + removeKeepAliveApiCallback(name, callback); + // 是否还存在监听,若已不存在,则移除onMethod监听 + const hasInvokeOnApi = findInvokeCallbackByName(name); + if (!hasInvokeOnApi) { + offKeepAliveApiCallback(name); + fn(); + } + }; +} +function normalizeErrMsg(errMsg) { + if (!errMsg || isString(errMsg)) { + return errMsg; + } + if (errMsg.stack) { + console.error(errMsg.message + LINEFEED + errMsg.stack); + return errMsg.message; + } + return errMsg; +} +function wrapperTaskApi(name, fn, protocol, options) { + return (args) => { + const id = createAsyncApiCallback(name, args, options); + const errMsg = beforeInvokeApi(name, [args], protocol, options); + if (errMsg) { + return invokeFail(id, name, errMsg); + } + return fn(args, { + resolve: (res) => invokeSuccess(id, name, res), + reject: (errMsg, errRes) => invokeFail(id, name, normalizeErrMsg(errMsg), errRes), + }); + }; +} +function wrapperSyncApi(name, fn, protocol, options) { + return (...args) => { + const errMsg = beforeInvokeApi(name, args, protocol, options); + if (errMsg) { + throw new Error(errMsg); + } + return fn.apply(null, args); + }; +} +function wrapperAsyncApi(name, fn, protocol, options) { + return wrapperTaskApi(name, fn, protocol, options); +} +function defineOnApi(name, fn, options) { + return wrapperOnApi(name, fn, options); +} +function defineOffApi(name, fn, options) { + return wrapperOffApi(name, fn, options); +} +function defineTaskApi(name, fn, protocol, options) { + return promisify(name, wrapperTaskApi(name, fn, (process.env.NODE_ENV !== 'production') ? protocol : undefined, options)); +} +function defineSyncApi(name, fn, protocol, options) { + return wrapperSyncApi(name, fn, (process.env.NODE_ENV !== 'production') ? protocol : undefined, options); +} +function defineAsyncApi(name, fn, protocol, options) { + return promisify(name, wrapperAsyncApi(name, fn, (process.env.NODE_ENV !== 'production') ? protocol : undefined, options)); +} - function parseUrl(url) { - const [path, querystring] = url.split('?', 2); - return { - path, - query: parseQuery(querystring || ''), - }; - } +const API_BASE64_TO_ARRAY_BUFFER = 'base64ToArrayBuffer'; +const Base64ToArrayBufferProtocol = [ + { + name: 'base64', + type: String, + required: true, + }, +]; +const API_ARRAY_BUFFER_TO_BASE64 = 'arrayBufferToBase64'; +const ArrayBufferToBase64Protocol = [ + { + name: 'arrayBuffer', + type: [ArrayBuffer, Uint8Array], + required: true, + }, +]; + +// @ts-ignore +const base64ToArrayBuffer = defineSyncApi(API_BASE64_TO_ARRAY_BUFFER, (base64) => { + return decode(base64); +}, Base64ToArrayBufferProtocol); +const arrayBufferToBase64 = defineSyncApi(API_ARRAY_BUFFER_TO_BASE64, (arrayBuffer) => { + return encode$2(arrayBuffer); +}, ArrayBufferToBase64Protocol); + +/** + * 简易版systemInfo,主要为upx2px,i18n服务 + * @returns + */ +function getBaseSystemInfo() { + // @ts-expect-error view 层 + if (typeof __SYSTEM_INFO__ !== 'undefined') { + return window.__SYSTEM_INFO__; + } + const { resolutionWidth } = plus.screen.getCurrentSize(); + return { + platform: (plus.os.name || '').toLowerCase(), + pixelRatio: plus.screen.scale, + windowWidth: Math.round(resolutionWidth), + }; +} - class DOMException extends Error { - constructor(message) { - super(message); - this.name = 'DOMException'; - } - } +function requestComponentInfo(page, reqs, callback) { + UniServiceJSBridge.invokeViewMethod('requestComponentInfo', { + reqs: reqs.map((req) => { + if (req.component) { + req.component = req.component.$el.nodeId; + } + return req; + }), + }, page.$page.id, callback); +} - function normalizeEventType(type, options) { - if (options) { - if (options.capture) { - type += 'Capture'; - } - if (options.once) { - type += 'Once'; - } - if (options.passive) { - type += 'Passive'; - } - } - return `on${shared.capitalize(shared.camelize(type))}`; - } - class UniEvent { - constructor(type, opts) { - this.defaultPrevented = false; - this.timeStamp = Date.now(); - this._stop = false; - this._end = false; - this.type = type; - this.bubbles = !!opts.bubbles; - this.cancelable = !!opts.cancelable; - } - preventDefault() { - this.defaultPrevented = true; - } - stopImmediatePropagation() { - this._end = this._stop = true; - } - stopPropagation() { - this._stop = true; - } - } - function createUniEvent(evt) { - if (evt instanceof UniEvent) { - return evt; - } - const [type] = parseEventName(evt.type); - const uniEvent = new UniEvent(type, { - bubbles: false, - cancelable: false, - }); - shared.extend(uniEvent, evt); - return uniEvent; - } - class UniEventTarget { - constructor() { - this.listeners = Object.create(null); - } - dispatchEvent(evt) { - const listeners = this.listeners[evt.type]; - if (!listeners) { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('dispatchEvent', this.nodeId), evt.type, 'not found'); - } - return false; - } - // 格式化事件类型 - const event = createUniEvent(evt); - const len = listeners.length; - for (let i = 0; i < len; i++) { - listeners[i].call(this, event); - if (event._end) { - break; - } - } - return event.cancelable && event.defaultPrevented; - } - addEventListener(type, listener, options) { - type = normalizeEventType(type, options); - (this.listeners[type] || (this.listeners[type] = [])).push(listener); - } - removeEventListener(type, callback, options) { - type = normalizeEventType(type, options); - const listeners = this.listeners[type]; - if (!listeners) { - return; - } - const index = listeners.indexOf(callback); - if (index > -1) { - listeners.splice(index, 1); - } - } - } - const optionsModifierRE = /(?:Once|Passive|Capture)$/; - function parseEventName(name) { - let options; - if (optionsModifierRE.test(name)) { - options = {}; - let m; - while ((m = name.match(optionsModifierRE))) { - name = name.slice(0, name.length - m[0].length); - options[m[0].toLowerCase()] = true; - } - } - return [shared.hyphenate(name.slice(2)), options]; - } +function setCurrentPageMeta(page, options) { + UniServiceJSBridge.invokeViewMethod('setPageMeta', options, page.$page.id); +} - const NODE_TYPE_PAGE = 0; - const NODE_TYPE_ELEMENT = 1; - function sibling(node, type) { - const { parentNode } = node; - if (!parentNode) { - return null; - } - const { childNodes } = parentNode; - return childNodes[childNodes.indexOf(node) + (type === 'n' ? 1 : -1)] || null; - } - function removeNode(node) { - const { parentNode } = node; - if (parentNode) { - parentNode.removeChild(node); - } - } - function checkNodeId(node) { - if (!node.nodeId && node.pageNode) { - node.nodeId = node.pageNode.genId(); - } - } - // 为优化性能,各平台不使用proxy来实现node的操作拦截,而是直接通过pageNode定制 - class UniNode extends UniEventTarget { - constructor(nodeType, nodeName, container) { - super(); - this.pageNode = null; - this.parentNode = null; - this._text = null; - if (container) { - const { pageNode } = container; - if (pageNode) { - this.pageNode = pageNode; - this.nodeId = pageNode.genId(); - !pageNode.isUnmounted && pageNode.onCreate(this, nodeName); - } - } - this.nodeType = nodeType; - this.nodeName = nodeName; - this.childNodes = []; - } - get firstChild() { - return this.childNodes[0] || null; - } - get lastChild() { - const { childNodes } = this; - const length = childNodes.length; - return length ? childNodes[length - 1] : null; - } - get nextSibling() { - return sibling(this, 'n'); - } - get nodeValue() { - return null; - } - set nodeValue(_val) { } - get textContent() { - return this._text || ''; - } - set textContent(text) { - this._text = text; - if (this.pageNode && !this.pageNode.isUnmounted) { - this.pageNode.onTextContent(this, text); - } - } - get parentElement() { - const { parentNode } = this; - if (parentNode && parentNode.nodeType === NODE_TYPE_ELEMENT) { - return parentNode; - } - return null; - } - get previousSibling() { - return sibling(this, 'p'); - } - appendChild(newChild) { - return this.insertBefore(newChild, null); - } - cloneNode(deep) { - const cloned = shared.extend(Object.create(Object.getPrototypeOf(this)), this); - const { attributes } = cloned; - if (attributes) { - cloned.attributes = shared.extend({}, attributes); - } - if (deep) { - cloned.childNodes = cloned.childNodes.map((childNode) => childNode.cloneNode(true)); - } - return cloned; - } - insertBefore(newChild, refChild) { - removeNode(newChild); - newChild.pageNode = this.pageNode; - newChild.parentNode = this; - checkNodeId(newChild); - const { childNodes } = this; - if (refChild) { - const index = childNodes.indexOf(refChild); - if (index === -1) { - throw new DOMException(`Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.`); - } - childNodes.splice(index, 0, newChild); - } - else { - childNodes.push(newChild); - } - return this.pageNode && !this.pageNode.isUnmounted - ? this.pageNode.onInsertBefore(this, newChild, refChild) - : newChild; - } - removeChild(oldChild) { - const { childNodes } = this; - const index = childNodes.indexOf(oldChild); - if (index === -1) { - throw new DOMException(`Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.`); - } - oldChild.parentNode = null; - childNodes.splice(index, 1); - return this.pageNode && !this.pageNode.isUnmounted - ? this.pageNode.onRemoveChild(oldChild) - : oldChild; - } - } - - const ACTION_TYPE_PAGE_CREATE = 1; - const ACTION_TYPE_PAGE_CREATED = 2; - const ACTION_TYPE_CREATE = 3; - const ACTION_TYPE_INSERT = 4; - const ACTION_TYPE_REMOVE = 5; - const ACTION_TYPE_SET_ATTRIBUTE = 6; - const ACTION_TYPE_REMOVE_ATTRIBUTE = 7; - const ACTION_TYPE_ADD_EVENT = 8; - const ACTION_TYPE_REMOVE_EVENT = 9; - const ACTION_TYPE_SET_TEXT = 10; - const ACTION_TYPE_ADD_WXS_EVENT = 12; - const ACTION_TYPE_PAGE_SCROLL = 15; - const ACTION_TYPE_EVENT = 20; - - function cache(fn) { - const cache = Object.create(null); - return (str) => { - const hit = cache[str]; - return hit || (cache[str] = fn(str)); - }; - } - function cacheStringFunction(fn) { - return cache(fn); - } - function getLen(str = '') { - return ('' + str).replace(/[^\x00-\xff]/g, '**').length; - } - function hasLeadingSlash(str) { - return str.indexOf('/') === 0; - } - function addLeadingSlash(str) { - return hasLeadingSlash(str) ? str : '/' + str; - } - function removeLeadingSlash(str) { - return hasLeadingSlash(str) ? str.substr(1) : str; - } - const invokeArrayFns = (fns, arg) => { - let ret; - for (let i = 0; i < fns.length; i++) { - ret = fns[i](arg); - } - return ret; - }; - function once(fn, ctx = null) { - let res; - return ((...args) => { - if (fn) { - res = fn.apply(ctx, args); - fn = null; - } - return res; - }); - } - function callOptions(options, data) { - options = options || {}; - if (typeof data === 'string') { - data = { - errMsg: data, - }; - } - if (/:ok$/.test(data.errMsg)) { - if (typeof options.success === 'function') { - options.success(data); - } - } - else { - if (typeof options.fail === 'function') { - options.fail(data); - } - } - if (typeof options.complete === 'function') { - options.complete(data); - } - } - - function debounce(fn, delay) { - let timeout; - const newFn = function () { - clearTimeout(timeout); - const timerFn = () => fn.apply(this, arguments); - timeout = setTimeout(timerFn, delay); - }; - newFn.cancel = function () { - clearTimeout(timeout); - }; - return newFn; - } +const isArray = Array.isArray; +const isObject = (val) => val !== null && typeof val === 'object'; +const defaultDelimiters = ['{', '}']; +class BaseFormatter { + constructor() { + this._caches = Object.create(null); + } + interpolate(message, values, delimiters = defaultDelimiters) { + if (!values) { + return [message]; + } + let tokens = this._caches[message]; + if (!tokens) { + tokens = parse(message, delimiters); + this._caches[message] = tokens; + } + return compile(tokens, values); + } +} +const RE_TOKEN_LIST_VALUE = /^(?:\d)+/; +const RE_TOKEN_NAMED_VALUE = /^(?:\w)+/; +function parse(format, [startDelimiter, endDelimiter]) { + const tokens = []; + let position = 0; + let text = ''; + while (position < format.length) { + let char = format[position++]; + if (char === startDelimiter) { + if (text) { + tokens.push({ type: 'text', value: text }); + } + text = ''; + let sub = ''; + char = format[position++]; + while (char !== undefined && char !== endDelimiter) { + sub += char; + char = format[position++]; + } + const isClosed = char === endDelimiter; + const type = RE_TOKEN_LIST_VALUE.test(sub) + ? 'list' + : isClosed && RE_TOKEN_NAMED_VALUE.test(sub) + ? 'named' + : 'unknown'; + tokens.push({ value: sub, type }); + } + // else if (char === '%') { + // // when found rails i18n syntax, skip text capture + // if (format[position] !== '{') { + // text += char + // } + // } + else { + text += char; + } + } + text && tokens.push({ type: 'text', value: text }); + return tokens; +} +function compile(tokens, values) { + const compiled = []; + let index = 0; + const mode = isArray(values) + ? 'list' + : isObject(values) + ? 'named' + : 'unknown'; + if (mode === 'unknown') { + return compiled; + } + while (index < tokens.length) { + const token = tokens[index]; + switch (token.type) { + case 'text': + compiled.push(token.value); + break; + case 'list': + compiled.push(values[parseInt(token.value, 10)]); + break; + case 'named': + if (mode === 'named') { + compiled.push(values[token.value]); + } + else { + if (process.env.NODE_ENV !== 'production') { + console.warn(`Type of token '${token.type}' and format of value '${mode}' don't match!`); + } + } + break; + case 'unknown': + if (process.env.NODE_ENV !== 'production') { + console.warn(`Detect 'unknown' type of token!`); + } + break; + } + index++; + } + return compiled; +} - class EventChannel { - constructor(id, events) { - this.id = id; - this.listener = {}; - this.emitCache = {}; - if (events) { - Object.keys(events).forEach((name) => { - this.on(name, events[name]); - }); - } - } - emit(eventName, ...args) { - const fns = this.listener[eventName]; - if (!fns) { - return (this.emitCache[eventName] || (this.emitCache[eventName] = [])).push(args); - } - fns.forEach((opt) => { - opt.fn.apply(opt.fn, args); - }); - this.listener[eventName] = fns.filter((opt) => opt.type !== 'once'); - } - on(eventName, fn) { - this._addListener(eventName, 'on', fn); - this._clearCache(eventName); - } - once(eventName, fn) { - this._addListener(eventName, 'once', fn); - this._clearCache(eventName); - } - off(eventName, fn) { - const fns = this.listener[eventName]; - if (!fns) { - return; - } - if (fn) { - for (let i = 0; i < fns.length;) { - if (fns[i].fn === fn) { - fns.splice(i, 1); - i--; - } - i++; - } - } - else { - delete this.listener[eventName]; - } - } - _clearCache(eventName) { - const cacheArgs = this.emitCache[eventName]; - if (cacheArgs) { - for (; cacheArgs.length > 0;) { - this.emit.apply(this, [eventName, ...cacheArgs.shift()]); - } - } - } - _addListener(eventName, type, fn) { - (this.listener[eventName] || (this.listener[eventName] = [])).push({ - fn, - type, - }); - } - } - const UniLifecycleHooks = [ - ON_SHOW, - ON_HIDE, - ON_LAUNCH, - ON_ERROR, - ON_THEME_CHANGE, - ON_PAGE_NOT_FOUND, - ON_UNHANDLE_REJECTION, - ON_LOAD, - ON_READY, - ON_UNLOAD, - ON_RESIZE, - ON_BACK_PRESS, - ON_PAGE_SCROLL, - ON_TAB_ITEM_TAP, - ON_REACH_BOTTOM, - ON_PULL_DOWN_REFRESH, - ON_SHARE_TIMELINE, - ON_ADD_TO_FAVORITES, - ON_SHARE_APP_MESSAGE, - ON_NAVIGATION_BAR_BUTTON_TAP, - ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, - ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, - ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, - ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, - ]; - - const CHOOSE_SIZE_TYPES = ['original', 'compressed']; - const CHOOSE_SOURCE_TYPES = ['album', 'camera']; - const HTTP_METHODS = [ - 'GET', - 'OPTIONS', - 'HEAD', - 'POST', - 'PUT', - 'DELETE', - 'TRACE', - 'CONNECT', - 'PATCH', - ]; - function elemInArray(str, arr) { - if (!str || arr.indexOf(str) === -1) { - return arr[0]; - } - return str; - } - function elemsInArray(strArr, optionalVal) { - if (!shared.isArray(strArr) || - strArr.length === 0 || - strArr.find((val) => optionalVal.indexOf(val) === -1)) { - return optionalVal; - } - return strArr; - } - function validateProtocolFail(name, msg) { - console.warn(`${name}: ${msg}`); - } - function validateProtocol(name, data, protocol, onFail) { - if (!onFail) { - onFail = validateProtocolFail; - } - for (const key in protocol) { - const errMsg = validateProp(key, data[key], protocol[key], !shared.hasOwn(data, key)); - if (shared.isString(errMsg)) { - onFail(name, errMsg); - } - } - } - function validateProtocols(name, args, protocol, onFail) { - if (!protocol) { - return; - } - if (!shared.isArray(protocol)) { - return validateProtocol(name, args[0] || Object.create(null), protocol, onFail); - } - const len = protocol.length; - const argsLen = args.length; - for (let i = 0; i < len; i++) { - const opts = protocol[i]; - const data = Object.create(null); - if (argsLen > i) { - data[opts.name] = args[i]; - } - validateProtocol(name, data, { [opts.name]: opts }, onFail); - } - } - function validateProp(name, value, prop, isAbsent) { - if (!shared.isPlainObject(prop)) { - prop = { type: prop }; - } - const { type, required, validator } = prop; - // required! - if (required && isAbsent) { - return 'Missing required args: "' + name + '"'; - } - // missing but optional - if (value == null && !required) { - return; - } - // type check - if (type != null) { - let isValid = false; - const types = shared.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) { - return getInvalidTypeMessage(name, value, expectedTypes); - } - } - // custom validator - if (validator) { - return validator(value); - } - } - const isSimpleType = /*#__PURE__*/ shared.makeMap('String,Number,Boolean,Function,Symbol'); - 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 = shared.isObject(value); - } - else if (expectedType === 'Array') { - valid = shared.isArray(value); - } - else { - { - // App平台ArrayBuffer等参数跨实例传输,无法通过 instanceof 识别 - valid = value instanceof type || shared.toRawType(value) === getType(type); - } - } - return { - valid, - expectedType, - }; - } - function getInvalidTypeMessage(name, value, expectedTypes) { - let message = `Invalid args: type check failed for args "${name}".` + - ` Expected ${expectedTypes.map(shared.capitalize).join(', ')}`; - const expectedType = expectedTypes[0]; - const receivedType = shared.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; - } - function getType(ctor) { - const match = ctor && ctor.toString().match(/^\s*function (\w+)/); - return match ? match[1] : ''; - } - function styleValue(value, type) { - if (type === 'String') { - return `"${value}"`; - } - else if (type === 'Number') { - return `${Number(value)}`; - } - else { - return `${value}`; - } - } - function isExplicable(type) { - const explicitTypes = ['string', 'number', 'boolean']; - return explicitTypes.some((elem) => type.toLowerCase() === elem); - } - function isBoolean(...args) { - return args.some((elem) => elem.toLowerCase() === 'boolean'); - } +const LOCALE_ZH_HANS = 'zh-Hans'; +const LOCALE_ZH_HANT = 'zh-Hant'; +const LOCALE_EN = 'en'; +const LOCALE_FR = 'fr'; +const LOCALE_ES = 'es'; +const hasOwnProperty = Object.prototype.hasOwnProperty; +const hasOwn = (val, key) => hasOwnProperty.call(val, key); +const defaultFormatter = new BaseFormatter(); +function include(str, parts) { + return !!parts.find((part) => str.indexOf(part) !== -1); +} +function startsWith(str, parts) { + return parts.find((part) => str.indexOf(part) === 0); +} +function normalizeLocale(locale, messages) { + if (!locale) { + return; + } + locale = locale.trim().replace(/_/g, '-'); + if (messages && messages[locale]) { + return locale; + } + locale = locale.toLowerCase(); + if (locale === 'chinese') { + // 支付宝 + return LOCALE_ZH_HANS; + } + if (locale.indexOf('zh') === 0) { + if (locale.indexOf('-hans') > -1) { + return LOCALE_ZH_HANS; + } + if (locale.indexOf('-hant') > -1) { + return LOCALE_ZH_HANT; + } + if (include(locale, ['-tw', '-hk', '-mo', '-cht'])) { + return LOCALE_ZH_HANT; + } + return LOCALE_ZH_HANS; + } + const lang = startsWith(locale, [LOCALE_EN, LOCALE_FR, LOCALE_ES]); + if (lang) { + return lang; + } +} +class I18n { + constructor({ locale, fallbackLocale, messages, watcher, formater, }) { + this.locale = LOCALE_EN; + this.fallbackLocale = LOCALE_EN; + this.message = {}; + this.messages = {}; + this.watchers = []; + if (fallbackLocale) { + this.fallbackLocale = fallbackLocale; + } + this.formater = formater || defaultFormatter; + this.messages = messages || {}; + this.setLocale(locale || LOCALE_EN); + if (watcher) { + this.watchLocale(watcher); + } + } + setLocale(locale) { + const oldLocale = this.locale; + this.locale = normalizeLocale(locale, this.messages) || this.fallbackLocale; + if (!this.messages[this.locale]) { + // 可能初始化时不存在 + this.messages[this.locale] = {}; + } + this.message = this.messages[this.locale]; + // 仅发生变化时,通知 + if (oldLocale !== this.locale) { + this.watchers.forEach((watcher) => { + watcher(this.locale, oldLocale); + }); + } + } + getLocale() { + return this.locale; + } + watchLocale(fn) { + const index = this.watchers.push(fn) - 1; + return () => { + this.watchers.splice(index, 1); + }; + } + add(locale, message, override = true) { + const curMessages = this.messages[locale]; + if (curMessages) { + if (override) { + Object.assign(curMessages, message); + } + else { + Object.keys(message).forEach((key) => { + if (!hasOwn(curMessages, key)) { + curMessages[key] = message[key]; + } + }); + } + } + else { + this.messages[locale] = message; + } + } + f(message, values, delimiters) { + return this.formater.interpolate(message, values, delimiters).join(''); + } + t(key, locale, values) { + let message = this.message; + if (typeof locale === 'string') { + locale = normalizeLocale(locale, this.messages); + locale && (message = this.messages[locale]); + } + else { + values = locale; + } + if (!hasOwn(message, key)) { + console.warn(`Cannot translate the value of keypath ${key}. Use the value of keypath as default.`); + return key; + } + return this.formater.interpolate(message[key], values).join(''); + } +} - function tryCatch(fn) { - return function () { - try { - return fn.apply(fn, arguments); - } - catch (e) { - // TODO - console.error(e); - } - }; - } +function watchAppLocale(appVm, i18n) { + // 需要保证 watch 的触发在组件渲染之前 + if (appVm.$watchLocale) { + // vue2 + appVm.$watchLocale((newLocale) => { + i18n.setLocale(newLocale); + }); + } + else { + appVm.$watch(() => appVm.$locale, (newLocale) => { + i18n.setLocale(newLocale); + }); + } +} +function getDefaultLocale() { + if (typeof uni !== 'undefined' && uni.getLocale) { + return uni.getLocale(); + } + // 小程序平台,uni 和 uni-i18n 互相引用,导致访问不到 uni,故在 global 上挂了 getLocale + if (typeof global !== 'undefined' && global.getLocale) { + return global.getLocale(); + } + return LOCALE_EN; +} +function initVueI18n(locale, messages = {}, fallbackLocale, watcher) { + // 兼容旧版本入参 + if (typeof locale !== 'string') { + [locale, messages] = [ + messages, + locale, + ]; + } + if (typeof locale !== 'string') { + // 因为小程序平台,uni-i18n 和 uni 互相引用,导致此时访问 uni 时,为 undefined + locale = getDefaultLocale(); + } + if (typeof fallbackLocale !== 'string') { + fallbackLocale = + (typeof __uniConfig !== 'undefined' && __uniConfig.fallbackLocale) || + LOCALE_EN; + } + const i18n = new I18n({ + locale, + fallbackLocale, + messages, + watcher, + }); + let t = (key, values) => { + if (typeof getApp !== 'function') { + // app view + /* eslint-disable no-func-assign */ + t = function (key, values) { + return i18n.t(key, values); + }; + } + else { + let isWatchedAppLocale = false; + t = function (key, values) { + const appVm = getApp().$vm; + // 可能$vm还不存在,比如在支付宝小程序中,组件定义较早,在props的default里使用了t()函数(如uni-goods-nav),此时app还未初始化 + // options: { + // type: Array, + // default () { + // return [{ + // icon: 'shop', + // text: t("uni-goods-nav.options.shop"), + // }, { + // icon: 'cart', + // text: t("uni-goods-nav.options.cart") + // }] + // } + // }, + if (appVm) { + // 触发响应式 + appVm.$locale; + if (!isWatchedAppLocale) { + isWatchedAppLocale = true; + watchAppLocale(appVm, i18n); + } + } + return i18n.t(key, values); + }; + } + return t(key, values); + }; + return { + i18n, + f(message, values, delimiters) { + return i18n.f(message, values, delimiters); + }, + t(key, values) { + return t(key, values); + }, + add(locale, message, override = true) { + return i18n.add(locale, message, override); + }, + watch(fn) { + return i18n.watchLocale(fn); + }, + getLocale() { + return i18n.getLocale(); + }, + setLocale(newLocale) { + return i18n.setLocale(newLocale); + }, + }; +} +function isI18nStr(value, delimiters) { + return value.indexOf(delimiters[0]) > -1; +} - let invokeCallbackId = 1; - const invokeCallbacks = {}; - function addInvokeCallback(id, name, callback, keepAlive = false) { - invokeCallbacks[id] = { - name, - keepAlive, - callback, - }; - return id; - } - // onNativeEventReceive((event,data)=>{}) 需要两个参数,目前写死最多两个参数 - function invokeCallback(id, res, extras) { - if (typeof id === 'number') { - const opts = invokeCallbacks[id]; - if (opts) { - if (!opts.keepAlive) { - delete invokeCallbacks[id]; - } - return opts.callback(res, extras); - } - } - return res; - } - function findInvokeCallbackByName(name) { - for (const key in invokeCallbacks) { - if (invokeCallbacks[key].name === name) { - return true; - } - } - return false; - } - function removeKeepAliveApiCallback(name, callback) { - for (const key in invokeCallbacks) { - const item = invokeCallbacks[key]; - if (item.callback === callback && item.name === name) { - delete invokeCallbacks[key]; - } - } - } - function offKeepAliveApiCallback(name) { - UniServiceJSBridge.off('api.' + name); - } - function onKeepAliveApiCallback(name) { - UniServiceJSBridge.on('api.' + name, (res) => { - for (const key in invokeCallbacks) { - const opts = invokeCallbacks[key]; - if (opts.name === name) { - opts.callback(res); - } - } - }); - } - function createKeepAliveApiCallback(name, callback) { - return addInvokeCallback(invokeCallbackId++, name, callback, true); - } - const API_SUCCESS = 'success'; - const API_FAIL = 'fail'; - const API_COMPLETE = 'complete'; - function getApiCallbacks(args) { - const apiCallbacks = {}; - for (const name in args) { - const fn = args[name]; - if (shared.isFunction(fn)) { - apiCallbacks[name] = tryCatch(fn); - delete args[name]; - } - } - return apiCallbacks; - } - function normalizeErrMsg$1(errMsg, name) { - if (!errMsg || errMsg.indexOf(':fail') === -1) { - return name + ':ok'; - } - return name + errMsg.substring(errMsg.indexOf(':fail')); - } - function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = {}) { - if (!shared.isPlainObject(args)) { - args = {}; - } - const { success, fail, complete } = getApiCallbacks(args); - const hasSuccess = shared.isFunction(success); - const hasFail = shared.isFunction(fail); - const hasComplete = shared.isFunction(complete); - const callbackId = invokeCallbackId++; - addInvokeCallback(callbackId, name, (res) => { - res = res || {}; - res.errMsg = normalizeErrMsg$1(res.errMsg, name); - shared.isFunction(beforeAll) && beforeAll(res); - if (res.errMsg === name + ':ok') { - shared.isFunction(beforeSuccess) && beforeSuccess(res, args); - hasSuccess && success(res); - } - else { - hasFail && fail(res); - } - hasComplete && complete(res); - }); - return callbackId; - } +const isEnableLocale = once(() => typeof __uniConfig !== 'undefined' && + __uniConfig.locales && + !!Object.keys(__uniConfig.locales).length); + +let i18n; +function getLocaleMessage() { + const locale = uni.getLocale(); + const locales = __uniConfig.locales; + return (locales[locale] || locales[__uniConfig.fallbackLocale] || locales.en || {}); +} +function formatI18n(message) { + if (isI18nStr(message, I18N_JSON_DELIMITERS)) { + return useI18n().f(message, getLocaleMessage(), I18N_JSON_DELIMITERS); + } + return message; +} +function resolveJsonObj(jsonObj, names) { + if (names.length === 1) { + if (jsonObj) { + const value = jsonObj[names[0]]; + if (isString(value) && isI18nStr(value, I18N_JSON_DELIMITERS)) { + return jsonObj; + } + } + return; + } + const name = names.shift(); + return resolveJsonObj(jsonObj && jsonObj[name], names); +} +function defineI18nProperties(obj, names) { + return names.map((name) => defineI18nProperty(obj, name)); +} +function defineI18nProperty(obj, names) { + const jsonObj = resolveJsonObj(obj, names); + if (!jsonObj) { + return false; + } + const prop = names[names.length - 1]; + let value = jsonObj[prop]; + Object.defineProperty(jsonObj, prop, { + get() { + return formatI18n(value); + }, + set(v) { + value = v; + }, + }); + return true; +} +function useI18n() { + if (!i18n) { + let locale; + { + if (typeof getApp === 'function') { + locale = weex.requireModule('plus').getLanguage(); + } + else { + locale = plus.webview.currentWebview().getStyle().locale; + } + } + i18n = initVueI18n(locale); + // 自定义locales + if (isEnableLocale()) { + const localeKeys = Object.keys(__uniConfig.locales || {}); + if (localeKeys.length) { + localeKeys.forEach((locale) => i18n.add(locale, __uniConfig.locales[locale])); + } + // initVueI18n 时 messages 还没有,导致用户自定义 locale 可能不生效,当设置完 messages 后,重新设置 locale + i18n.setLocale(locale); + } + } + return i18n; +} - const HOOK_SUCCESS = 'success'; - const HOOK_FAIL = 'fail'; - const HOOK_COMPLETE = 'complete'; - const globalInterceptors = {}; - const scopedInterceptors = {}; - function wrapperHook(hook) { - return function (data) { - return hook(data) || data; - }; - } - function queue(hooks, data) { - let promise = false; - for (let i = 0; i < hooks.length; i++) { - const hook = hooks[i]; - if (promise) { - promise = Promise.resolve(wrapperHook(hook)); - } - else { - const res = hook(data); - if (shared.isPromise(res)) { - promise = Promise.resolve(res); - } - if (res === false) { - return { - then() { }, - catch() { }, - }; - } - } - } - return (promise || { - then(callback) { - return callback(data); - }, - catch() { }, - }); - } - function wrapperOptions(interceptors, options = {}) { - [HOOK_SUCCESS, HOOK_FAIL, HOOK_COMPLETE].forEach((name) => { - const hooks = interceptors[name]; - if (!shared.isArray(hooks)) { - return; - } - const oldCallback = options[name]; - options[name] = function callbackInterceptor(res) { - queue(hooks, res).then((res) => { - return (shared.isFunction(oldCallback) && oldCallback(res)) || res; - }); - }; - }); - return options; - } - function wrapperReturnValue(method, returnValue) { - const returnValueHooks = []; - if (shared.isArray(globalInterceptors.returnValue)) { - returnValueHooks.push(...globalInterceptors.returnValue); - } - const interceptor = scopedInterceptors[method]; - if (interceptor && shared.isArray(interceptor.returnValue)) { - returnValueHooks.push(...interceptor.returnValue); - } - returnValueHooks.forEach((hook) => { - returnValue = hook(returnValue) || returnValue; - }); - return returnValue; - } - function getApiInterceptorHooks(method) { - const interceptor = Object.create(null); - Object.keys(globalInterceptors).forEach((hook) => { - if (hook !== 'returnValue') { - interceptor[hook] = globalInterceptors[hook].slice(); - } - }); - const scopedInterceptor = scopedInterceptors[method]; - if (scopedInterceptor) { - Object.keys(scopedInterceptor).forEach((hook) => { - if (hook !== 'returnValue') { - interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]); - } - }); - } - return interceptor; - } - function invokeApi(method, api, options, params) { - const interceptor = getApiInterceptorHooks(method); - if (interceptor && Object.keys(interceptor).length) { - if (shared.isArray(interceptor.invoke)) { - const res = queue(interceptor.invoke, options); - return res.then((options) => { - return api(wrapperOptions(interceptor, options), ...params); - }); - } - else { - return api(wrapperOptions(interceptor, options), ...params); - } - } - return api(options, ...params); - } +// This file is created by scripts/i18n.js +function normalizeMessages(module, keys, values) { + return keys.reduce((res, name, index) => { + res[module + name] = values[index]; + return res; + }, {}); +} +const initI18nAppMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.app.'; + const keys = ['quit']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Press back button again to exit']), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Pulse otra vez para salir']), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ + "Appuyez à nouveau pour quitter l'application", + ]), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['再按一次退出应用']), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['再按一次退出應用']), false); + } +}); +const initI18nShowActionSheetMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.showActionSheet.'; + const keys = ['cancel']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel']), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar']), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler']), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消']), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消']), false); + } +}); +const initI18nShowModalMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.showModal.'; + const keys = ['cancel', 'confirm']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel', 'OK']), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar', 'OK']), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler', 'OK']), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消', '确定']), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消', '確定']), false); + } +}); +const initI18nChooseImageMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.chooseImage.'; + const keys = ['cancel', 'sourceType.album', 'sourceType.camera']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel', 'Album', 'Camera']), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar', 'Álbum', 'Cámara']), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler', 'Album', 'Caméra']), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消', '从相册选择', '拍摄']), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消', '從相冊選擇', '拍攝']), false); + } +}); +const initI18nChooseVideoMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.chooseVideo.'; + const keys = ['cancel', 'sourceType.album', 'sourceType.camera']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel', 'Album', 'Camera']), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar', 'Álbum', 'Cámara']), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler', 'Album', 'Caméra']), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消', '从相册选择', '拍摄']), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消', '從相冊選擇', '拍攝']), false); + } +}); +const initI18nPreviewImageMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.previewImage.'; + const keys = ['cancel', 'button.save', 'save.success', 'save.fail']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, [ + 'Cancel', + 'Save Image', + 'Saved successfully', + 'Save failed', + ]), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, [ + 'Cancelar', + 'Guardar imagen', + 'Guardado exitosamente', + 'Error al guardar', + ]), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ + 'Annuler', + 'Guardar imagen', + 'Enregistré avec succès', + 'Échec de la sauvegarde', + ]), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, [ + '取消', + '保存图像', + '保存图像到相册成功', + '保存图像到相册失败', + ]), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, [ + '取消', + '保存圖像', + '保存圖像到相冊成功', + '保存圖像到相冊失敗', + ]), false); + } +}); +const initI18nSetClipboardDataMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.setClipboardData.'; + const keys = ['success', 'fail']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, [ + 'Content copied', + 'Copy failed, please copy manually', + ]), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, [ + 'Contenido copiado', + 'Error al copiar, copie manualmente', + ]), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ + 'Contenu copié', + 'Échec de la copie, copiez manuellement', + ]), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['内容已复制', '复制失败,请手动复制']), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['內容已復制', '復制失敗,請手動復製']), false); + } +}); +const initI18nScanCodeMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.scanCode.'; + const keys = ['title', 'album', 'fail', 'flash.on', 'flash.off']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, [ + 'Scan code', + 'Album', + 'Recognition failure', + 'Tap to turn light on', + 'Tap to turn light off', + ]), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, [ + 'Código de escaneo', + 'Álbum', + 'Échec de la reconnaissance', + 'Toque para encender la luz', + 'Toque para apagar la luz', + ]), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ + 'Code d’analyse', + 'Album', + 'Fallo de reconocimiento', + "Appuyez pour activer l'éclairage", + "Appuyez pour désactiver l'éclairage", + ]), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, [ + '扫码', + '相册', + '识别失败', + '轻触照亮', + '轻触关闭', + ]), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, [ + '掃碼', + '相冊', + '識別失敗', + '輕觸照亮', + '輕觸關閉', + ]), false); + } +}); +const initI18nStartSoterAuthenticationMsgsOnce = /*#__PURE__*/ once(() => { + const name = 'uni.startSoterAuthentication.'; + const keys = ['authContent']; + { + useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Fingerprint recognition']), false); + } + { + useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Reconocimiento de huellas dactilares']), false); + } + { + useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ + "Reconnaissance de l'empreinte digitale", + ]), false); + } + { + useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['指纹识别中...']), false); + } + { + useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['指紋識別中...']), false); + } +}); + +function initNavigationBarI18n(navigationBar) { + if (isEnableLocale()) { + return defineI18nProperties(navigationBar, [ + ['titleText'], + ['searchInput', 'placeholder'], + ]); + } +} +function initPullToRefreshI18n(pullToRefresh) { + if (isEnableLocale()) { + const CAPTION = 'caption'; + return defineI18nProperties(pullToRefresh, [ + ['contentdown', CAPTION], + ['contentover', CAPTION], + ['contentrefresh', CAPTION], + ]); + } +} - function hasCallback(args) { - if (shared.isPlainObject(args) && - [API_SUCCESS, API_FAIL, API_COMPLETE].find((cb) => shared.isFunction(args[cb]))) { - return true; - } - return false; - } - function handlePromise(promise) { - // if (false) { - // return promise - // .then((data) => { - // return [null, data] - // }) - // .catch((err) => [err]) - // } - return promise; - } - function promisify(name, fn) { - return (args = {}, ...rest) => { - if (hasCallback(args)) { - return wrapperReturnValue(name, invokeApi(name, fn, args, rest)); - } - return wrapperReturnValue(name, handlePromise(new Promise((resolve, reject) => { - invokeApi(name, fn, shared.extend(args, { success: resolve, fail: reject }), rest); - }))); - }; - } +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +function initBridge(subscribeNamespace) { + const emitter = new Emitter(); + return { + on(event, callback) { + return emitter.on(event, callback); + }, + once(event, callback) { + return emitter.once(event, callback); + }, + off(event, callback) { + return emitter.off(event, callback); + }, + emit(event, ...args) { + return emitter.emit(event, ...args); + }, + subscribe(event, callback, once = false) { + emitter[once ? 'once' : 'on'](`${subscribeNamespace}.${event}`, callback); + }, + unsubscribe(event, callback) { + emitter.off(`${subscribeNamespace}.${event}`, callback); + }, + subscribeHandler(event, args, pageId) { + emitter.emit(`${subscribeNamespace}.${event}`, args, pageId); + }, + }; +} - function formatApiArgs(args, options) { - const params = args[0]; - if (!options || - (!shared.isPlainObject(options.formatArgs) && shared.isPlainObject(params))) { - return; - } - const formatArgs = options.formatArgs; - const keys = Object.keys(formatArgs); - for (let i = 0; i < keys.length; i++) { - const name = keys[i]; - const formatterOrDefaultValue = formatArgs[name]; - if (shared.isFunction(formatterOrDefaultValue)) { - const errMsg = formatterOrDefaultValue(args[0][name], params); - if (shared.isString(errMsg)) { - return errMsg; - } - } - else { - // defaultValue - if (!shared.hasOwn(params, name)) { - params[name] = formatterOrDefaultValue; - } - } - } - } - function invokeSuccess(id, name, res) { - return invokeCallback(id, shared.extend(res || {}, { errMsg: name + ':ok' })); - } - function invokeFail(id, name, errMsg, errRes) { - return invokeCallback(id, shared.extend({ errMsg: name + ':fail' + (errMsg ? ' ' + errMsg : '') }, errRes)); - } - function beforeInvokeApi(name, args, protocol, options) { - if ((process.env.NODE_ENV !== 'production')) { - validateProtocols(name, args, protocol); - } - if (options && options.beforeInvoke) { - const errMsg = options.beforeInvoke(args); - if (shared.isString(errMsg)) { - return errMsg; - } - } - const errMsg = formatApiArgs(args, options); - if (errMsg) { - return errMsg; - } - } - function checkCallback(callback) { - if (!shared.isFunction(callback)) { - throw new Error('Invalid args: type check failed for args "callback". Expected Function'); - } - } - function wrapperOnApi(name, fn, options) { - return (callback) => { - checkCallback(callback); - const errMsg = beforeInvokeApi(name, [callback], undefined, options); - if (errMsg) { - throw new Error(errMsg); - } - // 是否是首次调用on,如果是首次,需要初始化onMethod监听 - const isFirstInvokeOnApi = !findInvokeCallbackByName(name); - createKeepAliveApiCallback(name, callback); - if (isFirstInvokeOnApi) { - onKeepAliveApiCallback(name); - fn(); - } - }; - } - function wrapperOffApi(name, fn, options) { - return (callback) => { - checkCallback(callback); - const errMsg = beforeInvokeApi(name, [callback], undefined, options); - if (errMsg) { - throw new Error(errMsg); - } - name = name.replace('off', 'on'); - removeKeepAliveApiCallback(name, callback); - // 是否还存在监听,若已不存在,则移除onMethod监听 - const hasInvokeOnApi = findInvokeCallbackByName(name); - if (!hasInvokeOnApi) { - offKeepAliveApiCallback(name); - fn(); - } - }; - } - function normalizeErrMsg(errMsg) { - if (!errMsg || shared.isString(errMsg)) { - return errMsg; - } - if (errMsg.stack) { - console.error(errMsg.message + LINEFEED + errMsg.stack); - return errMsg.message; - } - return errMsg; - } - function wrapperTaskApi(name, fn, protocol, options) { - return (args) => { - const id = createAsyncApiCallback(name, args, options); - const errMsg = beforeInvokeApi(name, [args], protocol, options); - if (errMsg) { - return invokeFail(id, name, errMsg); - } - return fn(args, { - resolve: (res) => invokeSuccess(id, name, res), - reject: (errMsg, errRes) => invokeFail(id, name, normalizeErrMsg(errMsg), errRes), - }); - }; - } - function wrapperSyncApi(name, fn, protocol, options) { - return (...args) => { - const errMsg = beforeInvokeApi(name, args, protocol, options); - if (errMsg) { - throw new Error(errMsg); - } - return fn.apply(null, args); - }; - } - function wrapperAsyncApi(name, fn, protocol, options) { - return wrapperTaskApi(name, fn, protocol, options); - } - function defineOnApi(name, fn, options) { - return wrapperOnApi(name, fn, options); - } - function defineOffApi(name, fn, options) { - return wrapperOffApi(name, fn, options); - } - function defineTaskApi(name, fn, protocol, options) { - return promisify(name, wrapperTaskApi(name, fn, (process.env.NODE_ENV !== 'production') ? protocol : undefined, options)); - } - function defineSyncApi(name, fn, protocol, options) { - return wrapperSyncApi(name, fn, (process.env.NODE_ENV !== 'production') ? protocol : undefined, options); - } - function defineAsyncApi(name, fn, protocol, options) { - return promisify(name, wrapperAsyncApi(name, fn, (process.env.NODE_ENV !== 'production') ? protocol : undefined, options)); - } +const INVOKE_VIEW_API = 'invokeViewApi'; +const INVOKE_SERVICE_API = 'invokeServiceApi'; + +function hasRpx(str) { + str = str + ''; + return str.indexOf('rpx') !== -1 || str.indexOf('upx') !== -1; +} +function rpx2px(str, replace = false) { + if (replace) { + return rpx2pxWithReplace(str); + } + if (typeof str === 'string') { + const res = parseInt(str) || 0; + if (hasRpx(str)) { + return uni.upx2px(res); + } + return res; + } + return str; +} +function rpx2pxWithReplace(str) { + if (!hasRpx(str)) { + return str; + } + return str.replace(/(\d+(\.\d+)?)[ru]px/g, (_a, b) => { + return uni.upx2px(parseFloat(b)) + 'px'; + }); +} - const API_BASE64_TO_ARRAY_BUFFER = 'base64ToArrayBuffer'; - const Base64ToArrayBufferProtocol = [ - { - name: 'base64', - type: String, - required: true, - }, - ]; - const API_ARRAY_BUFFER_TO_BASE64 = 'arrayBufferToBase64'; - const ArrayBufferToBase64Protocol = [ - { - name: 'arrayBuffer', - type: [ArrayBuffer, Uint8Array], - required: true, - }, - ]; - - // @ts-ignore - const base64ToArrayBuffer = defineSyncApi(API_BASE64_TO_ARRAY_BUFFER, (base64) => { - return decode$1(base64); - }, Base64ToArrayBufferProtocol); - const arrayBufferToBase64 = defineSyncApi(API_ARRAY_BUFFER_TO_BASE64, (arrayBuffer) => { - return encode$3(arrayBuffer); - }, ArrayBufferToBase64Protocol); - - /** - * 简易版systemInfo,主要为upx2px,i18n服务 - * @returns - */ - function getBaseSystemInfo() { - // @ts-expect-error view 层 - if (typeof __SYSTEM_INFO__ !== 'undefined') { - return window.__SYSTEM_INFO__; - } - const { resolutionWidth } = plus.screen.getCurrentSize(); - return { - platform: (plus.os.name || '').toLowerCase(), - pixelRatio: plus.screen.scale, - windowWidth: Math.round(resolutionWidth), - }; - } +function getPageIdByVm(instance) { + const vm = resolveComponentInstance(instance); + if (vm.$page) { + return vm.$page.id; + } + if (!vm.$) { + return; + } + const rootProxy = vm.$.root.proxy; + if (rootProxy && rootProxy.$page) { + return rootProxy.$page.id; + } +} +function getCurrentPage() { + const pages = getCurrentPages(); + const len = pages.length; + if (len) { + return pages[len - 1]; + } +} +function getCurrentPageMeta() { + const page = getCurrentPage(); + if (page) { + return page.$page.meta; + } +} +function getCurrentPageId() { + const meta = getCurrentPageMeta(); + if (meta) { + return meta.id; + } + return -1; +} +function getCurrentPageVm() { + const page = getCurrentPage(); + if (page) { + return page.$vm; + } +} +const PAGE_META_KEYS = ['navigationBar', 'pullToRefresh']; +function initGlobalStyle() { + return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {})); +} +function initRouteMeta(pageMeta, id) { + const globalStyle = initGlobalStyle(); + const res = extend({ id }, globalStyle, pageMeta); + PAGE_META_KEYS.forEach((name) => { + res[name] = extend({}, globalStyle[name], pageMeta[name]); + }); + const { navigationBar } = res; + navigationBar.titleText && + navigationBar.titleImage && + (navigationBar.titleText = ''); + return res; +} +function normalizePullToRefreshRpx(pullToRefresh) { + if (pullToRefresh.offset) { + pullToRefresh.offset = rpx2px(pullToRefresh.offset); + } + if (pullToRefresh.height) { + pullToRefresh.height = rpx2px(pullToRefresh.height); + } + if (pullToRefresh.range) { + pullToRefresh.range = rpx2px(pullToRefresh.range); + } + return pullToRefresh; +} +function initPageInternalInstance(openType, url, pageQuery, meta, eventChannel) { + const { id, route } = meta; + return { + id: id, + path: addLeadingSlash(route), + route: route, + fullPath: url, + options: pageQuery, + meta, + openType, + eventChannel, + statusBarStyle: meta.navigationBar.titleColor === '#000000' ? 'dark' : 'light', + }; +} - function requestComponentInfo(page, reqs, callback) { - UniServiceJSBridge.invokeViewMethod('requestComponentInfo', { - reqs: reqs.map((req) => { - if (req.component) { - req.component = req.component.$el.nodeId; - } - return req; - }), - }, page.$page.id, callback); - } +function invokeHook(vm, name, args) { + if (isString(vm)) { + args = name; + name = vm; + vm = getCurrentPageVm(); + } + else if (typeof vm === 'number') { + const page = getCurrentPages().find((page) => page.$page.id === vm); + if (page) { + vm = page.$vm; + } + else { + vm = getCurrentPageVm(); + } + } + if (!vm) { + return; + } + // 兼容 nvue + { + if (vm.__call_hook) { + return vm.__call_hook(name, args); + } + } + const hooks = vm.$[name]; + return hooks && invokeArrayFns(hooks, args); +} - function setCurrentPageMeta(page, options) { - UniServiceJSBridge.invokeViewMethod('setPageMeta', options, page.$page.id); - } +function normalizeRoute(toRoute) { + if (toRoute.indexOf('/') === 0) { + return toRoute; + } + let fromRoute = ''; + const pages = getCurrentPages(); + if (pages.length) { + fromRoute = pages[pages.length - 1].$page.route; + } + return getRealRoute(fromRoute, toRoute); +} +function getRealRoute(fromRoute, toRoute) { + if (toRoute.indexOf('/') === 0) { + return toRoute; + } + if (toRoute.indexOf('./') === 0) { + return getRealRoute(fromRoute, toRoute.substr(2)); + } + const toRouteArray = toRoute.split('/'); + const toRouteLength = toRouteArray.length; + let i = 0; + for (; i < toRouteLength && toRouteArray[i] === '..'; i++) { + // noop + } + toRouteArray.splice(0, i); + toRoute = toRouteArray.join('/'); + const fromRouteArray = fromRoute.length > 0 ? fromRoute.split('/') : []; + fromRouteArray.splice(fromRouteArray.length - i - 1, i + 1); + return addLeadingSlash(fromRouteArray.concat(toRouteArray).join('/')); +} +function getRouteOptions(path, alias = false) { + if (alias) { + return __uniRoutes.find((route) => route.path === path || route.alias === path); + } + return __uniRoutes.find((route) => route.path === path); +} +function getRouteMeta(path) { + const routeOptions = getRouteOptions(path); + if (routeOptions) { + return routeOptions.meta; + } +} - const isArray = Array.isArray; - const isObject = (val) => val !== null && typeof val === 'object'; - const defaultDelimiters = ['{', '}']; - class BaseFormatter { - constructor() { - this._caches = Object.create(null); - } - interpolate(message, values, delimiters = defaultDelimiters) { - if (!values) { - return [message]; - } - let tokens = this._caches[message]; - if (!tokens) { - tokens = parse(message, delimiters); - this._caches[message] = tokens; - } - return compile(tokens, values); - } - } - const RE_TOKEN_LIST_VALUE = /^(?:\d)+/; - const RE_TOKEN_NAMED_VALUE = /^(?:\w)+/; - function parse(format, [startDelimiter, endDelimiter]) { - const tokens = []; - let position = 0; - let text = ''; - while (position < format.length) { - let char = format[position++]; - if (char === startDelimiter) { - if (text) { - tokens.push({ type: 'text', value: text }); - } - text = ''; - let sub = ''; - char = format[position++]; - while (char !== undefined && char !== endDelimiter) { - sub += char; - char = format[position++]; - } - const isClosed = char === endDelimiter; - const type = RE_TOKEN_LIST_VALUE.test(sub) - ? 'list' - : isClosed && RE_TOKEN_NAMED_VALUE.test(sub) - ? 'named' - : 'unknown'; - tokens.push({ value: sub, type }); - } - // else if (char === '%') { - // // when found rails i18n syntax, skip text capture - // if (format[position] !== '{') { - // text += char - // } - // } - else { - text += char; - } - } - text && tokens.push({ type: 'text', value: text }); - return tokens; - } - function compile(tokens, values) { - const compiled = []; - let index = 0; - const mode = isArray(values) - ? 'list' - : isObject(values) - ? 'named' - : 'unknown'; - if (mode === 'unknown') { - return compiled; - } - while (index < tokens.length) { - const token = tokens[index]; - switch (token.type) { - case 'text': - compiled.push(token.value); - break; - case 'list': - compiled.push(values[parseInt(token.value, 10)]); - break; - case 'named': - if (mode === 'named') { - compiled.push(values[token.value]); - } - else { - if (process.env.NODE_ENV !== 'production') { - console.warn(`Type of token '${token.type}' and format of value '${mode}' don't match!`); - } - } - break; - case 'unknown': - if (process.env.NODE_ENV !== 'production') { - console.warn(`Detect 'unknown' type of token!`); - } - break; - } - index++; - } - return compiled; - } +const invokeOnCallback = (name, res) => UniServiceJSBridge.emit('api.' + name, res); + +let invokeViewMethodId = 1; +function publishViewMethodName() { + return getCurrentPageId() + '.' + INVOKE_VIEW_API; +} +const invokeViewMethod = (name, args, pageId, callback) => { + const { subscribe, publishHandler } = UniServiceJSBridge; + const id = callback ? invokeViewMethodId++ : 0; + callback && subscribe(INVOKE_VIEW_API + '.' + id, callback, true); + publishHandler(publishViewMethodName(), { id, name, args }, pageId); +}; +const invokeViewMethodKeepAlive = (name, args, callback, pageId) => { + const { subscribe, unsubscribe, publishHandler } = UniServiceJSBridge; + const id = invokeViewMethodId++; + const subscribeName = INVOKE_VIEW_API + '.' + id; + subscribe(subscribeName, callback); + publishHandler(publishViewMethodName(), { id, name, args }, pageId); + return () => { + unsubscribe(subscribeName); + }; +}; + +const serviceMethods = Object.create(null); +function subscribeServiceMethod() { + UniServiceJSBridge.subscribe(INVOKE_SERVICE_API, onInvokeServiceMethod); +} +function registerServiceMethod(name, fn) { + if (!serviceMethods[name]) { + serviceMethods[name] = fn; + } +} +function onInvokeServiceMethod({ id, name, args, }, pageId) { + const publish = (res) => { + id && + UniServiceJSBridge.publishHandler(INVOKE_SERVICE_API + '.' + id, res, pageId); + }; + const handler = serviceMethods[name]; + if (handler) { + handler(args, publish); + } + else { + publish({}); + } +} - const LOCALE_ZH_HANS = 'zh-Hans'; - const LOCALE_ZH_HANT = 'zh-Hant'; - const LOCALE_EN = 'en'; - const LOCALE_FR = 'fr'; - const LOCALE_ES = 'es'; - const hasOwnProperty = Object.prototype.hasOwnProperty; - const hasOwn = (val, key) => hasOwnProperty.call(val, key); - const defaultFormatter = new BaseFormatter(); - function include(str, parts) { - return !!parts.find((part) => str.indexOf(part) !== -1); - } - function startsWith(str, parts) { - return parts.find((part) => str.indexOf(part) === 0); - } - function normalizeLocale(locale, messages) { - if (!locale) { - return; - } - locale = locale.trim().replace(/_/g, '-'); - if (messages && messages[locale]) { - return locale; - } - locale = locale.toLowerCase(); - if (locale === 'chinese') { - // 支付宝 - return LOCALE_ZH_HANS; - } - if (locale.indexOf('zh') === 0) { - if (locale.indexOf('-hans') > -1) { - return LOCALE_ZH_HANS; - } - if (locale.indexOf('-hant') > -1) { - return LOCALE_ZH_HANT; - } - if (include(locale, ['-tw', '-hk', '-mo', '-cht'])) { - return LOCALE_ZH_HANT; - } - return LOCALE_ZH_HANS; - } - const lang = startsWith(locale, [LOCALE_EN, LOCALE_FR, LOCALE_ES]); - if (lang) { - return lang; - } - } - class I18n { - constructor({ locale, fallbackLocale, messages, watcher, formater, }) { - this.locale = LOCALE_EN; - this.fallbackLocale = LOCALE_EN; - this.message = {}; - this.messages = {}; - this.watchers = []; - if (fallbackLocale) { - this.fallbackLocale = fallbackLocale; - } - this.formater = formater || defaultFormatter; - this.messages = messages || {}; - this.setLocale(locale || LOCALE_EN); - if (watcher) { - this.watchLocale(watcher); - } - } - setLocale(locale) { - const oldLocale = this.locale; - this.locale = normalizeLocale(locale, this.messages) || this.fallbackLocale; - if (!this.messages[this.locale]) { - // 可能初始化时不存在 - this.messages[this.locale] = {}; - } - this.message = this.messages[this.locale]; - // 仅发生变化时,通知 - if (oldLocale !== this.locale) { - this.watchers.forEach((watcher) => { - watcher(this.locale, oldLocale); - }); - } - } - getLocale() { - return this.locale; - } - watchLocale(fn) { - const index = this.watchers.push(fn) - 1; - return () => { - this.watchers.splice(index, 1); - }; - } - add(locale, message, override = true) { - const curMessages = this.messages[locale]; - if (curMessages) { - if (override) { - Object.assign(curMessages, message); - } - else { - Object.keys(message).forEach((key) => { - if (!hasOwn(curMessages, key)) { - curMessages[key] = message[key]; - } - }); - } - } - else { - this.messages[locale] = message; - } - } - f(message, values, delimiters) { - return this.formater.interpolate(message, values, delimiters).join(''); - } - t(key, locale, values) { - let message = this.message; - if (typeof locale === 'string') { - locale = normalizeLocale(locale, this.messages); - locale && (message = this.messages[locale]); - } - else { - values = locale; - } - if (!hasOwn(message, key)) { - console.warn(`Cannot translate the value of keypath ${key}. Use the value of keypath as default.`); - return key; - } - return this.formater.interpolate(message[key], values).join(''); - } - } +const ServiceJSBridge = /*#__PURE__*/ extend(initBridge('view' /* view 指的是 service 层订阅的是 view 层事件 */), { + invokeOnCallback, + invokeViewMethod, + invokeViewMethodKeepAlive, +}); + +function initOn() { + const { on } = UniServiceJSBridge; + on(ON_RESIZE, onResize); + on(ON_APP_ENTER_FOREGROUND, onAppEnterForeground); + on(ON_APP_ENTER_BACKGROUND, onAppEnterBackground); +} +function onResize(res) { + invokeHook(getCurrentPage(), ON_RESIZE, res); + UniServiceJSBridge.invokeOnCallback('onWindowResize', res); // API +} +function onAppEnterForeground(enterOptions) { + const page = getCurrentPage(); + invokeHook(getApp(), ON_SHOW, enterOptions); + invokeHook(page, ON_SHOW); +} +function onAppEnterBackground() { + invokeHook(getApp(), ON_HIDE); + invokeHook(getCurrentPage(), ON_HIDE); +} - function watchAppLocale(appVm, i18n) { - // 需要保证 watch 的触发在组件渲染之前 - if (appVm.$watchLocale) { - // vue2 - appVm.$watchLocale((newLocale) => { - i18n.setLocale(newLocale); - }); - } - else { - appVm.$watch(() => appVm.$locale, (newLocale) => { - i18n.setLocale(newLocale); - }); - } - } - function getDefaultLocale() { - if (typeof uni !== 'undefined' && uni.getLocale) { - return uni.getLocale(); - } - // 小程序平台,uni 和 uni-i18n 互相引用,导致访问不到 uni,故在 global 上挂了 getLocale - if (typeof global !== 'undefined' && global.getLocale) { - return global.getLocale(); - } - return LOCALE_EN; - } - function initVueI18n(locale, messages = {}, fallbackLocale, watcher) { - // 兼容旧版本入参 - if (typeof locale !== 'string') { - [locale, messages] = [ - messages, - locale, - ]; - } - if (typeof locale !== 'string') { - // 因为小程序平台,uni-i18n 和 uni 互相引用,导致此时访问 uni 时,为 undefined - locale = getDefaultLocale(); - } - if (typeof fallbackLocale !== 'string') { - fallbackLocale = - (typeof __uniConfig !== 'undefined' && __uniConfig.fallbackLocale) || - LOCALE_EN; - } - const i18n = new I18n({ - locale, - fallbackLocale, - messages, - watcher, - }); - let t = (key, values) => { - if (typeof getApp !== 'function') { - // app view - /* eslint-disable no-func-assign */ - t = function (key, values) { - return i18n.t(key, values); - }; - } - else { - let isWatchedAppLocale = false; - t = function (key, values) { - const appVm = getApp().$vm; - // 可能$vm还不存在,比如在支付宝小程序中,组件定义较早,在props的default里使用了t()函数(如uni-goods-nav),此时app还未初始化 - // options: { - // type: Array, - // default () { - // return [{ - // icon: 'shop', - // text: t("uni-goods-nav.options.shop"), - // }, { - // icon: 'cart', - // text: t("uni-goods-nav.options.cart") - // }] - // } - // }, - if (appVm) { - // 触发响应式 - appVm.$locale; - if (!isWatchedAppLocale) { - isWatchedAppLocale = true; - watchAppLocale(appVm, i18n); - } - } - return i18n.t(key, values); - }; - } - return t(key, values); - }; - return { - i18n, - f(message, values, delimiters) { - return i18n.f(message, values, delimiters); - }, - t(key, values) { - return t(key, values); - }, - add(locale, message, override = true) { - return i18n.add(locale, message, override); - }, - watch(fn) { - return i18n.watchLocale(fn); - }, - getLocale() { - return i18n.getLocale(); - }, - setLocale(newLocale) { - return i18n.setLocale(newLocale); - }, - }; - } - function isI18nStr(value, delimiters) { - return value.indexOf(delimiters[0]) > -1; - } +const SUBSCRIBE_LIFECYCLE_HOOKS = [ON_PAGE_SCROLL, ON_REACH_BOTTOM]; +function initSubscribe() { + SUBSCRIBE_LIFECYCLE_HOOKS.forEach((name) => UniServiceJSBridge.subscribe(name, createPageEvent(name))); +} +function createPageEvent(name) { + return (args, pageId) => { + invokeHook(parseInt(pageId), name, args); + }; +} - const isEnableLocale = once(() => typeof __uniConfig !== 'undefined' && - __uniConfig.locales && - !!Object.keys(__uniConfig.locales).length); - - let i18n; - function getLocaleMessage() { - const locale = uni.getLocale(); - const locales = __uniConfig.locales; - return (locales[locale] || locales[__uniConfig.fallbackLocale] || locales.en || {}); - } - function formatI18n(message) { - if (isI18nStr(message, I18N_JSON_DELIMITERS)) { - return useI18n().f(message, getLocaleMessage(), I18N_JSON_DELIMITERS); - } - return message; - } - function resolveJsonObj(jsonObj, names) { - if (names.length === 1) { - if (jsonObj) { - const value = jsonObj[names[0]]; - if (shared.isString(value) && isI18nStr(value, I18N_JSON_DELIMITERS)) { - return jsonObj; - } - } - return; - } - const name = names.shift(); - return resolveJsonObj(jsonObj && jsonObj[name], names); - } - function defineI18nProperties(obj, names) { - return names.map((name) => defineI18nProperty(obj, name)); - } - function defineI18nProperty(obj, names) { - const jsonObj = resolveJsonObj(obj, names); - if (!jsonObj) { - return false; - } - const prop = names[names.length - 1]; - let value = jsonObj[prop]; - Object.defineProperty(jsonObj, prop, { - get() { - return formatI18n(value); - }, - set(v) { - value = v; - }, - }); - return true; - } - function useI18n() { - if (!i18n) { - let locale; - { - if (typeof getApp === 'function') { - locale = weex.requireModule('plus').getLanguage(); - } - else { - locale = plus.webview.currentWebview().getStyle().locale; - } - } - i18n = initVueI18n(locale); - // 自定义locales - if (isEnableLocale()) { - const localeKeys = Object.keys(__uniConfig.locales || {}); - if (localeKeys.length) { - localeKeys.forEach((locale) => i18n.add(locale, __uniConfig.locales[locale])); - } - // initVueI18n 时 messages 还没有,导致用户自定义 locale 可能不生效,当设置完 messages 后,重新设置 locale - i18n.setLocale(locale); - } - } - return i18n; - } +function initService() { + { + initOn(); + initSubscribe(); + } +} +function initAppVm(appVm) { + appVm.$vm = appVm; + appVm.$mpType = 'app'; + const locale = ref(useI18n().getLocale()); + Object.defineProperty(appVm, '$locale', { + get() { + { + uni.$nvueState && uni.$nvueState.locale; + } + return locale.value; + }, + set(v) { + { + uni.$nvueState && (uni.$nvueState.locale = v); + } + locale.value = v; + }, + }); +} +function initPageVm(pageVm, page) { + pageVm.route = page.route; + pageVm.$vm = pageVm; + pageVm.$page = page; + pageVm.$mpType = 'page'; + if (page.meta.isTabBar) { + pageVm.$.__isTabBar = true; + // TODO preload? 初始化时,状态肯定是激活 + pageVm.$.__isActive = true; + } +} - // This file is created by scripts/i18n.js - function normalizeMessages(module, keys, values) { - return keys.reduce((res, name, index) => { - res[module + name] = values[index]; - return res; - }, {}); - } - const initI18nAppMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.app.'; - const keys = ['quit']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Press back button again to exit']), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Pulse otra vez para salir']), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ - "Appuyez à nouveau pour quitter l'application", - ]), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['再按一次退出应用']), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['再按一次退出應用']), false); - } - }); - const initI18nShowActionSheetMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.showActionSheet.'; - const keys = ['cancel']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel']), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar']), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler']), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消']), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消']), false); - } - }); - const initI18nShowModalMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.showModal.'; - const keys = ['cancel', 'confirm']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel', 'OK']), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar', 'OK']), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler', 'OK']), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消', '确定']), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消', '確定']), false); - } - }); - const initI18nChooseImageMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.chooseImage.'; - const keys = ['cancel', 'sourceType.album', 'sourceType.camera']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel', 'Album', 'Camera']), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar', 'Álbum', 'Cámara']), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler', 'Album', 'Caméra']), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消', '从相册选择', '拍摄']), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消', '從相冊選擇', '拍攝']), false); - } - }); - const initI18nChooseVideoMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.chooseVideo.'; - const keys = ['cancel', 'sourceType.album', 'sourceType.camera']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Cancel', 'Album', 'Camera']), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Cancelar', 'Álbum', 'Cámara']), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, ['Annuler', 'Album', 'Caméra']), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['取消', '从相册选择', '拍摄']), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['取消', '從相冊選擇', '拍攝']), false); - } - }); - const initI18nPreviewImageMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.previewImage.'; - const keys = ['cancel', 'button.save', 'save.success', 'save.fail']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, [ - 'Cancel', - 'Save Image', - 'Saved successfully', - 'Save failed', - ]), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, [ - 'Cancelar', - 'Guardar imagen', - 'Guardado exitosamente', - 'Error al guardar', - ]), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ - 'Annuler', - 'Guardar imagen', - 'Enregistré avec succès', - 'Échec de la sauvegarde', - ]), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, [ - '取消', - '保存图像', - '保存图像到相册成功', - '保存图像到相册失败', - ]), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, [ - '取消', - '保存圖像', - '保存圖像到相冊成功', - '保存圖像到相冊失敗', - ]), false); - } - }); - const initI18nSetClipboardDataMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.setClipboardData.'; - const keys = ['success', 'fail']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, [ - 'Content copied', - 'Copy failed, please copy manually', - ]), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, [ - 'Contenido copiado', - 'Error al copiar, copie manualmente', - ]), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ - 'Contenu copié', - 'Échec de la copie, copiez manuellement', - ]), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['内容已复制', '复制失败,请手动复制']), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['內容已復制', '復制失敗,請手動復製']), false); - } - }); - const initI18nScanCodeMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.scanCode.'; - const keys = ['title', 'album', 'fail', 'flash.on', 'flash.off']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, [ - 'Scan code', - 'Album', - 'Recognition failure', - 'Tap to turn light on', - 'Tap to turn light off', - ]), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, [ - 'Código de escaneo', - 'Álbum', - 'Échec de la reconnaissance', - 'Toque para encender la luz', - 'Toque para apagar la luz', - ]), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ - 'Code d’analyse', - 'Album', - 'Fallo de reconocimiento', - "Appuyez pour activer l'éclairage", - "Appuyez pour désactiver l'éclairage", - ]), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, [ - '扫码', - '相册', - '识别失败', - '轻触照亮', - '轻触关闭', - ]), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, [ - '掃碼', - '相冊', - '識別失敗', - '輕觸照亮', - '輕觸關閉', - ]), false); - } - }); - const initI18nStartSoterAuthenticationMsgsOnce = /*#__PURE__*/ once(() => { - const name = 'uni.startSoterAuthentication.'; - const keys = ['authContent']; - { - useI18n().add(LOCALE_EN, normalizeMessages(name, keys, ['Fingerprint recognition']), false); - } - { - useI18n().add(LOCALE_ES, normalizeMessages(name, keys, ['Reconocimiento de huellas dactilares']), false); - } - { - useI18n().add(LOCALE_FR, normalizeMessages(name, keys, [ - "Reconnaissance de l'empreinte digitale", - ]), false); - } - { - useI18n().add(LOCALE_ZH_HANS, normalizeMessages(name, keys, ['指纹识别中...']), false); - } - { - useI18n().add(LOCALE_ZH_HANT, normalizeMessages(name, keys, ['指紋識別中...']), false); - } - }); - - function initNavigationBarI18n(navigationBar) { - if (isEnableLocale()) { - return defineI18nProperties(navigationBar, [ - ['titleText'], - ['searchInput', 'placeholder'], - ]); - } - } - function initPullToRefreshI18n(pullToRefresh) { - if (isEnableLocale()) { - const CAPTION = 'caption'; - return defineI18nProperties(pullToRefresh, [ - ['contentdown', CAPTION], - ['contentover', CAPTION], - ['contentrefresh', CAPTION], - ]); - } - } +function querySelector(vm, selector) { + const el = vm.$el.querySelector(selector); + return el && el.__vue__; +} +function querySelectorAll(vm, selector) { + const nodeList = vm.$el.querySelectorAll(selector); + if (nodeList) { + return [...nodeList].map((node) => node.__vue__).filter(Boolean); + } + return []; +} +function createSelectorQuery$1() { + return uni.createSelectorQuery().in(this); +} +function createMediaQueryObserver$1() { + return uni.createMediaQueryObserver(this); +} +function createIntersectionObserver$1(options) { + return uni.createIntersectionObserver(this, options); +} +function selectComponent(selector) { + return querySelector(this, selector); +} +function selectAllComponents(selector) { + return querySelectorAll(this, selector); +} - const E = function () { - // Keep this empty so it's easier to inherit from - // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) - }; - E.prototype = { - on: function (name, callback, ctx) { - var e = this.e || (this.e = {}); - (e[name] || (e[name] = [])).push({ - fn: callback, - ctx: ctx, - }); - return this; - }, - once: function (name, callback, ctx) { - var self = this; - function listener() { - self.off(name, listener); - callback.apply(ctx, arguments); - } - listener._ = callback; - return this.on(name, listener, ctx); - }, - emit: function (name) { - var data = [].slice.call(arguments, 1); - var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); - var i = 0; - var len = evtArr.length; - for (i; i < len; i++) { - evtArr[i].fn.apply(evtArr[i].ctx, data); - } - return this; - }, - off: function (name, callback) { - var e = this.e || (this.e = {}); - var evts = e[name]; - var liveEvents = []; - if (evts && callback) { - for (var i = 0, len = evts.length; i < len; i++) { - if (evts[i].fn !== callback && evts[i].fn._ !== callback) - liveEvents.push(evts[i]); - } - } - // Remove event from queue to prevent memory leak - // Suggested by https://github.com/lazd - // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 - liveEvents.length ? (e[name] = liveEvents) : delete e[name]; - return this; - }, - }; - var Emitter = E; - - function initBridge(subscribeNamespace) { - const emitter = new Emitter(); - return { - on(event, callback) { - return emitter.on(event, callback); - }, - once(event, callback) { - return emitter.once(event, callback); - }, - off(event, callback) { - return emitter.off(event, callback); - }, - emit(event, ...args) { - return emitter.emit(event, ...args); - }, - subscribe(event, callback, once = false) { - emitter[once ? 'once' : 'on'](`${subscribeNamespace}.${event}`, callback); - }, - unsubscribe(event, callback) { - emitter.off(`${subscribeNamespace}.${event}`, callback); - }, - subscribeHandler(event, args, pageId) { - emitter.emit(`${subscribeNamespace}.${event}`, args, pageId); - }, - }; - } +var wxInstance = { + __proto__: null, + createSelectorQuery: createSelectorQuery$1, + createMediaQueryObserver: createMediaQueryObserver$1, + createIntersectionObserver: createIntersectionObserver$1, + selectComponent: selectComponent, + selectAllComponents: selectAllComponents +}; + +function getOpenerEventChannel() { + // TODO App +} - const INVOKE_VIEW_API = 'invokeViewApi'; - const INVOKE_SERVICE_API = 'invokeServiceApi'; - - function hasRpx(str) { - str = str + ''; - return str.indexOf('rpx') !== -1 || str.indexOf('upx') !== -1; - } - function rpx2px(str, replace = false) { - if (replace) { - return rpx2pxWithReplace(str); - } - if (typeof str === 'string') { - const res = parseInt(str) || 0; - if (hasRpx(str)) { - return uni.upx2px(res); - } - return res; - } - return str; - } - function rpx2pxWithReplace(str) { - if (!hasRpx(str)) { - return str; - } - return str.replace(/(\d+(\.\d+)?)[ru]px/g, (_a, b) => { - return uni.upx2px(parseFloat(b)) + 'px'; - }); - } +function initAppConfig(appConfig) { + const globalProperties = appConfig.globalProperties; + globalProperties.getOpenerEventChannel = getOpenerEventChannel; + { + extend(globalProperties, wxInstance); + } +} - function getPageIdByVm(instance) { - const vm = resolveComponentInstance(instance); - if (vm.$page) { - return vm.$page.id; - } - if (!vm.$) { - return; - } - const rootProxy = vm.$.root.proxy; - if (rootProxy && rootProxy.$page) { - return rootProxy.$page.id; - } - } - function getCurrentPage() { - const pages = getCurrentPages(); - const len = pages.length; - if (len) { - return pages[len - 1]; - } - } - function getCurrentPageMeta() { - const page = getCurrentPage(); - if (page) { - return page.$page.meta; - } - } - function getCurrentPageId() { - const meta = getCurrentPageMeta(); - if (meta) { - return meta.id; - } - return -1; - } - function getCurrentPageVm() { - const page = getCurrentPage(); - if (page) { - return page.$vm; - } - } - const PAGE_META_KEYS = ['navigationBar', 'pullToRefresh']; - function initGlobalStyle() { - return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {})); - } - function initRouteMeta(pageMeta, id) { - const globalStyle = initGlobalStyle(); - const res = shared.extend({ id }, globalStyle, pageMeta); - PAGE_META_KEYS.forEach((name) => { - res[name] = shared.extend({}, globalStyle[name], pageMeta[name]); - }); - const { navigationBar } = res; - navigationBar.titleText && - navigationBar.titleImage && - (navigationBar.titleText = ''); - return res; - } - function normalizePullToRefreshRpx(pullToRefresh) { - if (pullToRefresh.offset) { - pullToRefresh.offset = rpx2px(pullToRefresh.offset); - } - if (pullToRefresh.height) { - pullToRefresh.height = rpx2px(pullToRefresh.height); - } - if (pullToRefresh.range) { - pullToRefresh.range = rpx2px(pullToRefresh.range); - } - return pullToRefresh; - } - function initPageInternalInstance(openType, url, pageQuery, meta, eventChannel) { - const { id, route } = meta; - return { - id: id, - path: addLeadingSlash(route), - route: route, - fullPath: url, - options: pageQuery, - meta, - openType, - eventChannel, - statusBarStyle: meta.navigationBar.titleColor === '#000000' ? 'dark' : 'light', - }; - } +function initServicePlugin(app) { + initAppConfig(app._context.config); +} - function invokeHook(vm, name, args) { - if (shared.isString(vm)) { - args = name; - name = vm; - vm = getCurrentPageVm(); - } - else if (typeof vm === 'number') { - const page = getCurrentPages().find((page) => page.$page.id === vm); - if (page) { - vm = page.$vm; - } - else { - vm = getCurrentPageVm(); - } - } - if (!vm) { - return; - } - // 兼容 nvue - { - if (vm.__call_hook) { - return vm.__call_hook(name, args); - } - } - const hooks = vm.$[name]; - return hooks && invokeArrayFns(hooks, args); - } +function createLaunchOptions() { + return { + path: '', + query: {}, + scene: 1001, + referrerInfo: { + appId: '', + extraData: {}, + }, + }; +} +function defineGlobalData(app, defaultGlobalData) { + const options = app.$options || {}; + options.globalData = extend(options.globalData || {}, defaultGlobalData); + Object.defineProperty(app, 'globalData', { + get() { + return options.globalData; + }, + set(newGlobalData) { + options.globalData = newGlobalData; + }, + }); +} - function normalizeRoute(toRoute) { - if (toRoute.indexOf('/') === 0) { - return toRoute; - } - let fromRoute = ''; - const pages = getCurrentPages(); - if (pages.length) { - fromRoute = pages[pages.length - 1].$page.route; - } - return getRealRoute(fromRoute, toRoute); - } - function getRealRoute(fromRoute, toRoute) { - if (toRoute.indexOf('/') === 0) { - return toRoute; - } - if (toRoute.indexOf('./') === 0) { - return getRealRoute(fromRoute, toRoute.substr(2)); - } - const toRouteArray = toRoute.split('/'); - const toRouteLength = toRouteArray.length; - let i = 0; - for (; i < toRouteLength && toRouteArray[i] === '..'; i++) { - // noop - } - toRouteArray.splice(0, i); - toRoute = toRouteArray.join('/'); - const fromRouteArray = fromRoute.length > 0 ? fromRoute.split('/') : []; - fromRouteArray.splice(fromRouteArray.length - i - 1, i + 1); - return addLeadingSlash(fromRouteArray.concat(toRouteArray).join('/')); - } - function getRouteOptions(path, alias = false) { - if (alias) { - return __uniRoutes.find((route) => route.path === path || route.alias === path); - } - return __uniRoutes.find((route) => route.path === path); - } - function getRouteMeta(path) { - const routeOptions = getRouteOptions(path); - if (routeOptions) { - return routeOptions.meta; - } - } +function getRealPath(filepath) { + // 无协议的情况补全 https + if (filepath.indexOf('//') === 0) { + return 'https:' + filepath; + } + // 网络资源或base64 + if (SCHEME_RE.test(filepath) || DATA_RE.test(filepath)) { + return filepath; + } + if (isSystemURL(filepath)) { + return 'file://' + normalizeLocalPath(filepath); + } + const wwwPath = 'file://' + normalizeLocalPath('_www'); + // 绝对路径转换为本地文件系统路径 + if (filepath.indexOf('/') === 0) { + // 平台绝对路径 安卓、iOS + if (filepath.startsWith('/storage/') || + filepath.startsWith('/sdcard/') || + filepath.includes('/Containers/Data/Application/')) { + return 'file://' + filepath; + } + return wwwPath + filepath; + } + // 相对资源 + if (filepath.indexOf('../') === 0 || filepath.indexOf('./') === 0) { + // @ts-expect-error app-view + if (typeof __id__ === 'string') { + // @ts-expect-error app-view + return wwwPath + getRealRoute(addLeadingSlash(__id__), filepath); + } + else { + const page = getCurrentPage(); + if (page) { + return wwwPath + getRealRoute(addLeadingSlash(page.route), filepath); + } + } + } + return filepath; +} +const normalizeLocalPath = cacheStringFunction((filepath) => { + return plus.io + .convertLocalFileSystemURL(filepath) + .replace(/^\/?apps\//, '/android_asset/apps/') + .replace(/\/$/, ''); +}); +function isSystemURL(filepath) { + if (filepath.indexOf('_www') === 0 || + filepath.indexOf('_doc') === 0 || + filepath.indexOf('_documents') === 0 || + filepath.indexOf('_downloads') === 0) { + return true; + } + return false; +} - const invokeOnCallback = (name, res) => UniServiceJSBridge.emit('api.' + name, res); - - let invokeViewMethodId = 1; - function publishViewMethodName() { - return getCurrentPageId() + '.' + INVOKE_VIEW_API; - } - const invokeViewMethod = (name, args, pageId, callback) => { - const { subscribe, publishHandler } = UniServiceJSBridge; - const id = callback ? invokeViewMethodId++ : 0; - callback && subscribe(INVOKE_VIEW_API + '.' + id, callback, true); - publishHandler(publishViewMethodName(), { id, name, args }, pageId); - }; - const invokeViewMethodKeepAlive = (name, args, callback, pageId) => { - const { subscribe, unsubscribe, publishHandler } = UniServiceJSBridge; - const id = invokeViewMethodId++; - const subscribeName = INVOKE_VIEW_API + '.' + id; - subscribe(subscribeName, callback); - publishHandler(publishViewMethodName(), { id, name, args }, pageId); - return () => { - unsubscribe(subscribeName); - }; - }; - - const serviceMethods = Object.create(null); - function subscribeServiceMethod() { - UniServiceJSBridge.subscribe(INVOKE_SERVICE_API, onInvokeServiceMethod); - } - function registerServiceMethod(name, fn) { - if (!serviceMethods[name]) { - serviceMethods[name] = fn; - } - } - function onInvokeServiceMethod({ id, name, args, }, pageId) { - const publish = (res) => { - id && - UniServiceJSBridge.publishHandler(INVOKE_SERVICE_API + '.' + id, res, pageId); - }; - const handler = serviceMethods[name]; - if (handler) { - handler(args, publish); - } - else { - publish({}); - } - } +const SUCCESS = 'success'; +const FAIL = 'fail'; +const COMPLETE = 'complete'; +const CALLBACKS = [SUCCESS, FAIL, COMPLETE]; +/** + * 调用无参数,或仅一个参数且为 callback 的 API + * @param {Object} vm + * @param {Object} method + * @param {Object} args + * @param {Object} extras + */ +function invokeVmMethodWithoutArgs(vm, method, args, extras) { + if (!vm) { + return; + } + if (typeof args === 'undefined') { + return vm[method](); + } + const [, callbacks] = normalizeArgs(args, extras); + if (!Object.keys(callbacks).length) { + return vm[method](); + } + return vm[method](normalizeCallback(method, callbacks)); +} +/** + * 调用两个参数(第一个入参为普通参数,第二个入参为 callback) API + * @param {Object} vm + * @param {Object} method + * @param {Object} args + * @param {Object} extras + */ +function invokeVmMethod(vm, method, args, extras) { + if (!vm) { + return; + } + const [pureArgs, callbacks] = normalizeArgs(args, extras); + if (!Object.keys(callbacks).length) { + return vm[method](pureArgs); + } + return vm[method](pureArgs, normalizeCallback(method, callbacks)); +} +function findElmById(id, vm) { + const elm = findRefByElm(id, vm.$el); + if (!elm) { + return console.error('Can not find `' + id + '`'); + } + return elm; +} +function findRefByElm(id, elm) { + if (!id || !elm) { + return; + } + if (elm.attr && elm.attr.id === id) { + return elm; + } + const children = elm.children; + if (!children) { + return; + } + for (let i = 0, len = children.length; i < len; i++) { + const elm = findRefByElm(id, children[i]); + if (elm) { + return elm; + } + } +} +function normalizeArgs(args = {}, extras) { + const callbacks = Object.create(null); + const iterator = function iterator(name) { + const callback = args[name]; + if (isFunction(callback)) { + callbacks[name] = callback; + delete args[name]; + } + }; + CALLBACKS.forEach(iterator); + extras && extras.forEach(iterator); + return [args, callbacks]; +} +function normalizeCallback(method, callbacks) { + return function weexCallback(ret) { + const type = ret.type; + delete ret.type; + const callback = callbacks[type]; + if (type === SUCCESS) { + ret.errMsg = `${method}:ok`; + } + else if (type === FAIL) { + ret.errMsg = method + ':fail ' + (ret.msg ? ' ' + ret.msg : ''); + } + delete ret.code; + delete ret.msg; + isFunction(callback) && callback(ret); + if (type === SUCCESS || type === FAIL) { + const complete = callbacks.complete; + isFunction(complete) && complete(ret); + } + }; +} - const ServiceJSBridge = /*#__PURE__*/ shared.extend(initBridge('view' /* view 指的是 service 层订阅的是 view 层事件 */), { - invokeOnCallback, - invokeViewMethod, - invokeViewMethodKeepAlive, - }); - - function initOn() { - const { on } = UniServiceJSBridge; - on(ON_RESIZE, onResize); - on(ON_APP_ENTER_FOREGROUND, onAppEnterForeground); - on(ON_APP_ENTER_BACKGROUND, onAppEnterBackground); - } - function onResize(res) { - invokeHook(getCurrentPage(), ON_RESIZE, res); - UniServiceJSBridge.invokeOnCallback('onWindowResize', res); // API - } - function onAppEnterForeground(enterOptions) { - const page = getCurrentPage(); - invokeHook(getApp(), ON_SHOW, enterOptions); - invokeHook(page, ON_SHOW); - } - function onAppEnterBackground() { - invokeHook(getApp(), ON_HIDE); - invokeHook(getCurrentPage(), ON_HIDE); - } +const METHODS$1 = { + play(ctx) { + return invokeVmMethodWithoutArgs(ctx, 'play'); + }, + pause(ctx) { + return invokeVmMethodWithoutArgs(ctx, 'pause'); + }, + seek(ctx, args) { + return invokeVmMethod(ctx, 'seek', args.position); + }, + stop(ctx) { + return invokeVmMethodWithoutArgs(ctx, 'stop'); + }, + sendDanmu(ctx, args) { + return invokeVmMethod(ctx, 'sendDanmu', args); + }, + playbackRate(ctx, args) { + return invokeVmMethod(ctx, 'playbackRate', args.rate); + }, + requestFullScreen(ctx, args = {}) { + return invokeVmMethod(ctx, 'requestFullScreen', args); + }, + exitFullScreen(ctx) { + return invokeVmMethodWithoutArgs(ctx, 'exitFullScreen'); + }, + showStatusBar(ctx) { + return invokeVmMethodWithoutArgs(ctx, 'showStatusBar'); + }, + hideStatusBar(ctx) { + return invokeVmMethodWithoutArgs(ctx, 'hideStatusBar'); + }, +}; +function operateVideoPlayer(videoId, pageId, type, data) { + const page = getCurrentPages().find((page) => page.$page.id === pageId); + if (page === null || page === void 0 ? void 0 : page.$page.meta.isNVue) { + const pageVm = page.$vm; + return METHODS$1[type](findElmById(videoId, pageVm), data); + } + UniServiceJSBridge.invokeViewMethod('video.' + videoId, { + videoId, + type, + data, + }, pageId); +} - const SUBSCRIBE_LIFECYCLE_HOOKS = [ON_PAGE_SCROLL, ON_REACH_BOTTOM]; - function initSubscribe() { - SUBSCRIBE_LIFECYCLE_HOOKS.forEach((name) => UniServiceJSBridge.subscribe(name, createPageEvent(name))); - } - function createPageEvent(name) { - return (args, pageId) => { - invokeHook(parseInt(pageId), name, args); - }; - } +const METHODS = { + getCenterLocation(ctx, cbs) { + return invokeVmMethodWithoutArgs(ctx, 'getCenterLocation', cbs); + }, + moveToLocation(ctx, args) { + return invokeVmMethod(ctx, 'moveToLocation', args); + }, + translateMarker(ctx, args) { + return invokeVmMethod(ctx, 'translateMarker', args, ['animationEnd']); + }, + includePoints(ctx, args) { + return invokeVmMethod(ctx, 'includePoints', args); + }, + getRegion(ctx, cbs) { + return invokeVmMethodWithoutArgs(ctx, 'getRegion', cbs); + }, + getScale(ctx, cbs) { + return invokeVmMethodWithoutArgs(ctx, 'getScale', cbs); + }, + addCustomLayer(ctx, args) { + return invokeVmMethod(ctx, 'addCustomLayer', args); + }, + removeCustomLayer(ctx, args) { + return invokeVmMethod(ctx, 'removeCustomLayer', args); + }, + addGroundOverlay(ctx, args) { + return invokeVmMethod(ctx, 'addGroundOverlay', args); + }, + removeGroundOverlay(ctx, args) { + return invokeVmMethod(ctx, 'removeGroundOverlay', args); + }, + updateGroundOverlay(ctx, args) { + return invokeVmMethod(ctx, 'updateGroundOverlay', args); + }, + initMarkerCluster(ctx, args) { + return invokeVmMethod(ctx, 'initMarkerCluster', args); + }, + addMarkers(ctx, args) { + return invokeVmMethod(ctx, 'addMarkers', args); + }, + removeMarkers(ctx, args) { + return invokeVmMethod(ctx, 'removeMarkers', args); + }, + moveAlong(ctx, args) { + return invokeVmMethod(ctx, 'moveAlong', args); + }, + openMapApp(ctx, args) { + return invokeVmMethod(ctx, 'openMapApp', args); + }, + on(ctx, args) { + return ctx.on(args.name, args.callback); + }, +}; +function operateMap(id, pageId, type, data, operateMapCallback) { + const page = getCurrentPages().find((page) => page.$page.id === pageId); + if (page === null || page === void 0 ? void 0 : page.$page.meta.isNVue) { + const pageVm = page.$vm; + return METHODS[type](findElmById(id, pageVm), data); + } + UniServiceJSBridge.invokeViewMethod('map.' + id, { + type, + data, + }, pageId, operateMapCallback); +} - function initService() { - { - initOn(); - initSubscribe(); - } - } - function initAppVm(appVm) { - appVm.$vm = appVm; - appVm.$mpType = 'app'; - const locale = vue.ref(useI18n().getLocale()); - Object.defineProperty(appVm, '$locale', { - get() { - { - uni.$nvueState && uni.$nvueState.locale; - } - return locale.value; - }, - set(v) { - { - uni.$nvueState && (uni.$nvueState.locale = v); - } - locale.value = v; - }, - }); - } - function initPageVm(pageVm, page) { - pageVm.route = page.route; - pageVm.$vm = pageVm; - pageVm.$page = page; - pageVm.$mpType = 'page'; - if (page.meta.isTabBar) { - pageVm.$.__isTabBar = true; - // TODO preload? 初始化时,状态肯定是激活 - pageVm.$.__isActive = true; - } - } +function getEventName$1(reqId) { + const EVENT_NAME = 'IntersectionObserver'; + return `${EVENT_NAME}.${reqId}`; +} +function addIntersectionObserver({ reqId, component, options, callback }, _pageId) { + const eventName = getEventName$1(reqId); + UniServiceJSBridge.invokeViewMethod('addIntersectionObserver', { + reqId, + component: component.$el.nodeId, + options, + eventName, + }, _pageId); + UniServiceJSBridge.subscribe(eventName, callback); +} +function removeIntersectionObserver({ reqId, component }, _pageId) { + UniServiceJSBridge.invokeViewMethod('removeIntersectionObserver', { + reqId, + component: component.$el.nodeId, + }, _pageId); + UniServiceJSBridge.unsubscribe(getEventName$1(reqId)); +} - function querySelector(vm, selector) { - const el = vm.$el.querySelector(selector); - return el && el.__vue__; - } - function querySelectorAll(vm, selector) { - const nodeList = vm.$el.querySelectorAll(selector); - if (nodeList) { - return [...nodeList].map((node) => node.__vue__).filter(Boolean); - } - return []; - } - function createSelectorQuery$1() { - return uni.createSelectorQuery().in(this); - } - function createMediaQueryObserver$1() { - return uni.createMediaQueryObserver(this); - } - function createIntersectionObserver$1(options) { - return uni.createIntersectionObserver(this, options); - } - function selectComponent(selector) { - return querySelector(this, selector); - } - function selectAllComponents(selector) { - return querySelectorAll(this, selector); - } +function getEventName(reqId) { + const EVENT_NAME = 'MediaQueryObserver'; + return `${EVENT_NAME}.${reqId}`; +} +function addMediaQueryObserver({ reqId, component, options, callback }, _pageId) { + const eventName = getEventName(reqId); + UniServiceJSBridge.invokeViewMethod('addMediaQueryObserver', { + reqId, + component: component.$el.nodeId, + options, + eventName, + }, _pageId); + UniServiceJSBridge.subscribe(eventName, callback); +} +function removeMediaQueryObserver({ reqId, component }, _pageId) { + UniServiceJSBridge.invokeViewMethod('removeMediaQueryObserver', { + reqId, + component: component.$el.nodeId, + }, _pageId); + UniServiceJSBridge.unsubscribe(getEventName(reqId)); +} - var wxInstance = { - __proto__: null, - createSelectorQuery: createSelectorQuery$1, - createMediaQueryObserver: createMediaQueryObserver$1, - createIntersectionObserver: createIntersectionObserver$1, - selectComponent: selectComponent, - selectAllComponents: selectAllComponents - }; - - function getOpenerEventChannel() { - // TODO App - } +const DEVICE_FREQUENCY = 200; +const NETWORK_TYPES = [ + 'unknown', + 'none', + 'ethernet', + 'wifi', + '2g', + '3g', + '4g', + '5g', +]; +const TEMP_PATH_BASE = '_doc/uniapp_temp'; +const TEMP_PATH = `${TEMP_PATH_BASE}_${Date.now()}`; + +const EVENT_BACKBUTTON = 'backbutton'; +function backbuttonListener() { + uni.navigateBack({ + from: 'backbutton', + success() { }, // 传入空方法,避免返回Promise,因为onBackPress可能导致fail + }); +} +const enterOptions = createLaunchOptions(); +const launchOptions = createLaunchOptions(); +function getLaunchOptions() { + return launchOptions; +} +function getEnterOptions() { + return enterOptions; +} +function initEnterOptions({ path, query, referrerInfo, }) { + extend(enterOptions, { + path, + query: query ? parseQuery(query) : {}, + referrerInfo: referrerInfo || {}, + }); +} +function initLaunchOptions({ path, query, referrerInfo, }) { + extend(launchOptions, { + path, + query: query ? parseQuery(query) : {}, + referrerInfo: referrerInfo || {}, + }); + extend(enterOptions, launchOptions); + return launchOptions; +} +function parseRedirectInfo() { + const weexPlus = weex.requireModule('plus'); + if (weexPlus.getRedirectInfo) { + const { path, query, extraData, userAction, fromAppid } = weexPlus.getRedirectInfo() || {}; + const referrerInfo = { + appId: fromAppid, + extraData: {}, + }; + if (extraData) { + referrerInfo.extraData = extraData; + } + return { + path: path || '', + query: query ? '?' + query : '', + referrerInfo, + userAction, + }; + } +} - function initAppConfig(appConfig) { - const globalProperties = appConfig.globalProperties; - globalProperties.getOpenerEventChannel = getOpenerEventChannel; - { - shared.extend(globalProperties, wxInstance); - } - } +function createCommonjsModule(fn) { + var module = { exports: {} }; + return fn(module, module.exports), module.exports; +} - function initServicePlugin(app) { - initAppConfig(app._context.config); - } +var common = createCommonjsModule(function (module, exports) { - function createLaunchOptions() { - return { - path: '', - query: {}, - scene: 1001, - referrerInfo: { - appId: '', - extraData: {}, - }, - }; - } - function defineGlobalData(app, defaultGlobalData) { - const options = app.$options || {}; - options.globalData = shared.extend(options.globalData || {}, defaultGlobalData); - Object.defineProperty(app, 'globalData', { - get() { - return options.globalData; - }, - set(newGlobalData) { - options.globalData = newGlobalData; - }, - }); - } - function getRealPath(filepath) { - // 无协议的情况补全 https - if (filepath.indexOf('//') === 0) { - return 'https:' + filepath; - } - // 网络资源或base64 - if (SCHEME_RE.test(filepath) || DATA_RE.test(filepath)) { - return filepath; - } - if (isSystemURL(filepath)) { - return 'file://' + normalizeLocalPath(filepath); - } - const wwwPath = 'file://' + normalizeLocalPath('_www'); - // 绝对路径转换为本地文件系统路径 - if (filepath.indexOf('/') === 0) { - // 平台绝对路径 安卓、iOS - if (filepath.startsWith('/storage/') || - filepath.startsWith('/sdcard/') || - filepath.includes('/Containers/Data/Application/')) { - return 'file://' + filepath; - } - return wwwPath + filepath; - } - // 相对资源 - if (filepath.indexOf('../') === 0 || filepath.indexOf('./') === 0) { - // @ts-expect-error app-view - if (typeof __id__ === 'string') { - // @ts-expect-error app-view - return wwwPath + getRealRoute(addLeadingSlash(__id__), filepath); - } - else { - const page = getCurrentPage(); - if (page) { - return wwwPath + getRealRoute(addLeadingSlash(page.route), filepath); - } - } - } - return filepath; - } - const normalizeLocalPath = cacheStringFunction((filepath) => { - return plus.io - .convertLocalFileSystemURL(filepath) - .replace(/^\/?apps\//, '/android_asset/apps/') - .replace(/\/$/, ''); - }); - function isSystemURL(filepath) { - if (filepath.indexOf('_www') === 0 || - filepath.indexOf('_doc') === 0 || - filepath.indexOf('_documents') === 0 || - filepath.indexOf('_downloads') === 0) { - return true; - } - return false; - } +var TYPED_OK = (typeof Uint8Array !== 'undefined') && + (typeof Uint16Array !== 'undefined') && + (typeof Int32Array !== 'undefined'); - const SUCCESS = 'success'; - const FAIL = 'fail'; - const COMPLETE = 'complete'; - const CALLBACKS = [SUCCESS, FAIL, COMPLETE]; - /** - * 调用无参数,或仅一个参数且为 callback 的 API - * @param {Object} vm - * @param {Object} method - * @param {Object} args - * @param {Object} extras - */ - function invokeVmMethodWithoutArgs(vm, method, args, extras) { - if (!vm) { - return; - } - if (typeof args === 'undefined') { - return vm[method](); - } - const [, callbacks] = normalizeArgs(args, extras); - if (!Object.keys(callbacks).length) { - return vm[method](); - } - return vm[method](normalizeCallback(method, callbacks)); - } - /** - * 调用两个参数(第一个入参为普通参数,第二个入参为 callback) API - * @param {Object} vm - * @param {Object} method - * @param {Object} args - * @param {Object} extras - */ - function invokeVmMethod(vm, method, args, extras) { - if (!vm) { - return; - } - const [pureArgs, callbacks] = normalizeArgs(args, extras); - if (!Object.keys(callbacks).length) { - return vm[method](pureArgs); - } - return vm[method](pureArgs, normalizeCallback(method, callbacks)); - } - function findElmById(id, vm) { - const elm = findRefByElm(id, vm.$el); - if (!elm) { - return console.error('Can not find `' + id + '`'); - } - return elm; - } - function findRefByElm(id, elm) { - if (!id || !elm) { - return; - } - if (elm.attr && elm.attr.id === id) { - return elm; - } - const children = elm.children; - if (!children) { - return; - } - for (let i = 0, len = children.length; i < len; i++) { - const elm = findRefByElm(id, children[i]); - if (elm) { - return elm; - } - } - } - function normalizeArgs(args = {}, extras) { - const callbacks = Object.create(null); - const iterator = function iterator(name) { - const callback = args[name]; - if (shared.isFunction(callback)) { - callbacks[name] = callback; - delete args[name]; - } - }; - CALLBACKS.forEach(iterator); - extras && extras.forEach(iterator); - return [args, callbacks]; - } - function normalizeCallback(method, callbacks) { - return function weexCallback(ret) { - const type = ret.type; - delete ret.type; - const callback = callbacks[type]; - if (type === SUCCESS) { - ret.errMsg = `${method}:ok`; - } - else if (type === FAIL) { - ret.errMsg = method + ':fail ' + (ret.msg ? ' ' + ret.msg : ''); - } - delete ret.code; - delete ret.msg; - shared.isFunction(callback) && callback(ret); - if (type === SUCCESS || type === FAIL) { - const complete = callbacks.complete; - shared.isFunction(complete) && complete(ret); - } - }; - } +function _has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} - const METHODS$1 = { - play(ctx) { - return invokeVmMethodWithoutArgs(ctx, 'play'); - }, - pause(ctx) { - return invokeVmMethodWithoutArgs(ctx, 'pause'); - }, - seek(ctx, args) { - return invokeVmMethod(ctx, 'seek', args.position); - }, - stop(ctx) { - return invokeVmMethodWithoutArgs(ctx, 'stop'); - }, - sendDanmu(ctx, args) { - return invokeVmMethod(ctx, 'sendDanmu', args); - }, - playbackRate(ctx, args) { - return invokeVmMethod(ctx, 'playbackRate', args.rate); - }, - requestFullScreen(ctx, args = {}) { - return invokeVmMethod(ctx, 'requestFullScreen', args); - }, - exitFullScreen(ctx) { - return invokeVmMethodWithoutArgs(ctx, 'exitFullScreen'); - }, - showStatusBar(ctx) { - return invokeVmMethodWithoutArgs(ctx, 'showStatusBar'); - }, - hideStatusBar(ctx) { - return invokeVmMethodWithoutArgs(ctx, 'hideStatusBar'); - }, - }; - function operateVideoPlayer(videoId, pageId, type, data) { - const page = getCurrentPages().find((page) => page.$page.id === pageId); - if (page === null || page === void 0 ? void 0 : page.$page.meta.isNVue) { - const pageVm = page.$vm; - return METHODS$1[type](findElmById(videoId, pageVm), data); - } - UniServiceJSBridge.invokeViewMethod('video.' + videoId, { - videoId, - type, - data, - }, pageId); - } +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } - const METHODS = { - getCenterLocation(ctx, cbs) { - return invokeVmMethodWithoutArgs(ctx, 'getCenterLocation', cbs); - }, - moveToLocation(ctx, args) { - return invokeVmMethod(ctx, 'moveToLocation', args); - }, - translateMarker(ctx, args) { - return invokeVmMethod(ctx, 'translateMarker', args, ['animationEnd']); - }, - includePoints(ctx, args) { - return invokeVmMethod(ctx, 'includePoints', args); - }, - getRegion(ctx, cbs) { - return invokeVmMethodWithoutArgs(ctx, 'getRegion', cbs); - }, - getScale(ctx, cbs) { - return invokeVmMethodWithoutArgs(ctx, 'getScale', cbs); - }, - addCustomLayer(ctx, args) { - return invokeVmMethod(ctx, 'addCustomLayer', args); - }, - removeCustomLayer(ctx, args) { - return invokeVmMethod(ctx, 'removeCustomLayer', args); - }, - addGroundOverlay(ctx, args) { - return invokeVmMethod(ctx, 'addGroundOverlay', args); - }, - removeGroundOverlay(ctx, args) { - return invokeVmMethod(ctx, 'removeGroundOverlay', args); - }, - updateGroundOverlay(ctx, args) { - return invokeVmMethod(ctx, 'updateGroundOverlay', args); - }, - initMarkerCluster(ctx, args) { - return invokeVmMethod(ctx, 'initMarkerCluster', args); - }, - addMarkers(ctx, args) { - return invokeVmMethod(ctx, 'addMarkers', args); - }, - removeMarkers(ctx, args) { - return invokeVmMethod(ctx, 'removeMarkers', args); - }, - moveAlong(ctx, args) { - return invokeVmMethod(ctx, 'moveAlong', args); - }, - openMapApp(ctx, args) { - return invokeVmMethod(ctx, 'openMapApp', args); - }, - on(ctx, args) { - return ctx.on(args.name, args.callback); - }, - }; - function operateMap(id, pageId, type, data, operateMapCallback) { - const page = getCurrentPages().find((page) => page.$page.id === pageId); - if (page === null || page === void 0 ? void 0 : page.$page.meta.isNVue) { - const pageVm = page.$vm; - return METHODS[type](findElmById(id, pageVm), data); - } - UniServiceJSBridge.invokeViewMethod('map.' + id, { - type, - data, - }, pageId, operateMapCallback); - } + if (typeof source !== 'object') { + throw new TypeError(source + 'must be non-object'); + } - function getEventName$1(reqId) { - const EVENT_NAME = 'IntersectionObserver'; - return `${EVENT_NAME}.${reqId}`; - } - function addIntersectionObserver({ reqId, component, options, callback }, _pageId) { - const eventName = getEventName$1(reqId); - UniServiceJSBridge.invokeViewMethod('addIntersectionObserver', { - reqId, - component: component.$el.nodeId, - options, - eventName, - }, _pageId); - UniServiceJSBridge.subscribe(eventName, callback); - } - function removeIntersectionObserver({ reqId, component }, _pageId) { - UniServiceJSBridge.invokeViewMethod('removeIntersectionObserver', { - reqId, - component: component.$el.nodeId, - }, _pageId); - UniServiceJSBridge.unsubscribe(getEventName$1(reqId)); + for (var p in source) { + if (_has(source, p)) { + obj[p] = source[p]; + } + } } - function getEventName(reqId) { - const EVENT_NAME = 'MediaQueryObserver'; - return `${EVENT_NAME}.${reqId}`; - } - function addMediaQueryObserver({ reqId, component, options, callback }, _pageId) { - const eventName = getEventName(reqId); - UniServiceJSBridge.invokeViewMethod('addMediaQueryObserver', { - reqId, - component: component.$el.nodeId, - options, - eventName, - }, _pageId); - UniServiceJSBridge.subscribe(eventName, callback); - } - function removeMediaQueryObserver({ reqId, component }, _pageId) { - UniServiceJSBridge.invokeViewMethod('removeMediaQueryObserver', { - reqId, - component: component.$el.nodeId, - }, _pageId); - UniServiceJSBridge.unsubscribe(getEventName(reqId)); - } + return obj; +}; - const DEVICE_FREQUENCY = 200; - const NETWORK_TYPES = [ - 'unknown', - 'none', - 'ethernet', - 'wifi', - '2g', - '3g', - '4g', - '5g', - ]; - const TEMP_PATH_BASE = '_doc/uniapp_temp'; - const TEMP_PATH = `${TEMP_PATH_BASE}_${Date.now()}`; - - const EVENT_BACKBUTTON = 'backbutton'; - function backbuttonListener() { - uni.navigateBack({ - from: 'backbutton', - success() { }, // 传入空方法,避免返回Promise,因为onBackPress可能导致fail - }); - } - const enterOptions = createLaunchOptions(); - const launchOptions = createLaunchOptions(); - function getLaunchOptions() { - return launchOptions; - } - function getEnterOptions() { - return enterOptions; - } - function initEnterOptions({ path, query, referrerInfo, }) { - shared.extend(enterOptions, { - path, - query: query ? parseQuery(query) : {}, - referrerInfo: referrerInfo || {}, - }); - } - function initLaunchOptions({ path, query, referrerInfo, }) { - shared.extend(launchOptions, { - path, - query: query ? parseQuery(query) : {}, - referrerInfo: referrerInfo || {}, - }); - shared.extend(enterOptions, launchOptions); - return launchOptions; - } - function parseRedirectInfo() { - const weexPlus = weex.requireModule('plus'); - if (weexPlus.getRedirectInfo) { - const { path, query, extraData, userAction, fromAppid } = weexPlus.getRedirectInfo() || {}; - const referrerInfo = { - appId: fromAppid, - extraData: {}, - }; - if (extraData) { - referrerInfo.extraData = extraData; - } - return { - path: path || '', - query: query ? '?' + query : '', - referrerInfo, - userAction, - }; - } - } - function createCommonjsModule(fn) { - var module = { exports: {} }; - return fn(module, module.exports), module.exports; - } +// reduce buffer size, avoiding mem copy +exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { return buf; } + if (buf.subarray) { return buf.subarray(0, size); } + buf.length = size; + return buf; +}; - var common = createCommonjsModule(function (module, exports) { +var fnTyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs + len), dest_offs); + return; + } + // Fallback to ordinary array + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; + } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + var i, l, len, pos, chunk, result; + + // calculate data length + len = 0; + for (i = 0, l = chunks.length; i < l; i++) { + len += chunks[i].length; + } - var TYPED_OK = (typeof Uint8Array !== 'undefined') && - (typeof Uint16Array !== 'undefined') && - (typeof Int32Array !== 'undefined'); + // join chunks + result = new Uint8Array(len); + pos = 0; + for (i = 0, l = chunks.length; i < l; i++) { + chunk = chunks[i]; + result.set(chunk, pos); + pos += chunk.length; + } - function _has(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); + return result; } +}; - exports.assign = function (obj /*from1, from2, from3, ...*/) { - var sources = Array.prototype.slice.call(arguments, 1); - while (sources.length) { - var source = sources.shift(); - if (!source) { continue; } - - if (typeof source !== 'object') { - throw new TypeError(source + 'must be non-object'); - } - - for (var p in source) { - if (_has(source, p)) { - obj[p] = source[p]; - } - } +var fnUntyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + for (var i = 0; i < len; i++) { + dest[dest_offs + i] = src[src_offs + i]; } + }, + // Join array of chunks to single array. + flattenChunks: function (chunks) { + return [].concat.apply([], chunks); + } +}; + + +// Enable/Disable typed arrays use, for testing +// +exports.setTyped = function (on) { + if (on) { + exports.Buf8 = Uint8Array; + exports.Buf16 = Uint16Array; + exports.Buf32 = Int32Array; + exports.assign(exports, fnTyped); + } else { + exports.Buf8 = Array; + exports.Buf16 = Array; + exports.Buf32 = Array; + exports.assign(exports, fnUntyped); + } +}; - return obj; - }; +exports.setTyped(TYPED_OK); +}); +var require$$0 = common; - // reduce buffer size, avoiding mem copy - exports.shrinkBuf = function (buf, size) { - if (buf.length === size) { return buf; } - if (buf.subarray) { return buf.subarray(0, size); } - buf.length = size; - return buf; - }; +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +/* eslint-disable space-unary-ops */ - var fnTyped = { - arraySet: function (dest, src, src_offs, len, dest_offs) { - if (src.subarray && dest.subarray) { - dest.set(src.subarray(src_offs, src_offs + len), dest_offs); - return; - } - // Fallback to ordinary array - for (var i = 0; i < len; i++) { - dest[dest_offs + i] = src[src_offs + i]; - } - }, - // Join array of chunks to single array. - flattenChunks: function (chunks) { - var i, l, len, pos, chunk, result; - - // calculate data length - len = 0; - for (i = 0, l = chunks.length; i < l; i++) { - len += chunks[i].length; - } - // join chunks - result = new Uint8Array(len); - pos = 0; - for (i = 0, l = chunks.length; i < l; i++) { - chunk = chunks[i]; - result.set(chunk, pos); - pos += chunk.length; - } - return result; - } - }; +/* Public constants ==========================================================*/ +/* ===========================================================================*/ - var fnUntyped = { - arraySet: function (dest, src, src_offs, len, dest_offs) { - for (var i = 0; i < len; i++) { - dest[dest_offs + i] = src[src_offs + i]; - } - }, - // Join array of chunks to single array. - flattenChunks: function (chunks) { - return [].concat.apply([], chunks); - } - }; +//var Z_FILTERED = 1; +//var Z_HUFFMAN_ONLY = 2; +//var Z_RLE = 3; +var Z_FIXED$1 = 4; +//var Z_DEFAULT_STRATEGY = 0; - // Enable/Disable typed arrays use, for testing - // - exports.setTyped = function (on) { - if (on) { - exports.Buf8 = Uint8Array; - exports.Buf16 = Uint16Array; - exports.Buf32 = Int32Array; - exports.assign(exports, fnTyped); - } else { - exports.Buf8 = Array; - exports.Buf16 = Array; - exports.Buf32 = Array; - exports.assign(exports, fnUntyped); - } - }; +/* Possible values of the data_type field (though see inflate()) */ +var Z_BINARY = 0; +var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN$1 = 2; - exports.setTyped(TYPED_OK); - }); +/*============================================================================*/ - var require$$0 = common; - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. +function zero$1(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } - /* eslint-disable space-unary-ops */ +// From zutil.h +var STORED_BLOCK = 0; +var STATIC_TREES = 1; +var DYN_TREES = 2; +/* The three kinds of block type */ +var MIN_MATCH$1 = 3; +var MAX_MATCH$1 = 258; +/* The minimum and maximum match lengths */ - /* Public constants ==========================================================*/ - /* ===========================================================================*/ +// From deflate.h +/* =========================================================================== + * Internal compression state. + */ +var LENGTH_CODES$1 = 29; +/* number of length codes, not counting the special END_BLOCK code */ - //var Z_FILTERED = 1; - //var Z_HUFFMAN_ONLY = 2; - //var Z_RLE = 3; - var Z_FIXED$1 = 4; - //var Z_DEFAULT_STRATEGY = 0; +var LITERALS$1 = 256; +/* number of literal bytes 0..255 */ - /* Possible values of the data_type field (though see inflate()) */ - var Z_BINARY = 0; - var Z_TEXT = 1; - //var Z_ASCII = 1; // = Z_TEXT - var Z_UNKNOWN$1 = 2; +var L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1; +/* number of Literal or Length codes, including the END_BLOCK code */ - /*============================================================================*/ +var D_CODES$1 = 30; +/* number of distance codes */ +var BL_CODES$1 = 19; +/* number of codes used to transfer the bit lengths */ - function zero$1(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } +var HEAP_SIZE$1 = 2 * L_CODES$1 + 1; +/* maximum heap size */ - // From zutil.h +var MAX_BITS$1 = 15; +/* All codes must not exceed MAX_BITS bits */ - var STORED_BLOCK = 0; - var STATIC_TREES = 1; - var DYN_TREES = 2; - /* The three kinds of block type */ +var Buf_size = 16; +/* size of bit buffer in bi_buf */ - var MIN_MATCH$1 = 3; - var MAX_MATCH$1 = 258; - /* The minimum and maximum match lengths */ - // From deflate.h - /* =========================================================================== - * Internal compression state. - */ +/* =========================================================================== + * Constants + */ - var LENGTH_CODES$1 = 29; - /* number of length codes, not counting the special END_BLOCK code */ +var MAX_BL_BITS = 7; +/* Bit length codes must not exceed MAX_BL_BITS bits */ - var LITERALS$1 = 256; - /* number of literal bytes 0..255 */ +var END_BLOCK = 256; +/* end of block literal code */ - var L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1; - /* number of Literal or Length codes, including the END_BLOCK code */ +var REP_3_6 = 16; +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - var D_CODES$1 = 30; - /* number of distance codes */ +var REPZ_3_10 = 17; +/* repeat a zero length 3-10 times (3 bits of repeat count) */ - var BL_CODES$1 = 19; - /* number of codes used to transfer the bit lengths */ +var REPZ_11_138 = 18; +/* repeat a zero length 11-138 times (7 bits of repeat count) */ - var HEAP_SIZE$1 = 2 * L_CODES$1 + 1; - /* maximum heap size */ +/* eslint-disable comma-spacing,array-bracket-spacing */ +var extra_lbits = /* extra bits for each length code */ + [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; - var MAX_BITS$1 = 15; - /* All codes must not exceed MAX_BITS bits */ +var extra_dbits = /* extra bits for each distance code */ + [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; - var Buf_size = 16; - /* size of bit buffer in bi_buf */ +var extra_blbits = /* extra bits for each bit length code */ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; +var bl_order = + [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; +/* eslint-enable comma-spacing,array-bracket-spacing */ - /* =========================================================================== - * Constants - */ +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ - var MAX_BL_BITS = 7; - /* Bit length codes must not exceed MAX_BL_BITS bits */ +/* =========================================================================== + * Local data. These are initialized only once. + */ - var END_BLOCK = 256; - /* end of block literal code */ +// We pre-fill arrays with 0 to avoid uninitialized gaps - var REP_3_6 = 16; - /* repeat previous bit length 3-6 times (2 bits of repeat count) */ +var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ - var REPZ_3_10 = 17; - /* repeat a zero length 3-10 times (3 bits of repeat count) */ +// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 +var static_ltree = new Array((L_CODES$1 + 2) * 2); +zero$1(static_ltree); +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ - var REPZ_11_138 = 18; - /* repeat a zero length 11-138 times (7 bits of repeat count) */ +var static_dtree = new Array(D_CODES$1 * 2); +zero$1(static_dtree); +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ - /* eslint-disable comma-spacing,array-bracket-spacing */ - var extra_lbits = /* extra bits for each length code */ - [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; +var _dist_code = new Array(DIST_CODE_LEN); +zero$1(_dist_code); +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ - var extra_dbits = /* extra bits for each distance code */ - [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; +var _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1); +zero$1(_length_code); +/* length code for each normalized match length (0 == MIN_MATCH) */ - var extra_blbits = /* extra bits for each bit length code */ - [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; +var base_length = new Array(LENGTH_CODES$1); +zero$1(base_length); +/* First normalized length for each code (0 = MIN_MATCH) */ - var bl_order = - [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; - /* eslint-enable comma-spacing,array-bracket-spacing */ +var base_dist = new Array(D_CODES$1); +zero$1(base_dist); +/* First normalized distance for each code (0 = distance of 1) */ - /* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - /* =========================================================================== - * Local data. These are initialized only once. - */ +function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { - // We pre-fill arrays with 0 to avoid uninitialized gaps + this.static_tree = static_tree; /* static tree or NULL */ + this.extra_bits = extra_bits; /* extra bits for each code or NULL */ + this.extra_base = extra_base; /* base index for extra_bits */ + this.elems = elems; /* max number of elements in the tree */ + this.max_length = max_length; /* max bit length for the codes */ - var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; +} - // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1 - var static_ltree = new Array((L_CODES$1 + 2) * 2); - zero$1(static_ltree); - /* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - var static_dtree = new Array(D_CODES$1 * 2); - zero$1(static_dtree); - /* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ +var static_l_desc; +var static_d_desc; +var static_bl_desc; - var _dist_code = new Array(DIST_CODE_LEN); - zero$1(_dist_code); - /* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - var _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1); - zero$1(_length_code); - /* length code for each normalized match length (0 == MIN_MATCH) */ +function TreeDesc(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = stat_desc; /* the corresponding static tree */ +} + - var base_length = new Array(LENGTH_CODES$1); - zero$1(base_length); - /* First normalized length for each code (0 = MIN_MATCH) */ - var base_dist = new Array(D_CODES$1); - zero$1(base_dist); - /* First normalized distance for each code (0 = distance of 1) */ +function d_code(dist) { + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; +} - function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) { +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +function put_short(s, w) { +// put_byte(s, (uch)((w) & 0xff)); +// put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = (w) & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +} - this.static_tree = static_tree; /* static tree or NULL */ - this.extra_bits = extra_bits; /* extra bits for each code or NULL */ - this.extra_base = extra_base; /* base index for extra_bits */ - this.elems = elems; /* max number of elements in the tree */ - this.max_length = max_length; /* max bit length for the codes */ - // show if `static_tree` has data or dummy - needed for monomorphic objects - this.has_stree = static_tree && static_tree.length; +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +function send_bits(s, value, length) { + if (s.bi_valid > (Buf_size - length)) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; } +} - var static_l_desc; - var static_d_desc; - var static_bl_desc; +function send_code(s, c, tree) { + send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); +} - function TreeDesc(dyn_tree, stat_desc) { - this.dyn_tree = dyn_tree; /* the dynamic tree */ - this.max_code = 0; /* largest code with non zero frequency */ - this.stat_desc = stat_desc; /* the corresponding static tree */ - } +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; +} +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; - function d_code(dist) { - return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; } +} - /* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ - function put_short(s, w) { - // put_byte(s, (uch)((w) & 0xff)); - // put_byte(s, (uch)((ush)(w) >> 8)); - s.pending_buf[s.pending++] = (w) & 0xff; - s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +function gen_bitlen(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; /* heap index */ + var n, m; /* iterate over the tree elements */ + var bits; /* bit length */ + var xbits; /* extra bits */ + var f; /* frequency */ + var overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS$1; bits++) { + s.bl_count[bits] = 0; } - - /* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). */ - function send_bits(s, value, length) { - if (s.bi_valid > (Buf_size - length)) { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - put_short(s, s.bi_buf); - s.bi_buf = value >> (Buf_size - s.bi_valid); - s.bi_valid += length - Buf_size; - } else { - s.bi_buf |= (value << s.bi_valid) & 0xffff; - s.bi_valid += length; + tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) { + n = s.heap[h]; + bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; } - } + tree[n * 2 + 1]/*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + if (n > max_code) { continue; } /* not a leaf node */ - function send_code(s, c, tree) { - send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/); + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n - base]; + } + f = tree[n * 2]/*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); + } } + if (overflow === 0) { return; } + + // Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s.bl_count[bits] === 0) { bits--; } + s.bl_count[bits]--; /* move one leaf down the tree */ + s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); - - /* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) */ - function bi_reverse(code, len) { - var res = 0; - do { - res |= code & 1; - code >>>= 1; - res <<= 1; - } while (--len > 0); - return res >>> 1; + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { continue; } + if (tree[m * 2 + 1]/*.Len*/ !== bits) { + // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; + tree[m * 2 + 1]/*.Len*/ = bits; + } + n--; + } } +} - /* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +function gen_codes(tree, max_code, bl_count) +// ct_data *tree; /* the tree to decorate */ +// int max_code; /* largest code with non zero frequency */ +// ushf *bl_count; /* number of codes at each bit length */ +{ + var next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */ + var code = 0; /* running code value */ + var bits; /* bit index */ + var n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. */ - function bi_flush(s) { - if (s.bi_valid === 16) { - put_short(s, s.bi_buf); - s.bi_buf = 0; - s.bi_valid = 0; - - } else if (s.bi_valid >= 8) { - s.pending_buf[s.pending++] = s.bi_buf & 0xff; - s.bi_buf >>= 8; - s.bi_valid -= 8; - } + for (bits = 1; bits <= MAX_BITS$1; bits++) { + next_code[bits] = code = (code + bl_count[bits - 1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES$1 - 1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + _length_code[length++] = code; + } + } + //Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: */ - function gen_bitlen(s, desc) - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - { - var tree = desc.dyn_tree; - var max_code = desc.max_code; - var stree = desc.stat_desc.static_tree; - var has_stree = desc.stat_desc.has_stree; - var extra = desc.stat_desc.extra_bits; - var base = desc.stat_desc.extra_base; - var max_length = desc.stat_desc.max_length; - var h; /* heap index */ - var n, m; /* iterate over the tree elements */ - var bits; /* bit length */ - var xbits; /* extra bits */ - var f; /* frequency */ - var overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS$1; bits++) { - s.bl_count[bits] = 0; + _length_code[length - 1] = code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + _dist_code[dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for (; code < D_CODES$1; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { + _dist_code[256 + dist++] = code; } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */ - - for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; - if (bits > max_length) { - bits = max_length; - overflow++; - } - tree[n * 2 + 1]/*.Len*/ = bits; - /* We overwrite tree[n].Dad which is no longer needed */ + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS$1; bits++) { + bl_count[bits] = 0; + } - if (n > max_code) { continue; } /* not a leaf node */ + n = 0; + while (n <= 143) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n * 2 + 1]/*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n * 2 + 1]/*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n * 2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES$1 + 1, bl_count); - s.bl_count[bits]++; - xbits = 0; - if (n >= base) { - xbits = extra[n - base]; - } - f = tree[n * 2]/*.Freq*/; - s.opt_len += f * (bits + xbits); - if (has_stree) { - s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits); - } - } - if (overflow === 0) { return; } + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES$1; n++) { + static_dtree[n * 2 + 1]/*.Len*/ = 5; + static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); + } - // Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS$1 + 1, L_CODES$1, MAX_BITS$1); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES$1, MAX_BITS$1); + static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS); - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s.bl_count[bits] === 0) { bits--; } - s.bl_count[bits]--; /* move one leaf down the tree */ - s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s.bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); + //static_init_done = true; +} - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits !== 0; bits--) { - n = s.bl_count[bits]; - while (n !== 0) { - m = s.heap[--h]; - if (m > max_code) { continue; } - if (tree[m * 2 + 1]/*.Len*/ !== bits) { - // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/; - tree[m * 2 + 1]/*.Len*/ = bits; - } - n--; - } - } - } +/* =========================================================================== + * Initialize a new block. + */ +function init_block(s) { + var n; /* iterates over tree elements */ - /* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ - function gen_codes(tree, max_code, bl_count) - // ct_data *tree; /* the tree to decorate */ - // int max_code; /* largest code with non zero frequency */ - // ushf *bl_count; /* number of codes at each bit length */ - { - var next_code = new Array(MAX_BITS$1 + 1); /* next code value for each bit length */ - var code = 0; /* running code value */ - var bits; /* bit index */ - var n; /* code index */ + /* Initialize the trees. */ + for (n = 0; n < L_CODES$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < D_CODES$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } + for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS$1; bits++) { - next_code[bits] = code = (code + bl_count[bits - 1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES$1 - 1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = code; - } - } - //Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for (; code < D_CODES$1; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = code; - } - } - //Assert (dist == 256, "tr_static_init: 256+dist != 512"); +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +function bi_windup(s) +{ + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; +} - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS$1; bits++) { - bl_count[bits] = 0; - } +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +function copy_block(s, buf, len, header) +//DeflateState *s; +//charf *buf; /* the input data */ +//unsigned len; /* its length */ +//int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, len); + put_short(s, ~len); + } +// while (len--) { +// put_byte(s, *buf++); +// } + require$$0.arraySet(s.pending_buf, s.window, buf, len, s.pending); + s.pending += len; +} - n = 0; - while (n <= 143) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - while (n <= 255) { - static_ltree[n * 2 + 1]/*.Len*/ = 9; - n++; - bl_count[9]++; - } - while (n <= 279) { - static_ltree[n * 2 + 1]/*.Len*/ = 7; - n++; - bl_count[7]++; - } - while (n <= 287) { - static_ltree[n * 2 + 1]/*.Len*/ = 8; - n++; - bl_count[8]++; - } - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes(static_ltree, L_CODES$1 + 1, bl_count); +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +function smaller(tree, n, m, depth) { + var _n2 = n * 2; + var _m2 = m * 2; + return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || + (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); +} - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES$1; n++) { - static_dtree[n * 2 + 1]/*.Len*/ = 5; - static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5); +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +function pqdownheap(s, tree, k) +// deflate_state *s; +// ct_data *tree; /* the tree to restore */ +// int k; /* node to move down */ +{ + var v = s.heap[k]; + var j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s.heap_len && + smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { + j++; } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { break; } - // Now data ready and we can init static trees - static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS$1 + 1, L_CODES$1, MAX_BITS$1); - static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES$1, MAX_BITS$1); - static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS); + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; - //static_init_done = true; + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; } + s.heap[k] = v; +} - /* =========================================================================== - * Initialize a new block. - */ - function init_block(s) { - var n; /* iterates over tree elements */ +// inlined manually +// var SMALLEST = 1; + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +function compress_block(s, ltree, dtree) +// deflate_state *s; +// const ct_data *ltree; /* literal tree */ +// const ct_data *dtree; /* distance tree */ +{ + var dist; /* distance of matched string */ + var lc; /* match length or unmatched char (if dist == 0) */ + var lx = 0; /* running index in l_buf */ + var code; /* the code to send */ + var extra; /* number of extra bits to send */ + + if (s.last_lit !== 0) { + do { + dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]); + lc = s.pending_buf[s.l_buf + lx]; + lx++; + + if (dist === 0) { + send_code(s, lc, ltree); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS$1 + 1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ - /* Initialize the trees. */ - for (n = 0; n < L_CODES$1; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < D_CODES$1; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; } - for (n = 0; n < BL_CODES$1; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; } + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + // "pendingBuf overflow"); - s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1; - s.opt_len = s.static_len = 0; - s.last_lit = s.matches = 0; + } while (lx < s.last_lit); } + send_code(s, END_BLOCK, ltree); +} + - /* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +function build_tree(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; /* iterate over heap elements */ + var max_code = -1; /* largest code with non zero frequency */ + var node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. */ - function bi_windup(s) - { - if (s.bi_valid > 8) { - put_short(s, s.bi_buf); - } else if (s.bi_valid > 0) { - //put_byte(s, (Byte)s->bi_buf); - s.pending_buf[s.pending++] = s.bi_buf; + s.heap_len = 0; + s.heap_max = HEAP_SIZE$1; + + for (n = 0; n < elems; n++) { + if (tree[n * 2]/*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + + } else { + tree[n * 2 + 1]/*.Len*/ = 0; } - s.bi_buf = 0; - s.bi_valid = 0; } - /* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. */ - function copy_block(s, buf, len, header) - //DeflateState *s; - //charf *buf; /* the input data */ - //unsigned len; /* its length */ - //int header; /* true if block header must be written */ - { - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, len); - put_short(s, ~len); + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[node * 2]/*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node * 2 + 1]/*.Len*/; } - // while (len--) { - // put_byte(s, *buf++); - // } - require$$0.arraySet(s.pending_buf, s.window, buf, len, s.pending); - s.pending += len; + /* node is 0 or 1 so it does not have extra bits */ } + desc.max_code = max_code; - /* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: */ - function smaller(tree, n, m, depth) { - var _n2 = n * 2; - var _m2 = m * 2; - return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || - (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); - } + for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } - /* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. */ - function pqdownheap(s, tree, k) - // deflate_state *s; - // ct_data *tree; /* the tree to restore */ - // int k; /* node to move down */ - { - var v = s.heap[k]; - var j = k << 1; /* left son of k */ - while (j <= s.heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s.heap_len && - smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s.heap[j], s.depth)) { break; } + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1/*SMALLEST*/]; + s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1/*SMALLEST*/); + /***/ - /* Exchange v with the smallest son */ - s.heap[k] = s.heap[j]; - k = j; + m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s.heap[k] = v; - } + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + /* Create a new node father of n and m */ + tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - // inlined manually - // var SMALLEST = 1; + /* and insert the new node in the heap */ + s.heap[1/*SMALLEST*/] = node++; + pqdownheap(s, tree, 1/*SMALLEST*/); - /* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ - function compress_block(s, ltree, dtree) - // deflate_state *s; - // const ct_data *ltree; /* literal tree */ - // const ct_data *dtree; /* distance tree */ - { - var dist; /* distance of matched string */ - var lc; /* match length or unmatched char (if dist == 0) */ - var lx = 0; /* running index in l_buf */ - var code; /* the code to send */ - var extra; /* number of extra bits to send */ + } while (s.heap_len >= 2); - if (s.last_lit !== 0) { - do { - dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]); - lc = s.pending_buf[s.l_buf + lx]; - lx++; + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - if (dist === 0) { - send_code(s, lc, ltree); /* send a literal byte */ - //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS$1 + 1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra !== 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - //Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra !== 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - // "pendingBuf overflow"); + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); +} - } while (lx < s.last_lit); - } - send_code(s, END_BLOCK, ltree); +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +function scan_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; } + tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - /* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ - function build_tree(s, desc) - // deflate_state *s; - // tree_desc *desc; /* the tree descriptor */ - { - var tree = desc.dyn_tree; - var stree = desc.stat_desc.static_tree; - var has_stree = desc.stat_desc.has_stree; - var elems = desc.stat_desc.elems; - var n, m; /* iterate over heap elements */ - var max_code = -1; /* largest code with non zero frequency */ - var node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s.heap_len = 0; - s.heap_max = HEAP_SIZE$1; + if (++count < max_count && curlen === nextlen) { + continue; - for (n = 0; n < elems; n++) { - if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; + } else if (count < min_count) { + s.bl_tree[curlen * 2]/*.Freq*/ += count; - } else { - tree[n * 2 + 1]/*.Len*/ = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s.heap_len < 2) { - node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); - tree[node * 2]/*.Freq*/ = 1; - s.depth[node] = 0; - s.opt_len--; - - if (has_stree) { - s.static_len -= stree[node * 2 + 1]/*.Len*/; - } - /* node is 0 or 1 so it does not have extra bits */ - } - desc.max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - //pqremove(s, tree, n); /* n = node of least frequency */ - /*** pqremove ***/ - n = s.heap[1/*SMALLEST*/]; - s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; - pqdownheap(s, tree, 1/*SMALLEST*/); - /***/ - - m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - - s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ - s.heap[--s.heap_max] = m; - - /* Create a new node father of n and m */ - tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; - s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; - tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node; - - /* and insert the new node in the heap */ - s.heap[1/*SMALLEST*/] = node++; - pqdownheap(s, tree, 1/*SMALLEST*/); - - } while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes(tree, max_code, s.bl_count); - } + } else if (curlen !== 0) { + if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } + s.bl_tree[REP_3_6 * 2]/*.Freq*/++; - /* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ - function scan_tree(s, tree, max_code) - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - { - var n; /* iterates over all tree elements */ - var prevlen = -1; /* last emitted length */ - var curlen; /* length of current code */ + } else if (count <= 10) { + s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; - var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + } else { + s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; + } - var count = 0; /* repeat count of the current code */ - var max_count = 7; /* max repeat count */ - var min_count = 4; /* min repeat count */ + count = 0; + prevlen = curlen; if (nextlen === 0) { max_count = 138; min_count = 3; - } - tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - s.bl_tree[curlen * 2]/*.Freq*/ += count; - - } else if (curlen !== 0) { + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; - if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } - s.bl_tree[REP_3_6 * 2]/*.Freq*/++; + } else { + max_count = 7; + min_count = 4; + } + } +} - } else if (count <= 10) { - s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++; - } else { - s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++; - } +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +function send_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } - count = 0; - prevlen = curlen; + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - if (nextlen === 0) { - max_count = 138; - min_count = 3; + if (++count < max_count && curlen === nextlen) { + continue; - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; + } else if (count < min_count) { + do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); - } else { - max_count = 7; - min_count = 4; + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; } - } - } - - - /* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ - function send_tree(s, tree, max_code) - // deflate_state *s; - // ct_data *tree; /* the tree to be scanned */ - // int max_code; /* and its largest code of non zero frequency */ - { - var n; /* iterates over all tree elements */ - var prevlen = -1; /* last emitted length */ - var curlen; /* length of current code */ + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count - 3, 2); - var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */ + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count - 3, 3); - var count = 0; /* repeat count of the current code */ - var max_count = 7; /* max repeat count */ - var min_count = 4; /* min repeat count */ + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count - 11, 7); + } - /* tree[max_code+1].Len = -1; */ /* guard already set */ + count = 0; + prevlen = curlen; if (nextlen === 0) { max_count = 138; min_count = 3; - } - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[(n + 1) * 2 + 1]/*.Len*/; - - if (++count < max_count && curlen === nextlen) { - continue; - - } else if (count < min_count) { - do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); - - } else if (curlen !== 0) { - if (curlen !== prevlen) { - send_code(s, curlen, s.bl_tree); - count--; - } - //Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s.bl_tree); - send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s.bl_tree); - send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s.bl_tree); - send_bits(s, count - 11, 7); - } - - count = 0; - prevlen = curlen; - if (nextlen === 0) { - max_count = 138; - min_count = 3; - } else if (curlen === nextlen) { - max_count = 6; - min_count = 3; + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; - } else { - max_count = 7; - min_count = 4; - } + } else { + max_count = 7; + min_count = 4; } } +} - /* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ - function build_bl_tree(s) { - var max_blindex; /* index of last bit length code of non zero freq */ +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +function build_bl_tree(s) { + var max_blindex; /* index of last bit length code of non zero freq */ - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, s.dyn_ltree, s.l_desc.max_code); - scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); - /* Build the bit length tree: */ - build_tree(s, s.bl_desc); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) { - if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { - break; - } + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) { + break; } - /* Update opt_len to include the bit length tree and counts */ - s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - // s->opt_len, s->static_len)); - - return max_blindex; } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + return max_blindex; +} - /* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ - function send_all_trees(s, lcodes, dcodes, blcodes) - // deflate_state *s; - // int lcodes, dcodes, blcodes; /* number of codes for each tree */ - { - var rank; /* index in bl_order */ - - //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - // "too many codes"); - //Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); - } - //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ - //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ - //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +function send_all_trees(s, lcodes, dcodes, blcodes) +// deflate_state *s; +// int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + var rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3); } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - /* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. + send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +function detect_data_type(s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 */ - function detect_data_type(s) { - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - var black_mask = 0xf3ffc07f; - var n; + var black_mask = 0xf3ffc07f; + var n; - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>>= 1) { - if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { - return Z_BINARY; - } + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) { + return Z_BINARY; } + } - /* Check for textual ("white-listed") bytes. */ - if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || - s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + /* Check for textual ("white-listed") bytes. */ + if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS$1; n++) { + if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { return Z_TEXT; } - for (n = 32; n < LITERALS$1; n++) { - if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { - return Z_TEXT; - } - } - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; } - - var static_init_done = false; - - /* =========================================================================== - * Initialize the tree data structures for a new zlib stream. + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. */ - function _tr_init(s) - { + return Z_BINARY; +} - if (!static_init_done) { - tr_static_init(); - static_init_done = true; - } - s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); - s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); - s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); +var static_init_done = false; - s.bi_buf = 0; - s.bi_valid = 0; +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +function _tr_init(s) +{ - /* Initialize the first block of the first file: */ - init_block(s); + if (!static_init_done) { + tr_static_init(); + static_init_done = true; } + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); - /* =========================================================================== - * Send a stored block - */ - function _tr_stored_block(s, buf, stored_len, last) - //DeflateState *s; - //charf *buf; /* input block */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - { - send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ - copy_block(s, buf, stored_len, true); /* with header */ - } + s.bi_buf = 0; + s.bi_valid = 0; + /* Initialize the first block of the first file: */ + init_block(s); +} - /* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ - function _tr_align(s) { - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree); - bi_flush(s); - } +/* =========================================================================== + * Send a stored block + */ +function _tr_stored_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */ + copy_block(s, buf, stored_len, true); /* with header */ +} - /* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ - function _tr_flush_block(s, buf, stored_len, last) - //DeflateState *s; - //charf *buf; /* input block, or NULL if too old */ - //ulg stored_len; /* length of input block */ - //int last; /* one if this is the last block for a file */ - { - var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - var max_blindex = 0; /* index of last bit length code of non zero freq */ - /* Build the Huffman trees unless a stored block is forced */ - if (s.level > 0) { +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +function _tr_align(s) { + send_bits(s, STATIC_TREES << 1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); +} - /* Check if the file is binary or text */ - if (s.strm.data_type === Z_UNKNOWN$1) { - s.strm.data_type = detect_data_type(s); - } - /* Construct the literal and distance trees */ - build_tree(s, s.l_desc); - // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +function _tr_flush_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block, or NULL if too old */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + var max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN$1) { + s.strm.data_type = detect_data_type(s); + } - build_tree(s, s.d_desc); - // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - // s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s.opt_len + 3 + 7) >>> 3; - static_lenb = (s.static_len + 3 + 7) >>> 3; + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); - // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - // s->last_lit)); + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len + 3 + 7) >>> 3; + static_lenb = (s.static_len + 3 + 7) >>> 3; - if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->last_lit)); - } else { - // Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } + if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } - if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { - /* 4: two words for the lengths */ + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); + if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) { + /* 4: two words for the lengths */ - } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) { + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); - send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); - compress_block(s, static_ltree, static_dtree); + } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) { - } else { - send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); - send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); - compress_block(s, s.dyn_ltree, s.dyn_dtree); - } - // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); + send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); - if (last) { - bi_windup(s); - } - // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - // s->compressed_len-7*last)); + } else { + send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); } - - /* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. */ - function _tr_tally(s, dist, lc) - // deflate_state *s; - // unsigned dist; /* distance of matched string */ - // unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ - { - //var out_length, in_length, dcode; - - s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; - s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; - - s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; - s.last_lit++; - - if (dist === 0) { - /* lc is the unmatched char */ - s.dyn_ltree[lc * 2]/*.Freq*/++; - } else { - s.matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - //Assert((ush)dist < (ush)MAX_DIST(s) && - // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s.dyn_ltree[(_length_code[lc] + LITERALS$1 + 1) * 2]/*.Freq*/++; - s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; - } + init_block(s); - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); +} - //#ifdef TRUNCATE_BLOCK - // /* Try to guess if it is profitable to stop the current block here */ - // if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { - // /* Compute an upper bound for the compressed length */ - // out_length = s.last_lit*8; - // in_length = s.strstart - s.block_start; - // - // for (dcode = 0; dcode < D_CODES; dcode++) { - // out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); - // } - // out_length >>>= 3; - // //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - // // s->last_lit, in_length, out_length, - // // 100L - out_length*100L/in_length)); - // if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { - // return true; - // } - // } - //#endif - - return (s.last_lit === s.lit_bufsize - 1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +function _tr_tally(s, dist, lc) +// deflate_state *s; +// unsigned dist; /* distance of matched string */ +// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + //var out_length, in_length, dcode; + + s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; + + s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; + s.last_lit++; + + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc * 2]/*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[(_length_code[lc] + LITERALS$1 + 1) * 2]/*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; } - var _tr_init_1 = _tr_init; - var _tr_stored_block_1 = _tr_stored_block; - var _tr_flush_block_1 = _tr_flush_block; - var _tr_tally_1 = _tr_tally; - var _tr_align_1 = _tr_align; - - var trees$1 = { - _tr_init: _tr_init_1, - _tr_stored_block: _tr_stored_block_1, - _tr_flush_block: _tr_flush_block_1, - _tr_tally: _tr_tally_1, - _tr_align: _tr_align_1 - }; - - // Note: adler32 takes 12% for level 0 and 2% for level 6. - // It isn't worth it to make additional optimizations as in original. - // Small size is preferable. - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function adler32$1(adler, buf, len, pos) { - var s1 = (adler & 0xffff) |0, - s2 = ((adler >>> 16) & 0xffff) |0, - n = 0; - - while (len !== 0) { - // Set limit ~ twice less than 5552, to keep - // s2 in 31-bits, because we force signed ints. - // in other case %= will fail. - n = len > 2000 ? 2000 : len; - len -= n; +// (!) This block is disabled in zlib defaults, +// don't enable it for binary compatibility + +//#ifdef TRUNCATE_BLOCK +// /* Try to guess if it is profitable to stop the current block here */ +// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { +// /* Compute an upper bound for the compressed length */ +// out_length = s.last_lit*8; +// in_length = s.strstart - s.block_start; +// +// for (dcode = 0; dcode < D_CODES; dcode++) { +// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); +// } +// out_length >>>= 3; +// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", +// // s->last_lit, in_length, out_length, +// // 100L - out_length*100L/in_length)); +// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { +// return true; +// } +// } +//#endif + + return (s.last_lit === s.lit_bufsize - 1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} - do { - s1 = (s1 + buf[pos++]) |0; - s2 = (s2 + s1) |0; - } while (--n); +var _tr_init_1 = _tr_init; +var _tr_stored_block_1 = _tr_stored_block; +var _tr_flush_block_1 = _tr_flush_block; +var _tr_tally_1 = _tr_tally; +var _tr_align_1 = _tr_align; + +var trees$1 = { + _tr_init: _tr_init_1, + _tr_stored_block: _tr_stored_block_1, + _tr_flush_block: _tr_flush_block_1, + _tr_tally: _tr_tally_1, + _tr_align: _tr_align_1 +}; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It isn't worth it to make additional optimizations as in original. +// Small size is preferable. + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +function adler32$1(adler, buf, len, pos) { + var s1 = (adler & 0xffff) |0, + s2 = ((adler >>> 16) & 0xffff) |0, + n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; - s1 %= 65521; - s2 %= 65521; - } + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); - return (s1 | (s2 << 16)) |0; + s1 %= 65521; + s2 %= 65521; } + return (s1 | (s2 << 16)) |0; +} - var adler32_1 = adler32$1; - - // Note: we can't get significant speed boost here. - // So write code to minimize size - no pregenerated tables - // and array tools dependencies. - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // Use ordinary array, since untyped makes no boost here - function makeTable() { - var c, table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); - } - table[n] = c; +var adler32_1 = adler32$1; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for (var n = 0; n < 256; n++) { + c = n; + for (var k = 0; k < 8; k++) { + c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); } - - return table; + table[n] = c; } - // Create table on load. Just 255 signed longs. Not a problem. - var crcTable = makeTable(); + return table; +} +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); - function crc32$1(crc, buf, len, pos) { - var t = crcTable, - end = pos + len; - crc ^= -1; +function crc32$1(crc, buf, len, pos) { + var t = crcTable, + end = pos + len; - for (var i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; - } + crc ^= -1; - return (crc ^ (-1)); // >>> 0; + for (var i = pos; i < end; i++) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; } - - var crc32_1 = crc32$1; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var messages = { - 2: 'need dictionary', /* Z_NEED_DICT 2 */ - 1: 'stream end', /* Z_STREAM_END 1 */ - 0: '', /* Z_OK 0 */ - '-1': 'file error', /* Z_ERRNO (-1) */ - '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ - '-3': 'data error', /* Z_DATA_ERROR (-3) */ - '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ - '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ - '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ - }; - - var trees = trees$1; - - var adler32 = adler32_1; - - var crc32 = crc32_1; - - var msg = messages; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. + return (crc ^ (-1)); // >>> 0; +} +var crc32_1 = crc32$1; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +var messages = { + 2: 'need dictionary', /* Z_NEED_DICT 2 */ + 1: 'stream end', /* Z_STREAM_END 1 */ + 0: '', /* Z_OK 0 */ + '-1': 'file error', /* Z_ERRNO (-1) */ + '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ + '-3': 'data error', /* Z_DATA_ERROR (-3) */ + '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ + '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ + '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ +}; + +var trees = trees$1; + +var adler32 = adler32_1; + +var crc32 = crc32_1; + +var msg = messages; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + + + + + + + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +var Z_NO_FLUSH$1 = 0; +var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +var Z_FULL_FLUSH = 3; +var Z_FINISH$2 = 4; +var Z_BLOCK$1 = 5; +//var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK$2 = 0; +var Z_STREAM_END$2 = 1; +//var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR$1 = -2; +var Z_DATA_ERROR$1 = -3; +//var Z_MEM_ERROR = -4; +var Z_BUF_ERROR$1 = -5; +//var Z_VERSION_ERROR = -6; + + +/* compression levels */ +//var Z_NO_COMPRESSION = 0; +//var Z_BEST_SPEED = 1; +//var Z_BEST_COMPRESSION = 9; +var Z_DEFAULT_COMPRESSION$1 = -1; + + +var Z_FILTERED = 1; +var Z_HUFFMAN_ONLY = 2; +var Z_RLE = 3; +var Z_FIXED = 4; +var Z_DEFAULT_STRATEGY$1 = 0; + +/* Possible values of the data_type field (though see inflate()) */ +//var Z_BINARY = 0; +//var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + + +/* The deflate compression method */ +var Z_DEFLATED$2 = 8; + +/*============================================================================*/ + + +var MAX_MEM_LEVEL = 9; +/* Maximum value for memLevel in deflateInit2 */ +var MAX_WBITS$1 = 15; +/* 32K LZ77 window */ +var DEF_MEM_LEVEL = 8; + + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ +var LITERALS = 256; +/* number of literal bytes 0..255 */ +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +var D_CODES = 30; +/* number of distance codes */ +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ +var HEAP_SIZE = 2 * L_CODES + 1; +/* maximum heap size */ +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + +var PRESET_DICT = 0x20; +var INIT_STATE = 42; +var EXTRA_STATE = 69; +var NAME_STATE = 73; +var COMMENT_STATE = 91; +var HCRC_STATE = 103; +var BUSY_STATE = 113; +var FINISH_STATE = 666; +var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ +var BS_BLOCK_DONE = 2; /* block flush performed */ +var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ +var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ +var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. - /* Public constants ==========================================================*/ - /* ===========================================================================*/ +function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; +} +function rank(f) { + return ((f) << 1) - ((f) > 4 ? 9 : 0); +} - /* Allowed flush values; see deflate() and inflate() below for details */ - var Z_NO_FLUSH$1 = 0; - var Z_PARTIAL_FLUSH = 1; - //var Z_SYNC_FLUSH = 2; - var Z_FULL_FLUSH = 3; - var Z_FINISH$2 = 4; - var Z_BLOCK$1 = 5; - //var Z_TREES = 6; +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - var Z_OK$2 = 0; - var Z_STREAM_END$2 = 1; - //var Z_NEED_DICT = 2; - //var Z_ERRNO = -1; - var Z_STREAM_ERROR$1 = -2; - var Z_DATA_ERROR$1 = -3; - //var Z_MEM_ERROR = -4; - var Z_BUF_ERROR$1 = -5; - //var Z_VERSION_ERROR = -6; +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->output buffer and copying into it. + * (See also read_buf()). + */ +function flush_pending(strm) { + var s = strm.state; + //_tr_flush_bits(s); + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { return; } + + require$$0.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } +} - /* compression levels */ - //var Z_NO_COMPRESSION = 0; - //var Z_BEST_SPEED = 1; - //var Z_BEST_COMPRESSION = 9; - var Z_DEFAULT_COMPRESSION$1 = -1; +function flush_block_only(s, last) { + trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); + s.block_start = s.strstart; + flush_pending(s.strm); +} - var Z_FILTERED = 1; - var Z_HUFFMAN_ONLY = 2; - var Z_RLE = 3; - var Z_FIXED = 4; - var Z_DEFAULT_STRATEGY$1 = 0; - /* Possible values of the data_type field (though see inflate()) */ - //var Z_BINARY = 0; - //var Z_TEXT = 1; - //var Z_ASCII = 1; // = Z_TEXT - var Z_UNKNOWN = 2; +function put_byte(s, b) { + s.pending_buf[s.pending++] = b; +} - /* The deflate compression method */ - var Z_DEFLATED$2 = 8; - - /*============================================================================*/ - - - var MAX_MEM_LEVEL = 9; - /* Maximum value for memLevel in deflateInit2 */ - var MAX_WBITS$1 = 15; - /* 32K LZ77 window */ - var DEF_MEM_LEVEL = 8; - - - var LENGTH_CODES = 29; - /* number of length codes, not counting the special END_BLOCK code */ - var LITERALS = 256; - /* number of literal bytes 0..255 */ - var L_CODES = LITERALS + 1 + LENGTH_CODES; - /* number of Literal or Length codes, including the END_BLOCK code */ - var D_CODES = 30; - /* number of distance codes */ - var BL_CODES = 19; - /* number of codes used to transfer the bit lengths */ - var HEAP_SIZE = 2 * L_CODES + 1; - /* maximum heap size */ - var MAX_BITS = 15; - /* All codes must not exceed MAX_BITS bits */ - - var MIN_MATCH = 3; - var MAX_MATCH = 258; - var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - - var PRESET_DICT = 0x20; - - var INIT_STATE = 42; - var EXTRA_STATE = 69; - var NAME_STATE = 73; - var COMMENT_STATE = 91; - var HCRC_STATE = 103; - var BUSY_STATE = 113; - var FINISH_STATE = 666; - - var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ - var BS_BLOCK_DONE = 2; /* block flush performed */ - var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ - var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ - - var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. - - function err(strm, errorCode) { - strm.msg = msg[errorCode]; - return errorCode; - } +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +function putShortMSB(s, b) { +// put_byte(s, (Byte)(b >> 8)); +// put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; +} - function rank(f) { - return ((f) << 1) - ((f) > 4 ? 9 : 0); - } - function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ +function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + if (len > size) { len = size; } + if (len === 0) { return 0; } - /* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->output buffer and copying into it. - * (See also read_buf()). - */ - function flush_pending(strm) { - var s = strm.state; + strm.avail_in -= len; - //_tr_flush_bits(s); - var len = s.pending; - if (len > strm.avail_out) { - len = strm.avail_out; - } - if (len === 0) { return; } - - require$$0.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); - strm.next_out += len; - s.pending_out += len; - strm.total_out += len; - strm.avail_out -= len; - s.pending -= len; - if (s.pending === 0) { - s.pending_out = 0; - } + // zmemcpy(buf, strm->next_in, len); + require$$0.arraySet(buf, strm.input, strm.next_in, len, start); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); } - - function flush_block_only(s, last) { - trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); - s.block_start = s.strstart; - flush_pending(s.strm); + else if (strm.state.wrap === 2) { + strm.adler = crc32(strm.adler, buf, len, start); } + strm.next_in += len; + strm.total_in += len; - function put_byte(s, b) { - s.pending_buf[s.pending++] = b; - } + return len; +} - /* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +function longest_match(s, cur_match) { + var chain_length = s.max_chain_length; /* max hash chain length */ + var scan = s.strstart; /* current string */ + var match; /* matched string */ + var len; /* length of current match */ + var best_len = s.prev_length; /* best match length so far */ + var nice_match = s.nice_match; /* stop if match long enough */ + var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; + + var _win = s.window; // shortcut + + var wmask = s.w_mask; + var prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. */ - function putShortMSB(s, b) { - // put_byte(s, (Byte)(b >> 8)); - // put_byte(s, (Byte)(b & 0xff)); - s.pending_buf[s.pending++] = (b >>> 8) & 0xff; - s.pending_buf[s.pending++] = b & 0xff; - } + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; - /* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->input buffer and copying from it. - * (See also flush_pending()). + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. */ - function read_buf(strm, buf, start, size) { - var len = strm.avail_in; + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - if (len > size) { len = size; } - if (len === 0) { return 0; } + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { nice_match = s.lookahead; } - strm.avail_in -= len; + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - // zmemcpy(buf, strm->next_in, len); - require$$0.arraySet(buf, strm.input, strm.next_in, len, start); - if (strm.state.wrap === 1) { - strm.adler = adler32(strm.adler, buf, len, start); - } + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; - else if (strm.state.wrap === 2) { - strm.adler = crc32(strm.adler, buf, len, start); + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if (_win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1]) { + continue; } - strm.next_in += len; - strm.total_in += len; + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); - return len; - } + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + scan < strend); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; +} - /* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ - function longest_match(s, cur_match) { - var chain_length = s.max_chain_length; /* max hash chain length */ - var scan = s.strstart; /* current string */ - var match; /* matched string */ - var len; /* length of current match */ - var best_len = s.prev_length; /* best match length so far */ - var nice_match = s.nice_match; /* stop if match long enough */ - var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; - - var _win = s.window; // shortcut - - var wmask = s.w_mask; - var prev = s.prev; - - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - var strend = s.strstart + MAX_MATCH; - var scan_end1 = _win[scan + best_len - 1]; - var scan_end = _win[scan + best_len]; +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - /* Do not waste too much time if we already have a good match: */ - if (s.prev_length >= s.good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. */ - if (nice_match > s.lookahead) { nice_match = s.lookahead; } + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + + require$$0.arraySet(s.window, s.window, _w_size, _w_size, 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ - // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = (m >= _w_size ? m - _w_size : 0); + } while (--n); - do { - // Assert(cur_match < s->strstart, "no future"); - match = cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = (m >= _w_size ? m - _w_size : 0); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); - if (_win[match + best_len] !== scan_end || - _win[match + best_len - 1] !== scan_end1 || - _win[match] !== _win[scan] || - _win[++match] !== _win[scan + 1]) { - continue; - } + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - // Assert(*scan == *match, "match[2]?"); + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; +//#if MIN_MATCH != 3 +// Call update_hash() MIN_MATCH-3 more times +//#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - /*jshint noempty:false*/ - } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && - scan < strend); - - // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s.match_start = cur_match; - best_len = len; - if (len >= nice_match) { + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { break; } - scan_end1 = _win[scan + best_len - 1]; - scan_end = _win[scan + best_len]; } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); - - if (best_len <= s.lookahead) { - return best_len; } - return s.lookahead; - } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); - /* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. */ - function fill_window(s) { - var _w_size = s.w_size; - var p, n, m, more, str; +// if (s.high_water < s.window_size) { +// var curr = s.strstart + s.lookahead; +// var init = 0; +// +// if (s.high_water < curr) { +// /* Previous high water mark below current data -- zero WIN_INIT +// * bytes or up to end of window, whichever is less. +// */ +// init = s.window_size - curr; +// if (init > WIN_INIT) +// init = WIN_INIT; +// zmemzero(s->window + curr, (unsigned)init); +// s->high_water = curr + init; +// } +// else if (s->high_water < (ulg)curr + WIN_INIT) { +// /* High water mark at or above current data, but below current data +// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up +// * to end of window, whichever is less. +// */ +// init = (ulg)curr + WIN_INIT - s->high_water; +// if (init > s->window_size - s->high_water) +// init = s->window_size - s->high_water; +// zmemzero(s->window + s->high_water, (unsigned)init); +// s->high_water += init; +// } +// } +// +// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, +// "not enough room for search"); +} - //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +function deflate_stored(s, flush) { + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + var max_block_size = 0xffff; - do { - more = s.window_size - s.lookahead - s.strstart; - - // JS ints have 32 bit, block below not needed - /* Deal with !@#$% 64K limit: */ - //if (sizeof(int) <= 2) { - // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - // more = wsize; - // - // } else if (more == (unsigned)(-1)) { - // /* Very unlikely, but possible on 16 bit machine if - // * strstart == 0 && lookahead == 1 (input done a byte at time) - // */ - // more--; - // } - //} - - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { - - require$$0.arraySet(s.window, s.window, _w_size, _w_size, 0); - s.match_start -= _w_size; - s.strstart -= _w_size; - /* we now have strstart >= MAX_DIST */ - s.block_start -= _w_size; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } - n = s.hash_size; - p = n; - do { - m = s.head[--p]; - s.head[p] = (m >= _w_size ? m - _w_size : 0); - } while (--n); + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s.lookahead <= 1) { - n = _w_size; - p = n; - do { - m = s.prev[--p]; - s.prev[p] = (m >= _w_size ? m - _w_size : 0); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); + //Assert(s->strstart < s->w_size+MAX_DIST(s) || + // s->block_start >= (long)s->w_size, "slide too late"); +// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || +// s.block_start >= s.w_size)) { +// throw new Error("slide too late"); +// } - more += _w_size; + fill_window(s); + if (s.lookahead === 0 && flush === Z_NO_FLUSH$1) { + return BS_NEED_MORE; } - if (s.strm.avail_in === 0) { + + if (s.lookahead === 0) { break; } + /* flush the current block */ + } + //Assert(s->block_start >= 0L, "block gone"); +// if (s.block_start < 0) throw new Error("block gone"); - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - //Assert(more >= 2, "more < 2"); - n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); - s.lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s.lookahead + s.insert >= MIN_MATCH) { - str = s.strstart - s.insert; - s.ins_h = s.window[str]; - - /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; - //#if MIN_MATCH != 3 - // Call update_hash() MIN_MATCH-3 more times - //#endif - while (s.insert) { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; - - s.prev[str & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = str; - str++; - s.insert--; - if (s.lookahead + s.insert < MIN_MATCH) { - break; - } - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ + s.strstart += s.lookahead; + s.lookahead = 0; - } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + /* Emit a stored block if pending_buf will be full: */ + var max_start = s.block_start + max_block_size; - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - // if (s.high_water < s.window_size) { - // var curr = s.strstart + s.lookahead; - // var init = 0; - // - // if (s.high_water < curr) { - // /* Previous high water mark below current data -- zero WIN_INIT - // * bytes or up to end of window, whichever is less. - // */ - // init = s.window_size - curr; - // if (init > WIN_INIT) - // init = WIN_INIT; - // zmemzero(s->window + curr, (unsigned)init); - // s->high_water = curr + init; - // } - // else if (s->high_water < (ulg)curr + WIN_INIT) { - // /* High water mark at or above current data, but below current data - // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - // * to end of window, whichever is less. - // */ - // init = (ulg)curr + WIN_INIT - s->high_water; - // if (init > s->window_size - s->high_water) - // init = s->window_size - s->high_water; - // zmemzero(s->window + s->high_water, (unsigned)init); - // s->high_water += init; - // } - // } - // - // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - // "not enough room for search"); - } + if (s.strstart === 0 || s.strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ - /* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ - function deflate_stored(s, flush) { - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - var max_block_size = 0xffff; - if (max_block_size > s.pending_buf_size - 5) { - max_block_size = s.pending_buf_size - 5; } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s.lookahead <= 1) { - - //Assert(s->strstart < s->w_size+MAX_DIST(s) || - // s->block_start >= (long)s->w_size, "slide too late"); - // if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || - // s.block_start >= s.w_size)) { - // throw new Error("slide too late"); - // } - - fill_window(s); - if (s.lookahead === 0 && flush === Z_NO_FLUSH$1) { - return BS_NEED_MORE; - } - - if (s.lookahead === 0) { - break; - } - /* flush the current block */ + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; } - //Assert(s->block_start >= 0L, "block gone"); - // if (s.block_start < 0) throw new Error("block gone"); + /***/ + } + } - s.strstart += s.lookahead; - s.lookahead = 0; + s.insert = 0; - /* Emit a stored block if pending_buf will be full: */ - var max_start = s.block_start + max_block_size; + if (flush === Z_FINISH$2) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } - if (s.strstart === 0 || s.strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s.lookahead = s.strstart - max_start; - s.strstart = max_start; - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ + if (s.strstart > s.block_start) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_NEED_MORE; +} +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +function deflate_fast(s, flush) { + var hash_head; /* head of the hash chain */ + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$1) { + return BS_NEED_MORE; } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ + if (s.lookahead === 0) { + break; /* flush the current block */ } } - s.insert = 0; - - if (flush === Z_FINISH$2) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; /***/ - return BS_FINISH_DONE; } - if (s.strstart > s.block_start) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - return BS_NEED_MORE; - } - - /* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ - function deflate_fast(s, flush) { - var hash_head; /* head of the hash chain */ - var bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$1) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { - break; /* flush the current block */ - } - } + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } + s.lookahead -= s.match_length; - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. */ - if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s.match_length >= MIN_MATCH) { - // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only - - /*** _tr_tally_dist(s, s.strstart - s.match_start, - s.match_length - MIN_MATCH, bflush); ***/ - bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); - - s.lookahead -= s.match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { - s.match_length--; /* string at strstart already in table */ - do { - s.strstart++; - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s.match_length !== 0); + if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { + s.match_length--; /* string at strstart already in table */ + do { s.strstart++; - } else - { - s.strstart += s.match_length; - s.match_length = 0; - s.ins_h = s.window[s.strstart]; - /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; - - //#if MIN_MATCH != 3 - // Call UPDATE_HASH() MIN_MATCH-3 more times - //#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. */ - } - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s.window[s.strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - - s.lookahead--; + } while (--s.match_length !== 0); s.strstart++; + } else + { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; + +//#if MIN_MATCH != 3 +// Call UPDATE_HASH() MIN_MATCH-3 more times +//#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); - if (flush === Z_FINISH$2) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; } - if (s.last_lit) { + if (bflush) { /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false); if (s.strm.avail_out === 0) { @@ -4939,257 +4361,257 @@ var serviceContext = (function (shared, vue) { } /***/ } - return BS_BLOCK_DONE; } + s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1); + if (flush === Z_FINISH$2) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} - /* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ - function deflate_slow(s, flush) { - var hash_head; /* head of hash chain */ - var bflush; /* set if current block must be flushed */ - - var max_insert; - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s.lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$1) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +function deflate_slow(s, flush) { + var hash_head; /* head of hash chain */ + var bflush; /* set if current block must be flushed */ + + var max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$1) { + return BS_NEED_MORE; } + if (s.lookahead === 0) { break; } /* flush the current block */ + } - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = 0/*NIL*/; - if (s.lookahead >= MIN_MATCH) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } - /* Find the longest match, discarding those <= prev_length. + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH - 1; + + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). */ - s.prev_length = s.match_length; - s.prev_match = s.match_start; - s.match_length = MIN_MATCH - 1; - - if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && - s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s.match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ - if (s.match_length <= 5 && - (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { + if (s.match_length <= 5 && + (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s.match_length = MIN_MATCH - 1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { - max_insert = s.strstart + s.lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - //check_match(s, s.strstart-1, s.prev_match, s.prev_length); - - /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, - s.prev_length - MIN_MATCH, bflush);***/ - bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. */ - s.lookahead -= s.prev_length - 1; - s.prev_length -= 2; - do { - if (++s.strstart <= max_insert) { - /*** INSERT_STRING(s, s.strstart, hash_head); ***/ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; - hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; - s.head[s.ins_h] = s.strstart; - /***/ - } - } while (--s.prev_length !== 0); - s.match_available = 0; s.match_length = MIN_MATCH - 1; - s.strstart++; - - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length - 1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; /***/ } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH - 1; + s.strstart++; - } else if (s.match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - //Tracevv((stderr,"%c", s->window[s->strstart-1])); - /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); - - if (bflush) { - /*** FLUSH_BLOCK_ONLY(s, 0) ***/ - flush_block_only(s, false); - /***/ - } - s.strstart++; - s.lookahead--; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); if (s.strm.avail_out === 0) { return BS_NEED_MORE; } - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s.match_available = 1; - s.strstart++; - s.lookahead--; + /***/ } - } - //Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s.match_available) { + + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ //Tracevv((stderr,"%c", s->window[s->strstart-1])); /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); - s.match_available = 0; - } - s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; - if (flush === Z_FINISH$2) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ } - /***/ - return BS_FINISH_DONE; - } - if (s.last_lit) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); + s.strstart++; + s.lookahead--; if (s.strm.avail_out === 0) { return BS_NEED_MORE; } - /***/ + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]); - return BS_BLOCK_DONE; + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1; + if (flush === Z_FINISH$2) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ } + return BS_BLOCK_DONE; +} - /* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ - function deflate_rle(s, flush) { - var bflush; /* set if current block must be flushed */ - var prev; /* byte at distance one to match */ - var scan, strend; /* scan goes up to strend for length of run */ - var _win = s.window; +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +function deflate_rle(s, flush) { + var bflush; /* set if current block must be flushed */ + var prev; /* byte at distance one to match */ + var scan, strend; /* scan goes up to strend for length of run */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s.lookahead <= MAX_MATCH) { - fill_window(s); - if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$1) { - return BS_NEED_MORE; - } - if (s.lookahead === 0) { break; } /* flush the current block */ + var _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$1) { + return BS_NEED_MORE; } + if (s.lookahead === 0) { break; } /* flush the current block */ + } - /* See how many times the previous byte repeats */ - s.match_length = 0; - if (s.lookahead >= MIN_MATCH && s.strstart > 0) { - scan = s.strstart - 1; - prev = _win[scan]; - if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { - strend = s.strstart + MAX_MATCH; - do { - /*jshint noempty:false*/ - } while (prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - prev === _win[++scan] && prev === _win[++scan] && - scan < strend); - s.match_length = MAX_MATCH - (strend - scan); - if (s.match_length > s.lookahead) { - s.match_length = s.lookahead; - } + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while (prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; } - //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s.match_length >= MIN_MATCH) { - //check_match(s, s.strstart, s.strstart - 1, s.match_length); + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); - /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ - bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); - s.lookahead -= s.match_length; - s.strstart += s.match_length; - s.match_length = 0; - } else { - /* No match, output a literal byte */ - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - } - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { - return BS_NEED_MORE; - } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$2) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; - } - /***/ - return BS_FINISH_DONE; + s.lookahead--; + s.strstart++; } - if (s.last_lit) { + if (bflush) { /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false); if (s.strm.avail_out === 0) { @@ -5197,55 +4619,55 @@ var serviceContext = (function (shared, vue) { } /***/ } - return BS_BLOCK_DONE; } + s.insert = 0; + if (flush === Z_FINISH$2) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} - /* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ - function deflate_huff(s, flush) { - var bflush; /* set if current block must be flushed */ +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +function deflate_huff(s, flush) { + var bflush; /* set if current block must be flushed */ - for (;;) { - /* Make sure that we have a literal to write. */ + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); if (s.lookahead === 0) { - fill_window(s); - if (s.lookahead === 0) { - if (flush === Z_NO_FLUSH$1) { - return BS_NEED_MORE; - } - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s.match_length = 0; - //Tracevv((stderr,"%c", s->window[s->strstart])); - /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ - bflush = trees._tr_tally(s, 0, s.window[s.strstart]); - s.lookahead--; - s.strstart++; - if (bflush) { - /*** FLUSH_BLOCK(s, 0); ***/ - flush_block_only(s, false); - if (s.strm.avail_out === 0) { + if (flush === Z_NO_FLUSH$1) { return BS_NEED_MORE; } - /***/ - } - } - s.insert = 0; - if (flush === Z_FINISH$2) { - /*** FLUSH_BLOCK(s, 1); ***/ - flush_block_only(s, true); - if (s.strm.avail_out === 0) { - return BS_FINISH_STARTED; + break; /* flush the current block */ } - /***/ - return BS_FINISH_DONE; } - if (s.last_lit) { + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { /*** FLUSH_BLOCK(s, 0); ***/ flush_block_only(s, false); if (s.strm.avail_out === 0) { @@ -5253,2753 +4675,2799 @@ var serviceContext = (function (shared, vue) { } /***/ } - return BS_BLOCK_DONE; } - - /* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ - function Config(good_length, max_lazy, nice_length, max_chain, func) { - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; + s.insert = 0; + if (flush === Z_FINISH$2) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ } + return BS_BLOCK_DONE; +} - var configuration_table; +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +function Config(good_length, max_lazy, nice_length, max_chain, func) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; +} - configuration_table = [ - /* good lazy nice chain */ - new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ - new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ - new Config(4, 5, 16, 8, deflate_fast), /* 2 */ - new Config(4, 6, 32, 32, deflate_fast), /* 3 */ +var configuration_table; - new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ - new Config(8, 16, 32, 32, deflate_slow), /* 5 */ - new Config(8, 16, 128, 128, deflate_slow), /* 6 */ - new Config(8, 32, 128, 256, deflate_slow), /* 7 */ - new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ - new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ - ]; +configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), /* 3 */ + new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ +]; - /* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ - function lm_init(s) { - s.window_size = 2 * s.w_size; - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +function lm_init(s) { + s.window_size = 2 * s.w_size; - /* Set the default configuration parameters: - */ - s.max_lazy_match = configuration_table[s.level].max_lazy; - s.good_match = configuration_table[s.level].good_length; - s.nice_match = configuration_table[s.level].nice_length; - s.max_chain_length = configuration_table[s.level].max_chain; + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.lookahead = 0; - s.insert = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - s.ins_h = 0; - } + /* Set the default configuration parameters: + */ + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; +} - function DeflateState() { - this.strm = null; /* pointer back to this zlib stream */ - this.status = 0; /* as the name implies */ - this.pending_buf = null; /* output still pending */ - this.pending_buf_size = 0; /* size of pending_buf */ - this.pending_out = 0; /* next pending byte to output to the stream */ - this.pending = 0; /* nb of bytes in the pending buffer */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.gzhead = null; /* gzip header information to write */ - this.gzindex = 0; /* where in extra, name, or comment */ - this.method = Z_DEFLATED$2; /* can only be DEFLATED */ - this.last_flush = -1; /* value of flush param for previous deflate call */ - - this.w_size = 0; /* LZ77 window size (32K by default) */ - this.w_bits = 0; /* log2(w_size) (8..16) */ - this.w_mask = 0; /* w_size - 1 */ - - this.window = null; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. - */ +function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED$2; /* can only be DEFLATED */ + this.last_flush = -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ - this.window_size = 0; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ - this.prev = null; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ - this.head = null; /* Heads of the hash chains or NIL. */ + this.head = null; /* Heads of the hash chains or NIL. */ - this.ins_h = 0; /* hash index of string to be inserted */ - this.hash_size = 0; /* number of elements in hash table */ - this.hash_bits = 0; /* log2(hash_size) */ - this.hash_mask = 0; /* hash_size-1 */ + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ - this.hash_shift = 0; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ - this.block_start = 0; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ - this.match_length = 0; /* length of best match */ - this.prev_match = 0; /* previous match */ - this.match_available = 0; /* set if previous match exists */ - this.strstart = 0; /* start of string to insert */ - this.match_start = 0; /* start of matching string */ - this.lookahead = 0; /* number of valid bytes ahead in window */ + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ - this.prev_length = 0; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ - this.max_chain_length = 0; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ - this.max_lazy_match = 0; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ - // That's alias to max_lazy_match, don't use directly - //this.max_insert_length = 0; - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ - this.level = 0; /* compression level (1..9) */ - this.strategy = 0; /* favor or force Huffman coding*/ + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ - this.good_match = 0; - /* Use a faster search when the previous match is longer than this */ + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ - this.nice_match = 0; /* Stop searching when current match exceeds this */ + this.nice_match = 0; /* Stop searching when current match exceeds this */ - /* used by trees.c: */ + /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ + /* Didn't use ct_data typedef below to suppress compiler warning */ - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - // Use flat array of DOUBLE size, with interleaved fata, - // because JS does not support effective - this.dyn_ltree = new require$$0.Buf16(HEAP_SIZE * 2); - this.dyn_dtree = new require$$0.Buf16((2 * D_CODES + 1) * 2); - this.bl_tree = new require$$0.Buf16((2 * BL_CODES + 1) * 2); - zero(this.dyn_ltree); - zero(this.dyn_dtree); - zero(this.bl_tree); + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new require$$0.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new require$$0.Buf16((2 * D_CODES + 1) * 2); + this.bl_tree = new require$$0.Buf16((2 * BL_CODES + 1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); - this.l_desc = null; /* desc. for literal tree */ - this.d_desc = null; /* desc. for distance tree */ - this.bl_desc = null; /* desc. for bit length tree */ + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ - //ush bl_count[MAX_BITS+1]; - this.bl_count = new require$$0.Buf16(MAX_BITS + 1); - /* number of codes at each bit length for an optimal tree */ + //ush bl_count[MAX_BITS+1]; + this.bl_count = new require$$0.Buf16(MAX_BITS + 1); + /* number of codes at each bit length for an optimal tree */ - //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - this.heap = new require$$0.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */ - zero(this.heap); + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new require$$0.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */ + zero(this.heap); - this.heap_len = 0; /* number of elements in the heap */ - this.heap_max = 0; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ - this.depth = new require$$0.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; - zero(this.depth); - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ + this.depth = new require$$0.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ - this.l_buf = 0; /* buffer index for literals or lengths */ - - this.lit_bufsize = 0; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ + this.l_buf = 0; /* buffer index for literals or lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ - this.last_lit = 0; /* running index in l_buf */ + this.last_lit = 0; /* running index in l_buf */ - this.d_buf = 0; - /* Buffer index for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ + this.d_buf = 0; + /* Buffer index for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ - this.opt_len = 0; /* bit length of current block with optimal trees */ - this.static_len = 0; /* bit length of current block with static trees */ - this.matches = 0; /* number of string matches in current block */ - this.insert = 0; /* bytes at end of window left to insert */ + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ - this.bi_buf = 0; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - this.bi_valid = 0; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ - // Used for window memory init. We safely ignore it for JS. That makes - // sense only for pointers and memory check tools. - //this.high_water = 0; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - } + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ +} - function deflateResetKeep(strm) { - var s; +function deflateResetKeep(strm) { + var s; - if (!strm || !strm.state) { - return err(strm, Z_STREAM_ERROR$1); - } + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR$1); + } - strm.total_in = strm.total_out = 0; - strm.data_type = Z_UNKNOWN; + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; - s = strm.state; - s.pending = 0; - s.pending_out = 0; + s = strm.state; + s.pending = 0; + s.pending_out = 0; - if (s.wrap < 0) { - s.wrap = -s.wrap; - /* was made negative by deflate(..., Z_FINISH); */ - } - s.status = (s.wrap ? INIT_STATE : BUSY_STATE); - strm.adler = (s.wrap === 2) ? - 0 // crc32(0, Z_NULL, 0) - : - 1; // adler32(0, Z_NULL, 0) - s.last_flush = Z_NO_FLUSH$1; - trees._tr_init(s); - return Z_OK$2; + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ } + s.status = (s.wrap ? INIT_STATE : BUSY_STATE); + strm.adler = (s.wrap === 2) ? + 0 // crc32(0, Z_NULL, 0) + : + 1; // adler32(0, Z_NULL, 0) + s.last_flush = Z_NO_FLUSH$1; + trees._tr_init(s); + return Z_OK$2; +} - function deflateReset(strm) { - var ret = deflateResetKeep(strm); - if (ret === Z_OK$2) { - lm_init(strm.state); - } - return ret; +function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK$2) { + lm_init(strm.state); } + return ret; +} - function deflateSetHeader(strm, head) { - if (!strm || !strm.state) { return Z_STREAM_ERROR$1; } - if (strm.state.wrap !== 2) { return Z_STREAM_ERROR$1; } - strm.state.gzhead = head; - return Z_OK$2; - } +function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { return Z_STREAM_ERROR$1; } + if (strm.state.wrap !== 2) { return Z_STREAM_ERROR$1; } + strm.state.gzhead = head; + return Z_OK$2; +} - function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { - if (!strm) { // === Z_NULL - return Z_STREAM_ERROR$1; - } - var wrap = 1; +function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { + if (!strm) { // === Z_NULL + return Z_STREAM_ERROR$1; + } + var wrap = 1; - if (level === Z_DEFAULT_COMPRESSION$1) { - level = 6; - } + if (level === Z_DEFAULT_COMPRESSION$1) { + level = 6; + } - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return err(strm, Z_STREAM_ERROR$1); - } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return err(strm, Z_STREAM_ERROR$1); + } - if (windowBits === 8) { - windowBits = 9; - } - /* until 256-byte window bug fixed */ + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ - var s = new DeflateState(); + var s = new DeflateState(); - strm.state = s; - s.strm = strm; + strm.state = s; + s.strm = strm; - s.wrap = wrap; - s.gzhead = null; - s.w_bits = windowBits; - s.w_size = 1 << s.w_bits; - s.w_mask = s.w_size - 1; + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; - s.hash_bits = memLevel + 7; - s.hash_size = 1 << s.hash_bits; - s.hash_mask = s.hash_size - 1; - s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); - s.window = new require$$0.Buf8(s.w_size * 2); - s.head = new require$$0.Buf16(s.hash_size); - s.prev = new require$$0.Buf16(s.w_size); + s.window = new require$$0.Buf8(s.w_size * 2); + s.head = new require$$0.Buf16(s.hash_size); + s.prev = new require$$0.Buf16(s.w_size); - // Don't need mem init magic for JS. - //s.high_water = 0; /* nothing written to s->window yet */ + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ - s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - s.pending_buf_size = s.lit_bufsize * 4; + s.pending_buf_size = s.lit_bufsize * 4; - //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - //s->pending_buf = (uchf *) overlay; - s.pending_buf = new require$$0.Buf8(s.pending_buf_size); + //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + //s->pending_buf = (uchf *) overlay; + s.pending_buf = new require$$0.Buf8(s.pending_buf_size); - // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) - //s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s.d_buf = 1 * s.lit_bufsize; + // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`) + //s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s.d_buf = 1 * s.lit_bufsize; - //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - s.l_buf = (1 + 2) * s.lit_bufsize; + //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + s.l_buf = (1 + 2) * s.lit_bufsize; - s.level = level; - s.strategy = strategy; - s.method = method; + s.level = level; + s.strategy = strategy; + s.method = method; - return deflateReset(strm); - } + return deflateReset(strm); +} - function deflateInit(strm, level) { - return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1); - } +function deflateInit(strm, level) { + return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1); +} - function deflate$2(strm, flush) { - var old_flush, s; - var beg, val; // for gzip header write only +function deflate$2(strm, flush) { + var old_flush, s; + var beg, val; // for gzip header write only - if (!strm || !strm.state || - flush > Z_BLOCK$1 || flush < 0) { - return strm ? err(strm, Z_STREAM_ERROR$1) : Z_STREAM_ERROR$1; - } + if (!strm || !strm.state || + flush > Z_BLOCK$1 || flush < 0) { + return strm ? err(strm, Z_STREAM_ERROR$1) : Z_STREAM_ERROR$1; + } - s = strm.state; + s = strm.state; - if (!strm.output || - (!strm.input && strm.avail_in !== 0) || - (s.status === FINISH_STATE && flush !== Z_FINISH$2)) { - return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$1); - } + if (!strm.output || + (!strm.input && strm.avail_in !== 0) || + (s.status === FINISH_STATE && flush !== Z_FINISH$2)) { + return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$1); + } - s.strm = strm; /* just in case */ - old_flush = s.last_flush; - s.last_flush = flush; - - /* Write the header */ - if (s.status === INIT_STATE) { - - if (s.wrap === 2) { // GZIP header - strm.adler = 0; //crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (!s.gzhead) { // s->gzhead == Z_NULL - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s.status = BUSY_STATE; + s.strm = strm; /* just in case */ + old_flush = s.last_flush; + s.last_flush = flush; + + /* Write the header */ + if (s.status === INIT_STATE) { + + if (s.wrap === 2) { // GZIP header + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } + else { + put_byte(s, (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, s.gzhead.os & 0xff); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 0xff); + put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); } - else { - put_byte(s, (s.gzhead.text ? 1 : 0) + - (s.gzhead.hcrc ? 2 : 0) + - (!s.gzhead.extra ? 0 : 4) + - (!s.gzhead.name ? 0 : 8) + - (!s.gzhead.comment ? 0 : 16) - ); - put_byte(s, s.gzhead.time & 0xff); - put_byte(s, (s.gzhead.time >> 8) & 0xff); - put_byte(s, (s.gzhead.time >> 16) & 0xff); - put_byte(s, (s.gzhead.time >> 24) & 0xff); - put_byte(s, s.level === 9 ? 2 : - (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? - 4 : 0)); - put_byte(s, s.gzhead.os & 0xff); - if (s.gzhead.extra && s.gzhead.extra.length) { - put_byte(s, s.gzhead.extra.length & 0xff); - put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); - } - if (s.gzhead.hcrc) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); - } - s.gzindex = 0; - s.status = EXTRA_STATE; + if (s.gzhead.hcrc) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); } + s.gzindex = 0; + s.status = EXTRA_STATE; } - else // DEFLATE header - { - var header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8; - var level_flags = -1; - - if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { - level_flags = 0; - } else if (s.level < 6) { - level_flags = 1; - } else if (s.level === 6) { - level_flags = 2; - } else { - level_flags = 3; - } - header |= (level_flags << 6); - if (s.strstart !== 0) { header |= PRESET_DICT; } - header += 31 - (header % 31); + } + else // DEFLATE header + { + var header = (Z_DEFLATED$2 + ((s.w_bits - 8) << 4)) << 8; + var level_flags = -1; + + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= (level_flags << 6); + if (s.strstart !== 0) { header |= PRESET_DICT; } + header += 31 - (header % 31); - s.status = BUSY_STATE; - putShortMSB(s, header); + s.status = BUSY_STATE; + putShortMSB(s, header); - /* Save the adler32 of the preset dictionary: */ - if (s.strstart !== 0) { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - strm.adler = 1; // adler32(0L, Z_NULL, 0); + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); } + strm.adler = 1; // adler32(0L, Z_NULL, 0); } + } - //#ifdef GZIP - if (s.status === EXTRA_STATE) { - if (s.gzhead.extra/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ +//#ifdef GZIP + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ - while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { + while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - break; - } + break; } - put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); - s.gzindex++; - } - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - if (s.gzindex === s.gzhead.extra.length) { - s.gzindex = 0; - s.status = NAME_STATE; } + put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); + s.gzindex++; } - else { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; s.status = NAME_STATE; } } - if (s.status === NAME_STATE) { - if (s.gzhead.name/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - //int val; + else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; - do { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - val = 1; - break; - } + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.name.length) { - val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; } - put_byte(s, val); - } while (val !== 0); - - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); } - if (val === 0) { - s.gzindex = 0; - s.status = COMMENT_STATE; + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); } - else { + if (val === 0) { + s.gzindex = 0; s.status = COMMENT_STATE; } } - if (s.status === COMMENT_STATE) { - if (s.gzhead.comment/* != Z_NULL*/) { - beg = s.pending; /* start of bytes to update crc */ - //int val; + else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; - do { - if (s.pending === s.pending_buf_size) { - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); - } - flush_pending(strm); - beg = s.pending; - if (s.pending === s.pending_buf_size) { - val = 1; - break; - } + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); } - // JS specific: little magic to add zero terminator to end of string - if (s.gzindex < s.gzhead.comment.length) { - val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; - } else { - val = 0; + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; } - put_byte(s, val); - } while (val !== 0); - - if (s.gzhead.hcrc && s.pending > beg) { - strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); } - if (val === 0) { - s.status = HCRC_STATE; + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); } - else { + if (val === 0) { s.status = HCRC_STATE; } } - if (s.status === HCRC_STATE) { - if (s.gzhead.hcrc) { - if (s.pending + 2 > s.pending_buf_size) { - flush_pending(strm); - } - if (s.pending + 2 <= s.pending_buf_size) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - strm.adler = 0; //crc32(0L, Z_NULL, 0); - s.status = BUSY_STATE; - } + else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); } - else { + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); s.status = BUSY_STATE; } } - //#endif - - /* Flush as much pending output as possible */ - if (s.pending !== 0) { - flush_pending(strm); - if (strm.avail_out === 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s.last_flush = -1; - return Z_OK$2; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && - flush !== Z_FINISH$2) { - return err(strm, Z_BUF_ERROR$1); + else { + s.status = BUSY_STATE; } + } +//#endif - /* User must not provide more input after the first FINISH: */ - if (s.status === FINISH_STATE && strm.avail_in !== 0) { - return err(strm, Z_BUF_ERROR$1); + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK$2; } - /* Start a new block or continue the current one. + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. */ - if (strm.avail_in !== 0 || s.lookahead !== 0 || - (flush !== Z_NO_FLUSH$1 && s.status !== FINISH_STATE)) { - var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : - (s.strategy === Z_RLE ? deflate_rle(s, flush) : - configuration_table[s.level].func(s, flush)); - - if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { - s.status = FINISH_STATE; + } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && + flush !== Z_FINISH$2) { + return err(strm, Z_BUF_ERROR$1); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR$1); + } + + /* Start a new block or continue the current one. + */ + if (strm.avail_in !== 0 || s.lookahead !== 0 || + (flush !== Z_NO_FLUSH$1 && s.status !== FINISH_STATE)) { + var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : + (s.strategy === Z_RLE ? deflate_rle(s, flush) : + configuration_table[s.level].func(s, flush)); + + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ } - if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { - if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR next call, see above */ - } - return Z_OK$2; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ + return Z_OK$2; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + trees._tr_align(s); } - if (bstate === BS_BLOCK_DONE) { - if (flush === Z_PARTIAL_FLUSH) { - trees._tr_align(s); - } - else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */ + else if (flush !== Z_BLOCK$1) { /* FULL_FLUSH or SYNC_FLUSH */ - trees._tr_stored_block(s, 0, 0, false); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush === Z_FULL_FLUSH) { - /*** CLEAR_HASH(s); ***/ /* forget history */ - zero(s.head); // Fill with NIL (= 0); - - if (s.lookahead === 0) { - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } + trees._tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; } } - flush_pending(strm); - if (strm.avail_out === 0) { - s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK$2; - } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK$2; } } - //Assert(strm->avail_out > 0, "bug2"); - //if (strm.avail_out <= 0) { throw new Error("bug2");} - - if (flush !== Z_FINISH$2) { return Z_OK$2; } - if (s.wrap <= 0) { return Z_STREAM_END$2; } - - /* Write the trailer */ - if (s.wrap === 2) { - put_byte(s, strm.adler & 0xff); - put_byte(s, (strm.adler >> 8) & 0xff); - put_byte(s, (strm.adler >> 16) & 0xff); - put_byte(s, (strm.adler >> 24) & 0xff); - put_byte(s, strm.total_in & 0xff); - put_byte(s, (strm.total_in >> 8) & 0xff); - put_byte(s, (strm.total_in >> 16) & 0xff); - put_byte(s, (strm.total_in >> 24) & 0xff); - } - else - { - putShortMSB(s, strm.adler >>> 16); - putShortMSB(s, strm.adler & 0xffff); - } - - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s.wrap > 0) { s.wrap = -s.wrap; } - /* write the trailer only once! */ - return s.pending !== 0 ? Z_OK$2 : Z_STREAM_END$2; + } + //Assert(strm->avail_out > 0, "bug2"); + //if (strm.avail_out <= 0) { throw new Error("bug2");} + + if (flush !== Z_FINISH$2) { return Z_OK$2; } + if (s.wrap <= 0) { return Z_STREAM_END$2; } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } + else + { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); } - function deflateEnd(strm) { - var status; - - if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { - return Z_STREAM_ERROR$1; - } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { s.wrap = -s.wrap; } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK$2 : Z_STREAM_END$2; +} - status = strm.state.status; - if (status !== INIT_STATE && - status !== EXTRA_STATE && - status !== NAME_STATE && - status !== COMMENT_STATE && - status !== HCRC_STATE && - status !== BUSY_STATE && - status !== FINISH_STATE - ) { - return err(strm, Z_STREAM_ERROR$1); - } +function deflateEnd(strm) { + var status; - strm.state = null; + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR$1; + } - return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$1) : Z_OK$2; + status = strm.state.status; + if (status !== INIT_STATE && + status !== EXTRA_STATE && + status !== NAME_STATE && + status !== COMMENT_STATE && + status !== HCRC_STATE && + status !== BUSY_STATE && + status !== FINISH_STATE + ) { + return err(strm, Z_STREAM_ERROR$1); } + strm.state = null; - /* ========================================================================= - * Initializes the compression dictionary from the given byte - * sequence without producing any compressed output. - */ - function deflateSetDictionary(strm, dictionary) { - var dictLength = dictionary.length; - - var s; - var str, n; - var wrap; - var avail; - var next; - var input; - var tmpDict; - - if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { - return Z_STREAM_ERROR$1; - } + return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$1) : Z_OK$2; +} - s = strm.state; - wrap = s.wrap; - if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { - return Z_STREAM_ERROR$1; - } +/* ========================================================================= + * Initializes the compression dictionary from the given byte + * sequence without producing any compressed output. + */ +function deflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap === 1) { - /* adler32(strm->adler, dictionary, dictLength); */ - strm.adler = adler32(strm.adler, dictionary, dictLength, 0); - } + var s; + var str, n; + var wrap; + var avail; + var next; + var input; + var tmpDict; - s.wrap = 0; /* avoid computing Adler-32 in read_buf */ + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR$1; + } - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s.w_size) { - if (wrap === 0) { /* already empty otherwise */ - /*** CLEAR_HASH(s); ***/ - zero(s.head); // Fill with NIL (= 0); - s.strstart = 0; - s.block_start = 0; - s.insert = 0; - } - /* use the tail */ - // dictionary = dictionary.slice(dictLength - s.w_size); - tmpDict = new require$$0.Buf8(s.w_size); - require$$0.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0); - dictionary = tmpDict; - dictLength = s.w_size; - } - /* insert dictionary into window and hash */ - avail = strm.avail_in; - next = strm.next_in; - input = strm.input; - strm.avail_in = dictLength; - strm.next_in = 0; - strm.input = dictionary; - fill_window(s); - while (s.lookahead >= MIN_MATCH) { - str = s.strstart; - n = s.lookahead - (MIN_MATCH - 1); - do { - /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ - s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; + s = strm.state; + wrap = s.wrap; - s.prev[str & s.w_mask] = s.head[s.ins_h]; + if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) { + return Z_STREAM_ERROR$1; + } - s.head[s.ins_h] = str; - str++; - } while (--n); - s.strstart = str; - s.lookahead = MIN_MATCH - 1; - fill_window(s); - } - s.strstart += s.lookahead; - s.block_start = s.strstart; - s.insert = s.lookahead; - s.lookahead = 0; - s.match_length = s.prev_length = MIN_MATCH - 1; - s.match_available = 0; - strm.next_in = next; - strm.input = input; - strm.avail_in = avail; - s.wrap = wrap; - return Z_OK$2; + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap === 1) { + /* adler32(strm->adler, dictionary, dictLength); */ + strm.adler = adler32(strm.adler, dictionary, dictLength, 0); } + s.wrap = 0; /* avoid computing Adler-32 in read_buf */ - var deflateInit_1 = deflateInit; - var deflateInit2_1 = deflateInit2; - var deflateReset_1 = deflateReset; - var deflateResetKeep_1 = deflateResetKeep; - var deflateSetHeader_1 = deflateSetHeader; - var deflate_2$1 = deflate$2; - var deflateEnd_1 = deflateEnd; - var deflateSetDictionary_1 = deflateSetDictionary; - var deflateInfo = 'pako deflate (from Nodeca project)'; - - /* Not implemented - exports.deflateBound = deflateBound; - exports.deflateCopy = deflateCopy; - exports.deflateParams = deflateParams; - exports.deflatePending = deflatePending; - exports.deflatePrime = deflatePrime; - exports.deflateTune = deflateTune; - */ + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s.w_size) { + if (wrap === 0) { /* already empty otherwise */ + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + /* use the tail */ + // dictionary = dictionary.slice(dictLength - s.w_size); + tmpDict = new require$$0.Buf8(s.w_size); + require$$0.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0); + dictionary = tmpDict; + dictLength = s.w_size; + } + /* insert dictionary into window and hash */ + avail = strm.avail_in; + next = strm.next_in; + input = strm.input; + strm.avail_in = dictLength; + strm.next_in = 0; + strm.input = dictionary; + fill_window(s); + while (s.lookahead >= MIN_MATCH) { + str = s.strstart; + n = s.lookahead - (MIN_MATCH - 1); + do { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask; - var deflate_1$1 = { - deflateInit: deflateInit_1, - deflateInit2: deflateInit2_1, - deflateReset: deflateReset_1, - deflateResetKeep: deflateResetKeep_1, - deflateSetHeader: deflateSetHeader_1, - deflate: deflate_2$1, - deflateEnd: deflateEnd_1, - deflateSetDictionary: deflateSetDictionary_1, - deflateInfo: deflateInfo - }; - - // Quick check if we can use fast array to bin string conversion - // - // - apply(Array) can fail on Android 2.2 - // - apply(Uint8Array) can fail on iOS 5.1 Safari - // - var STR_APPLY_OK = true; - var STR_APPLY_UIA_OK = true; + s.prev[str & s.w_mask] = s.head[s.ins_h]; - try { String.fromCharCode.apply(null, [ 0 ]); } catch (__) { STR_APPLY_OK = false; } - try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; } + s.head[s.ins_h] = str; + str++; + } while (--n); + s.strstart = str; + s.lookahead = MIN_MATCH - 1; + fill_window(s); + } + s.strstart += s.lookahead; + s.block_start = s.strstart; + s.insert = s.lookahead; + s.lookahead = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + strm.next_in = next; + strm.input = input; + strm.avail_in = avail; + s.wrap = wrap; + return Z_OK$2; +} - // Table with utf8 lengths (calculated by first byte of sequence) - // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, - // because max possible codepoint is 0x10ffff - var _utf8len = new require$$0.Buf8(256); - for (var q = 0; q < 256; q++) { - _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); - } - _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start +var deflateInit_1 = deflateInit; +var deflateInit2_1 = deflateInit2; +var deflateReset_1 = deflateReset; +var deflateResetKeep_1 = deflateResetKeep; +var deflateSetHeader_1 = deflateSetHeader; +var deflate_2$1 = deflate$2; +var deflateEnd_1 = deflateEnd; +var deflateSetDictionary_1 = deflateSetDictionary; +var deflateInfo = 'pako deflate (from Nodeca project)'; + +/* Not implemented +exports.deflateBound = deflateBound; +exports.deflateCopy = deflateCopy; +exports.deflateParams = deflateParams; +exports.deflatePending = deflatePending; +exports.deflatePrime = deflatePrime; +exports.deflateTune = deflateTune; +*/ + +var deflate_1$1 = { + deflateInit: deflateInit_1, + deflateInit2: deflateInit2_1, + deflateReset: deflateReset_1, + deflateResetKeep: deflateResetKeep_1, + deflateSetHeader: deflateSetHeader_1, + deflate: deflate_2$1, + deflateEnd: deflateEnd_1, + deflateSetDictionary: deflateSetDictionary_1, + deflateInfo: deflateInfo +}; + +// Quick check if we can use fast array to bin string conversion +// +// - apply(Array) can fail on Android 2.2 +// - apply(Uint8Array) can fail on iOS 5.1 Safari +// +var STR_APPLY_OK = true; +var STR_APPLY_UIA_OK = true; + +try { String.fromCharCode.apply(null, [ 0 ]); } catch (__) { STR_APPLY_OK = false; } +try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; } + + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new require$$0.Buf8(256); +for (var q = 0; q < 256; q++) { + _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1); +} +_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start - // convert string to array (typed, when possible) - var string2buf = function (str) { - var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; +// convert string to array (typed, when possible) +var string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } - // allocate buffer - buf = new require$$0.Buf8(buf_len); - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xC0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xE0 | (c >>> 12); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | (c >>> 12 & 0x3f); - buf[i++] = 0x80 | (c >>> 6 & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); + // allocate buffer + buf = new require$$0.Buf8(buf_len); + + // convert + for (i = 0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) { + c2 = str.charCodeAt(m_pos + 1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; } } - - return buf; - }; - - // Helper (used in 2 places) - function buf2binstring(buf, len) { - // On Chrome, the arguments in a function call that are allowed is `65534`. - // If the length of the buffer is smaller than that, we can use this optimization, - // otherwise we will take a slower path. - if (len < 65534) { - if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { - return String.fromCharCode.apply(null, require$$0.shrinkBuf(buf, len)); - } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); } + } - var result = ''; - for (var i = 0; i < len; i++) { - result += String.fromCharCode(buf[i]); + return buf; +}; + +// Helper (used in 2 places) +function buf2binstring(buf, len) { + // On Chrome, the arguments in a function call that are allowed is `65534`. + // If the length of the buffer is smaller than that, we can use this optimization, + // otherwise we will take a slower path. + if (len < 65534) { + if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { + return String.fromCharCode.apply(null, require$$0.shrinkBuf(buf, len)); } - return result; } + var result = ''; + for (var i = 0; i < len; i++) { + result += String.fromCharCode(buf[i]); + } + return result; +} + - // Convert byte array to binary string - var buf2binstring_1 = function (buf) { - return buf2binstring(buf, buf.length); - }; +// Convert byte array to binary string +var buf2binstring_1 = function (buf) { + return buf2binstring(buf, buf.length); +}; - // Convert binary string (typed, when possible) - var binstring2buf = function (str) { - var buf = new require$$0.Buf8(str.length); - for (var i = 0, len = buf.length; i < len; i++) { - buf[i] = str.charCodeAt(i); +// Convert binary string (typed, when possible) +var binstring2buf = function (str) { + var buf = new require$$0.Buf8(str.length); + for (var i = 0, len = buf.length; i < len; i++) { + buf[i] = str.charCodeAt(i); + } + return buf; +}; + + +// convert array to string +var buf2string = function (buf, max) { + var i, out, c, c_len; + var len = max || buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len * 2); + + for (out = 0, i = 0; i < len;) { + c = buf[i++]; + // quick process ascii + if (c < 0x80) { utf16buf[out++] = c; continue; } + + c_len = _utf8len[c]; + // skip 5 & 6 byte codes + if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; } - return buf; - }; - - - // convert array to string - var buf2string = function (buf, max) { - var i, out, c, c_len; - var len = max || buf.length; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - var utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len;) { - c = buf[i++]; - // quick process ascii - if (c < 0x80) { utf16buf[out++] = c; continue; } - - c_len = _utf8len[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - // terminated by end of string? - if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); } + } - return buf2binstring(utf16buf, out); - }; - + return buf2binstring(utf16buf, out); +}; + + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = function (buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max - 1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means buffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +var strings$1 = { + string2buf: string2buf, + buf2binstring: buf2binstring_1, + binstring2buf: binstring2buf, + buf2string: buf2string, + utf8border: utf8border +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +function ZStream$1() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} - // Calculate max possible position in utf8 buffer, - // that will not break sequence. If that's not possible - // - (very small limits) return max size as is. - // - // buf[] - utf8 bytes array - // max - length limit (mandatory); - var utf8border = function (buf, max) { - var pos; - - max = max || buf.length; - if (max > buf.length) { max = buf.length; } - - // go back from last position, until start of sequence found - pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } - - // Very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { return max; } - - // If we came to start of buffer - that means buffer is too small, - // return max too. - if (pos === 0) { return max; } - - return (pos + _utf8len[buf[pos]] > max) ? pos : max; - }; - - var strings$1 = { - string2buf: string2buf, - buf2binstring: buf2binstring_1, - binstring2buf: binstring2buf, - buf2string: buf2string, - utf8border: utf8border - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function ZStream$1() { - /* next input byte */ - this.input = null; // JS specific, because we have no pointers - this.next_in = 0; - /* number of bytes available at input */ - this.avail_in = 0; - /* total number of input bytes read so far */ - this.total_in = 0; - /* next output byte should be put there */ - this.output = null; // JS specific, because we have no pointers - this.next_out = 0; - /* remaining free space at output */ - this.avail_out = 0; - /* total number of bytes output so far */ - this.total_out = 0; - /* last error message, NULL if no error */ - this.msg = ''/*Z_NULL*/; - /* not visible by applications */ - this.state = null; - /* best guess about the data type: binary or text */ - this.data_type = 2/*Z_UNKNOWN*/; - /* adler32 value of the uncompressed data */ - this.adler = 0; +var zstream = ZStream$1; + +var zlib_deflate = deflate_1$1; + +var strings = strings$1; + +var ZStream = zstream; + +var toString$2 = Object.prototype.toString; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +var Z_NO_FLUSH = 0; +var Z_FINISH$1 = 4; + +var Z_OK$1 = 0; +var Z_STREAM_END$1 = 1; +var Z_SYNC_FLUSH = 2; + +var Z_DEFAULT_COMPRESSION = -1; + +var Z_DEFAULT_STRATEGY = 0; + +var Z_DEFLATED$1 = 8; + +/* ===========================================================================*/ + + +/** + * class Deflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[deflate]], + * [[deflateRaw]] and [[gzip]]. + **/ + +/* internal + * Deflate.chunks -> Array + * + * Chunks of output data, if [[Deflate#onData]] not overridden. + **/ + +/** + * Deflate.result -> Uint8Array|Array + * + * Compressed result, generated by default [[Deflate#onData]] + * and [[Deflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you + * push a chunk with explicit flush (call [[Deflate#push]] with + * `Z_SYNC_FLUSH` param). + **/ + +/** + * Deflate.err -> Number + * + * Error code after deflate finished. 0 (Z_OK) on success. + * You will not need it in real life, because deflate errors + * are possible only on wrong options or bad `onData` / `onEnd` + * custom handlers. + **/ + +/** + * Deflate.msg -> String + * + * Error message, if [[Deflate.err]] != 0 + **/ + + +/** + * new Deflate(options) + * - options (Object): zlib deflate options. + * + * Creates new deflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `level` + * - `windowBits` + * - `memLevel` + * - `strategy` + * - `dictionary` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw deflate + * - `gzip` (Boolean) - create gzip wrapper + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * - `header` (Object) - custom header for gzip + * - `text` (Boolean) - true if compressed data believed to be text + * - `time` (Number) - modification time, unix timestamp + * - `os` (Number) - operation system code + * - `extra` (Array) - array of bytes with extra data (max 65536) + * - `name` (String) - file name (binary string) + * - `comment` (String) - comment (binary string) + * - `hcrc` (Boolean) - true if header crc should be added + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var deflate = new pako.Deflate({ level: 3}); + * + * deflate.push(chunk1, false); + * deflate.push(chunk2, true); // true -> last chunk + * + * if (deflate.err) { throw new Error(deflate.err); } + * + * console.log(deflate.result); + * ``` + **/ +function Deflate(options) { + if (!(this instanceof Deflate)) return new Deflate(options); + + this.options = require$$0.assign({ + level: Z_DEFAULT_COMPRESSION, + method: Z_DEFLATED$1, + chunkSize: 16384, + windowBits: 15, + memLevel: 8, + strategy: Z_DEFAULT_STRATEGY, + to: '' + }, options || {}); + + var opt = this.options; + + if (opt.raw && (opt.windowBits > 0)) { + opt.windowBits = -opt.windowBits; } - var zstream = ZStream$1; - - var zlib_deflate = deflate_1$1; - - var strings = strings$1; - - var ZStream = zstream; - - var toString$2 = Object.prototype.toString; - - /* Public constants ==========================================================*/ - /* ===========================================================================*/ - - var Z_NO_FLUSH = 0; - var Z_FINISH$1 = 4; - - var Z_OK$1 = 0; - var Z_STREAM_END$1 = 1; - var Z_SYNC_FLUSH = 2; - - var Z_DEFAULT_COMPRESSION = -1; - - var Z_DEFAULT_STRATEGY = 0; - - var Z_DEFLATED$1 = 8; - - /* ===========================================================================*/ - - - /** - * class Deflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[deflate]], - * [[deflateRaw]] and [[gzip]]. - **/ - - /* internal - * Deflate.chunks -> Array - * - * Chunks of output data, if [[Deflate#onData]] not overridden. - **/ - - /** - * Deflate.result -> Uint8Array|Array - * - * Compressed result, generated by default [[Deflate#onData]] - * and [[Deflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you - * push a chunk with explicit flush (call [[Deflate#push]] with - * `Z_SYNC_FLUSH` param). - **/ - - /** - * Deflate.err -> Number - * - * Error code after deflate finished. 0 (Z_OK) on success. - * You will not need it in real life, because deflate errors - * are possible only on wrong options or bad `onData` / `onEnd` - * custom handlers. - **/ - - /** - * Deflate.msg -> String - * - * Error message, if [[Deflate.err]] != 0 - **/ - - - /** - * new Deflate(options) - * - options (Object): zlib deflate options. - * - * Creates new deflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `level` - * - `windowBits` - * - `memLevel` - * - `strategy` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw deflate - * - `gzip` (Boolean) - create gzip wrapper - * - `to` (String) - if equal to 'string', then result will be "binary string" - * (each char code [0..255]) - * - `header` (Object) - custom header for gzip - * - `text` (Boolean) - true if compressed data believed to be text - * - `time` (Number) - modification time, unix timestamp - * - `os` (Number) - operation system code - * - `extra` (Array) - array of bytes with extra data (max 65536) - * - `name` (String) - file name (binary string) - * - `comment` (String) - comment (binary string) - * - `hcrc` (Boolean) - true if header crc should be added - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * var deflate = new pako.Deflate({ level: 3}); - * - * deflate.push(chunk1, false); - * deflate.push(chunk2, true); // true -> last chunk - * - * if (deflate.err) { throw new Error(deflate.err); } - * - * console.log(deflate.result); - * ``` - **/ - function Deflate(options) { - if (!(this instanceof Deflate)) return new Deflate(options); - - this.options = require$$0.assign({ - level: Z_DEFAULT_COMPRESSION, - method: Z_DEFLATED$1, - chunkSize: 16384, - windowBits: 15, - memLevel: 8, - strategy: Z_DEFAULT_STRATEGY, - to: '' - }, options || {}); - - var opt = this.options; - - if (opt.raw && (opt.windowBits > 0)) { - opt.windowBits = -opt.windowBits; - } + else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { + opt.windowBits += 16; + } - else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { - opt.windowBits += 16; - } + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new ZStream(); + this.strm.avail_out = 0; + + var status = zlib_deflate.deflateInit2( + this.strm, + opt.level, + opt.method, + opt.windowBits, + opt.memLevel, + opt.strategy + ); + + if (status !== Z_OK$1) { + throw new Error(msg[status]); + } - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data + if (opt.header) { + zlib_deflate.deflateSetHeader(this.strm, opt.header); + } - this.strm = new ZStream(); - this.strm.avail_out = 0; + if (opt.dictionary) { + var dict; + // Convert data if needed + if (typeof opt.dictionary === 'string') { + // If we need to compress text, change encoding to utf8. + dict = strings.string2buf(opt.dictionary); + } else if (toString$2.call(opt.dictionary) === '[object ArrayBuffer]') { + dict = new Uint8Array(opt.dictionary); + } else { + dict = opt.dictionary; + } - var status = zlib_deflate.deflateInit2( - this.strm, - opt.level, - opt.method, - opt.windowBits, - opt.memLevel, - opt.strategy - ); + status = zlib_deflate.deflateSetDictionary(this.strm, dict); if (status !== Z_OK$1) { throw new Error(msg[status]); } - if (opt.header) { - zlib_deflate.deflateSetHeader(this.strm, opt.header); - } + this._dict_set = true; + } +} - if (opt.dictionary) { - var dict; - // Convert data if needed - if (typeof opt.dictionary === 'string') { - // If we need to compress text, change encoding to utf8. - dict = strings.string2buf(opt.dictionary); - } else if (toString$2.call(opt.dictionary) === '[object ArrayBuffer]') { - dict = new Uint8Array(opt.dictionary); - } else { - dict = opt.dictionary; - } +/** + * Deflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be + * converted to utf8 byte sequence. + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. + * + * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with + * new compressed chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That will flush internal pending buffers and call + * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you + * can use mode Z_SYNC_FLUSH, keeping the compression context. + * + * On fail call [[Deflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * array format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Deflate.prototype.push = function (data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + + if (this.ended) { return false; } + + _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH$1 : Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // If we need to compress text, change encoding to utf8. + strm.input = strings.string2buf(data); + } else if (toString$2.call(data) === '[object ArrayBuffer]') { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } - status = zlib_deflate.deflateSetDictionary(this.strm, dict); + strm.next_in = 0; + strm.avail_in = strm.input.length; - if (status !== Z_OK$1) { - throw new Error(msg[status]); - } + do { + if (strm.avail_out === 0) { + strm.output = new require$$0.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ - this._dict_set = true; + if (status !== Z_STREAM_END$1 && status !== Z_OK$1) { + this.onEnd(status); + this.ended = true; + return false; + } + if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH$1 || _mode === Z_SYNC_FLUSH))) { + if (this.options.to === 'string') { + this.onData(strings.buf2binstring(require$$0.shrinkBuf(strm.output, strm.next_out))); + } else { + this.onData(require$$0.shrinkBuf(strm.output, strm.next_out)); + } } + } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END$1); + + // Finalize on the last chunk. + if (_mode === Z_FINISH$1) { + status = zlib_deflate.deflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === Z_OK$1; } - /** - * Deflate#push(data[, mode]) -> Boolean - * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be - * converted to utf8 byte sequence. - * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with - * new compressed chunks. Returns `true` on success. The last data block must have - * mode Z_FINISH (or `true`). That will flush internal pending buffers and call - * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you - * can use mode Z_SYNC_FLUSH, keeping the compression context. - * - * On fail call [[Deflate#onEnd]] with error code and return false. - * - * We strongly recommend to use `Uint8Array` on input for best speed (output - * array format is detected automatically). Also, don't skip last param and always - * use the same type in your code (boolean or number). That will improve JS speed. - * - * For regular `Array`-s make sure all elements are [0..255]. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Deflate.prototype.push = function (data, mode) { - var strm = this.strm; - var chunkSize = this.options.chunkSize; - var status, _mode; - - if (this.ended) { return false; } - - _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH$1 : Z_NO_FLUSH); - - // Convert data if needed - if (typeof data === 'string') { - // If we need to compress text, change encoding to utf8. - strm.input = strings.string2buf(data); - } else if (toString$2.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } - - strm.next_in = 0; - strm.avail_in = strm.input.length; - - do { - if (strm.avail_out === 0) { - strm.output = new require$$0.Buf8(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } - status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ - - if (status !== Z_STREAM_END$1 && status !== Z_OK$1) { - this.onEnd(status); - this.ended = true; - return false; - } - if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH$1 || _mode === Z_SYNC_FLUSH))) { - if (this.options.to === 'string') { - this.onData(strings.buf2binstring(require$$0.shrinkBuf(strm.output, strm.next_out))); - } else { - this.onData(require$$0.shrinkBuf(strm.output, strm.next_out)); - } - } - } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END$1); - - // Finalize on the last chunk. - if (_mode === Z_FINISH$1) { - status = zlib_deflate.deflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === Z_OK$1; - } - - // callback interim results if Z_SYNC_FLUSH. - if (_mode === Z_SYNC_FLUSH) { - this.onEnd(Z_OK$1); - strm.avail_out = 0; - return true; - } - + // callback interim results if Z_SYNC_FLUSH. + if (_mode === Z_SYNC_FLUSH) { + this.onEnd(Z_OK$1); + strm.avail_out = 0; return true; - }; - - - /** - * Deflate#onData(chunk) -> Void - * - chunk (Uint8Array|Array|String): output data. Type of array depends - * on js engine support. When string output requested, each chunk - * will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Deflate.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Deflate#onEnd(status) -> Void - * - status (Number): deflate status. 0 (Z_OK) on success, - * other if not. - * - * Called once after you tell deflate that the input stream is - * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) - * or if an error happened. By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Deflate.prototype.onEnd = function (status) { - // On success - join - if (status === Z_OK$1) { - if (this.options.to === 'string') { - this.result = this.chunks.join(''); - } else { - this.result = require$$0.flattenChunks(this.chunks); - } - } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * deflate(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to compress. - * - options (Object): zlib deflate options. - * - * Compress `data` with deflate algorithm and `options`. - * - * Supported options are: - * - * - level - * - windowBits - * - memLevel - * - strategy - * - dictionary - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be "binary string" - * (each char code [0..255]) - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); - * - * console.log(pako.deflate(data)); - * ``` - **/ - function deflate$1(input, options) { - var deflator = new Deflate(options); - - deflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (deflator.err) { throw deflator.msg || msg[deflator.err]; } - - return deflator.result; } - - /** - * deflateRaw(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function deflateRaw(input, options) { - options = options || {}; - options.raw = true; - return deflate$1(input, options); + return true; +}; + + +/** + * Deflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): output data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Deflate.prototype.onData = function (chunk) { + this.chunks.push(chunk); +}; + + +/** + * Deflate#onEnd(status) -> Void + * - status (Number): deflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell deflate that the input stream is + * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) + * or if an error happened. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Deflate.prototype.onEnd = function (status) { + // On success - join + if (status === Z_OK$1) { + if (this.options.to === 'string') { + this.result = this.chunks.join(''); + } else { + this.result = require$$0.flattenChunks(this.chunks); + } } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * deflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * Compress `data` with deflate algorithm and `options`. + * + * Supported options are: + * + * - level + * - windowBits + * - memLevel + * - strategy + * - dictionary + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); + * + * console.log(pako.deflate(data)); + * ``` + **/ +function deflate$1(input, options) { + var deflator = new Deflate(options); + + deflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (deflator.err) { throw deflator.msg || msg[deflator.err]; } + + return deflator.result; +} - /** - * gzip(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to compress. - * - options (Object): zlib deflate options. - * - * The same as [[deflate]], but create gzip wrapper instead of - * deflate one. - **/ - function gzip(input, options) { - options = options || {}; - options.gzip = true; - return deflate$1(input, options); - } +/** + * deflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function deflateRaw(input, options) { + options = options || {}; + options.raw = true; + return deflate$1(input, options); +} - var Deflate_1 = Deflate; - var deflate_2 = deflate$1; - var deflateRaw_1 = deflateRaw; - var gzip_1 = gzip; +/** + * gzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but create gzip wrapper instead of + * deflate one. + **/ +function gzip(input, options) { + options = options || {}; + options.gzip = true; + return deflate$1(input, options); +} - var deflate_1 = { - Deflate: Deflate_1, - deflate: deflate_2, - deflateRaw: deflateRaw_1, - gzip: gzip_1 - }; - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - // See state defs from inflate.js - var BAD$1 = 30; /* got a data error -- remain here until reset */ - var TYPE$2 = 12; /* i: waiting for type bits, including last-flag bit */ +var Deflate_1 = Deflate; +var deflate_2 = deflate$1; +var deflateRaw_1 = deflateRaw; +var gzip_1 = gzip; + +var deflate_1 = { + Deflate: Deflate_1, + deflate: deflate_2, + deflateRaw: deflateRaw_1, + gzip: gzip_1 +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +// See state defs from inflate.js +var BAD$1 = 30; /* got a data error -- remain here until reset */ +var TYPE$2 = 12; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +var inffast = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ +//#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + // Use `s_window` instead `window`, avoid conflict with instrumentation tools + var s_window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + s_window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } - /* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state.mode === LEN - strm.avail_in >= 6 - strm.avail_out >= 258 - start >= strm.avail_out - state.bits < 8 - - On return, state.mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm.avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm.avail_out >= 258 for each loop to avoid checking for - output space. - */ - var inffast = function inflate_fast(strm, start) { - var state; - var _in; /* local strm.input */ - var last; /* have enough input while in < last */ - var _out; /* local strm.output */ - var beg; /* inflate()'s initial strm.output */ - var end; /* while out < end, enough space available */ - //#ifdef INFLATE_STRICT - var dmax; /* maximum distance from zlib header */ - //#endif - var wsize; /* window size or zero if not using window */ - var whave; /* valid bytes in the window */ - var wnext; /* window write index */ - // Use `s_window` instead `window`, avoid conflict with instrumentation tools - var s_window; /* allocated sliding window, if wsize != 0 */ - var hold; /* local strm.hold */ - var bits; /* local strm.bits */ - var lcode; /* local strm.lencode */ - var dcode; /* local strm.distcode */ - var lmask; /* mask for first level of length codes */ - var dmask; /* mask for first level of distance codes */ - var here; /* retrieved table entry */ - var op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - var len; /* match length, unused bytes */ - var dist; /* match distance */ - var from; /* where to copy match from */ - var from_source; - - - var input, output; // JS specific, because we have no pointers - - /* copy state to local variables */ - state = strm.state; - //here = state.here; - _in = strm.next_in; - input = strm.input; - last = _in + (strm.avail_in - 5); - _out = strm.next_out; - output = strm.output; - beg = _out - (start - strm.avail_out); - end = _out + (strm.avail_out - 257); - //#ifdef INFLATE_STRICT - dmax = state.dmax; - //#endif - wsize = state.wsize; - whave = state.whave; - wnext = state.wnext; - s_window = state.window; - hold = state.hold; - bits = state.bits; - lcode = state.lencode; - dcode = state.distcode; - lmask = (1 << state.lenbits) - 1; - dmask = (1 << state.distbits) - 1; - - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - - top: - do { - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; } - - here = lcode[hold & lmask]; - - dolen: - for (;;) { // Goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - if (op === 0) { /* literal */ - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - output[_out++] = here & 0xffff/*here.val*/; + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; } - else if (op & 16) { /* length base */ - len = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ - if (op) { + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ if (bits < op) { hold += input[_in++] << bits; bits += 8; - } - len += hold & ((1 << op) - 1); - hold >>>= op; - bits -= op; - } - //Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += input[_in++] << bits; - bits += 8; - hold += input[_in++] << bits; - bits += 8; - } - here = dcode[hold & dmask]; - - dodist: - for (;;) { // goto emulation - op = here >>> 24/*here.bits*/; - hold >>>= op; - bits -= op; - op = (here >>> 16) & 0xff/*here.op*/; - - if (op & 16) { /* distance base */ - dist = here & 0xffff/*here.val*/; - op &= 15; /* number of extra bits */ if (bits < op) { hold += input[_in++] << bits; bits += 8; - if (bits < op) { - hold += input[_in++] << bits; - bits += 8; - } - } - dist += hold & ((1 << op) - 1); - //#ifdef INFLATE_STRICT - if (dist > dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1; - break top; } - //#endif - hold >>>= op; - bits -= op; - //Tracevv((stderr, "inflate: distance %u\n", dist)); - op = _out - beg; /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD$1; - break top; - } - - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // if (len <= op - whave) { - // do { - // output[_out++] = 0; - // } while (--len); - // continue top; - // } - // len -= op - whave; - // do { - // output[_out++] = 0; - // } while (--op > whave); - // if (op === 0) { - // from = _out - dist; - // do { - // output[_out++] = output[from++]; - // } while (--len); - // continue top; - // } - //#endif - } - from = 0; // window index - from_source = s_window; - if (wnext === 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD$1; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD$1; + break top; } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = 0; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - output[_out++] = s_window[from++]; - } while (--op); - from = _out - dist; /* rest from output */ - from_source = output; - } - } + +// (!) This block is disabled in zlib defaults, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = s_window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; len -= op; do { output[_out++] = s_window[from++]; } while (--op); - from = _out - dist; /* rest from output */ + from = _out - dist; /* rest from output */ from_source = output; } } - while (len > 2) { - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - output[_out++] = from_source[from++]; - len -= 3; + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = s_window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; } - if (len) { + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { output[_out++] = from_source[from++]; - if (len > 1) { - output[_out++] = from_source[from++]; - } } } - else { - from = _out - dist; /* copy direct from output */ - do { /* minimum length is three */ - output[_out++] = output[from++]; - output[_out++] = output[from++]; - output[_out++] = output[from++]; - len -= 3; - } while (len > 2); - if (len) { + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { output[_out++] = output[from++]; - if (len > 1) { - output[_out++] = output[from++]; - } } } } - else if ((op & 64) === 0) { /* 2nd level distance code */ - here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dodist; - } - else { - strm.msg = 'invalid distance code'; - state.mode = BAD$1; - break top; - } - - break; // need to emulate goto via "continue" } - } - else if ((op & 64) === 0) { /* 2nd level length code */ - here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; - continue dolen; - } - else if (op & 32) { /* end-of-block */ - //Tracevv((stderr, "inflate: end of block\n")); - state.mode = TYPE$2; - break top; - } - else { - strm.msg = 'invalid literal/length code'; - state.mode = BAD$1; - break top; - } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD$1; + break top; + } - break; // need to emulate goto via "continue" + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE$2; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD$1; + break top; } - } while (_in < last && _out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - _in -= len; - bits -= len << 3; - hold &= (1 << bits) - 1; - - /* update state and return */ - strm.next_in = _in; - strm.next_out = _out; - strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); - strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); - state.hold = hold; - state.bits = bits; - return; - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - - - var MAXBITS = 15; - var ENOUGH_LENS$1 = 852; - var ENOUGH_DISTS$1 = 592; - //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - var CODES$1 = 0; - var LENS$1 = 1; - var DISTS$1 = 2; - - var lbase = [ /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - ]; - - var lext = [ /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 - ]; - - var dbase = [ /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0 - ]; - - var dext = [ /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64 - ]; - - var inftrees = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) - { - var bits = opts.bits; - //here = opts.here; /* table entry for duplication */ - - var len = 0; /* a code's length in bits */ - var sym = 0; /* index of code symbols */ - var min = 0, max = 0; /* minimum and maximum code lengths */ - var root = 0; /* number of index bits for root table */ - var curr = 0; /* number of index bits for current table */ - var drop = 0; /* code bits to drop for sub-table */ - var left = 0; /* number of prefix codes available */ - var used = 0; /* code entries in table used */ - var huff = 0; /* Huffman code */ - var incr; /* for incrementing code, index */ - var fill; /* index for replicating entries */ - var low; /* low bits for current root entry */ - var mask; /* mask for low root bits */ - var next; /* next available space in table */ - var base = null; /* base value table to use */ - var base_index = 0; - // var shoextra; /* extra bits table to use */ - var end; /* use base and extra for symbol > end */ - var count = new require$$0.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ - var offs = new require$$0.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ - var extra = null; - var extra_index = 0; - - var here_bits, here_op, here_val; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) { - count[len] = 0; - } - for (sym = 0; sym < codes; sym++) { - count[lens[lens_index + sym]]++; - } - /* bound code lengths, force root to be within code lengths */ - root = bits; - for (max = MAXBITS; max >= 1; max--) { - if (count[max] !== 0) { break; } + break; // need to emulate goto via "continue" } - if (root > max) { - root = max; - } - if (max === 0) { /* no symbols to code at all */ - //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ - //table.bits[opts.table_index] = 1; //here.bits = (var char)1; - //table.val[opts.table_index++] = 0; //here.val = (var short)0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + + + +var MAXBITS = 15; +var ENOUGH_LENS$1 = 852; +var ENOUGH_DISTS$1 = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var CODES$1 = 0; +var LENS$1 = 1; +var DISTS$1 = 2; + +var lbase = [ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]; + +var lext = [ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]; + +var dbase = [ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]; + +var dext = [ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]; + +var inftrees = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) +{ + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; +// var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new require$$0.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new require$$0.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ - //table.op[opts.table_index] = 64; - //table.bits[opts.table_index] = 1; - //table.val[opts.table_index++] = 0; - table[table_index++] = (1 << 24) | (64 << 16) | 0; + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } - opts.bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) { - if (count[min] !== 0) { break; } - } - if (root < min) { - root = min; - } + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) { - return -1; - } /* over-subscribed */ - } - if (left > 0 && (type === CODES$1 || max !== 1)) { - return -1; /* incomplete set */ - } - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) { - offs[len + 1] = offs[len] + count[len]; - } + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) { - if (lens[lens_index + sym] !== 0) { - work[offs[lens[lens_index + sym]]++] = sym; - } - } + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES$1 || max !== 1)) { + return -1; /* incomplete set */ + } - /* set up for code type */ - // poor man optimization - use if-else instead of switch, - // to avoid deopts in old v8 - if (type === CODES$1) { - base = extra = work; /* dummy value--not used */ - end = 19; - - } else if (type === LENS$1) { - base = lbase; - base_index -= 257; - extra = lext; - extra_index -= 257; - end = 256; - - } else { /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } - /* initialize opts for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = table_index; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = -1; /* trigger new sub-table when len > root */ - used = 1 << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type === LENS$1 && used > ENOUGH_LENS$1) || - (type === DISTS$1 && used > ENOUGH_DISTS$1)) { - return 1; + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; } + } - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here_bits = len - drop; - if (work[sym] < end) { - here_op = 0; - here_val = work[sym]; - } - else if (work[sym] > end) { - here_op = extra[extra_index + work[sym]]; - here_val = base[base_index + work[sym]]; - } - else { - here_op = 32 + 64; /* end of block */ - here_val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1 << (len - drop); - fill = 1 << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; - } while (fill !== 0); - - /* backwards increment the len-bit code huff */ - incr = 1 << (len - 1); - while (huff & incr) { - incr >>= 1; - } - if (incr !== 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--count[len] === 0) { - if (len === max) { break; } - len = lens[lens_index + work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) !== low) { - /* if first time, transition to sub-tables */ - if (drop === 0) { - drop = root; - } + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = 1 << curr; - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) { break; } - curr++; - left <<= 1; - } + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES$1) { + base = extra = work; /* dummy value--not used */ + end = 19; + + } else if (type === LENS$1) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + + } else { /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } - /* check for enough space */ - used += 1 << curr; - if ((type === LENS$1 && used > ENOUGH_LENS$1) || - (type === DISTS$1 && used > ENOUGH_DISTS$1)) { - return 1; - } + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS$1 && used > ENOUGH_LENS$1) || + (type === DISTS$1 && used > ENOUGH_DISTS$1)) { + return 1; + } - /* point entry in root table to sub-table */ - low = huff & mask; - /*table.op[low] = curr; - table.bits[low] = root; - table.val[low] = next - opts.table_index;*/ - table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; - } + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff !== 0) { - //table.op[next + huff] = 64; /* invalid code marker */ - //table.bits[next + huff] = len - drop; - //table.val[next + huff] = 0; - table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; } - /* set return parameters */ - //opts.table_index += used; - opts.bits = root; - return 0; - }; + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } - var inflate_fast = inffast; + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } - var inflate_table = inftrees; + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + /* check for enough space */ + used += 1 << curr; + if ((type === LENS$1 && used > ENOUGH_LENS$1) || + (type === DISTS$1 && used > ENOUGH_DISTS$1)) { + return 1; + } + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + +var inflate_fast = inffast; + +var inflate_table = inftrees; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + + + + + + + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +//var Z_NO_FLUSH = 0; +//var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +//var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + +/* The deflate compression method */ +var Z_DEFLATED = 8; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +var HEAD = 1; /* i: waiting for magic header */ +var FLAGS = 2; /* i: waiting for method and flags (gzip) */ +var TIME = 3; /* i: waiting for modification time (gzip) */ +var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ +var EXLEN = 5; /* i: waiting for extra length (gzip) */ +var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ +var NAME = 7; /* i: waiting for end of file name (gzip) */ +var COMMENT = 8; /* i: waiting for end of comment (gzip) */ +var HCRC = 9; /* i: waiting for header crc (gzip) */ +var DICTID = 10; /* i: waiting for dictionary check value */ +var DICT = 11; /* waiting for inflateSetDictionary() call */ +var TYPE$1 = 12; /* i: waiting for type bits, including last-flag bit */ +var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ +var STORED = 14; /* i: waiting for stored size (length and complement) */ +var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ +var COPY = 16; /* i/o: waiting for input or output to copy stored block */ +var TABLE = 17; /* i: waiting for dynamic block table lengths */ +var LENLENS = 18; /* i: waiting for code length code lengths */ +var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ +var LEN_ = 20; /* i: same as LEN below, but only first time in */ +var LEN = 21; /* i: waiting for length/lit/eob code */ +var LENEXT = 22; /* i: waiting for length extra bits */ +var DIST = 23; /* i: waiting for distance code */ +var DISTEXT = 24; /* i: waiting for distance extra bits */ +var MATCH = 25; /* o: waiting for output space to copy string */ +var LIT = 26; /* o: waiting for output space to write literal */ +var CHECK = 27; /* i: waiting for 32-bit check value */ +var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ +var DONE = 29; /* finished check, done -- remain here until reset */ +var BAD = 30; /* got a data error -- remain here until reset */ +var MEM = 31; /* got an inflate() memory error -- remain here until reset */ +var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_WBITS = MAX_WBITS; + + +function zswap32(q) { + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +} +function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new require$$0.Buf16(320); /* temporary storage for code lengths */ + this.work = new require$$0.Buf16(288); /* work area for code table building */ - var CODES = 0; - var LENS = 1; - var DISTS = 2; + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} - /* Public constants ==========================================================*/ - /* ===========================================================================*/ +function inflateResetKeep(strm) { + var state; + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new require$$0.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new require$$0.Buf32(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} - /* Allowed flush values; see deflate() and inflate() below for details */ - //var Z_NO_FLUSH = 0; - //var Z_PARTIAL_FLUSH = 1; - //var Z_SYNC_FLUSH = 2; - //var Z_FULL_FLUSH = 3; - var Z_FINISH = 4; - var Z_BLOCK = 5; - var Z_TREES = 6; +function inflateReset(strm) { + var state; + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - var Z_OK = 0; - var Z_STREAM_END = 1; - var Z_NEED_DICT = 2; - //var Z_ERRNO = -1; - var Z_STREAM_ERROR = -2; - var Z_DATA_ERROR = -3; - var Z_MEM_ERROR = -4; - var Z_BUF_ERROR = -5; - //var Z_VERSION_ERROR = -6; +} - /* The deflate compression method */ - var Z_DEFLATED = 8; - - - /* STATES ====================================================================*/ - /* ===========================================================================*/ - - - var HEAD = 1; /* i: waiting for magic header */ - var FLAGS = 2; /* i: waiting for method and flags (gzip) */ - var TIME = 3; /* i: waiting for modification time (gzip) */ - var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ - var EXLEN = 5; /* i: waiting for extra length (gzip) */ - var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ - var NAME = 7; /* i: waiting for end of file name (gzip) */ - var COMMENT = 8; /* i: waiting for end of comment (gzip) */ - var HCRC = 9; /* i: waiting for header crc (gzip) */ - var DICTID = 10; /* i: waiting for dictionary check value */ - var DICT = 11; /* waiting for inflateSetDictionary() call */ - var TYPE$1 = 12; /* i: waiting for type bits, including last-flag bit */ - var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ - var STORED = 14; /* i: waiting for stored size (length and complement) */ - var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ - var COPY = 16; /* i/o: waiting for input or output to copy stored block */ - var TABLE = 17; /* i: waiting for dynamic block table lengths */ - var LENLENS = 18; /* i: waiting for code length code lengths */ - var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ - var LEN_ = 20; /* i: same as LEN below, but only first time in */ - var LEN = 21; /* i: waiting for length/lit/eob code */ - var LENEXT = 22; /* i: waiting for length extra bits */ - var DIST = 23; /* i: waiting for distance code */ - var DISTEXT = 24; /* i: waiting for distance extra bits */ - var MATCH = 25; /* o: waiting for output space to copy string */ - var LIT = 26; /* o: waiting for output space to write literal */ - var CHECK = 27; /* i: waiting for 32-bit check value */ - var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ - var DONE = 29; /* finished check, done -- remain here until reset */ - var BAD = 30; /* got a data error -- remain here until reset */ - var MEM = 31; /* got an inflate() memory error -- remain here until reset */ - var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ - - /* ===========================================================================*/ - - - - var ENOUGH_LENS = 852; - var ENOUGH_DISTS = 592; - //var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); - - var MAX_WBITS = 15; - /* 32K LZ77 window */ - var DEF_WBITS = MAX_WBITS; - - - function zswap32(q) { - return (((q >>> 24) & 0xff) + - ((q >>> 8) & 0xff00) + - ((q & 0xff00) << 8) + - ((q & 0xff) << 24)); - } +function inflateReset2(strm, windowBits) { + var wrap; + var state; + /* get the state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; - function InflateState() { - this.mode = 0; /* current inflate mode */ - this.last = false; /* true if processing last block */ - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ - this.havedict = false; /* true if dictionary provided */ - this.flags = 0; /* gzip header method and flags (0 if zlib) */ - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ - this.check = 0; /* protected copy of check value */ - this.total = 0; /* protected copy of output count */ - // TODO: may be {} - this.head = null; /* where to save gzip header information */ - - /* sliding window */ - this.wbits = 0; /* log base 2 of requested window size */ - this.wsize = 0; /* window size or zero if not using window */ - this.whave = 0; /* valid bytes in the window */ - this.wnext = 0; /* window write index */ - this.window = null; /* allocated sliding window, if needed */ - - /* bit accumulator */ - this.hold = 0; /* input bit accumulator */ - this.bits = 0; /* number of bits in "in" */ - - /* for string and stored block copying */ - this.length = 0; /* literal or length of data to copy */ - this.offset = 0; /* distance back to copy string from */ - - /* for table and code decoding */ - this.extra = 0; /* extra bits needed */ - - /* fixed and dynamic code tables */ - this.lencode = null; /* starting table for length/literal codes */ - this.distcode = null; /* starting table for distance codes */ - this.lenbits = 0; /* index bits for lencode */ - this.distbits = 0; /* index bits for distcode */ - - /* dynamic table building */ - this.ncode = 0; /* number of code length code lengths */ - this.nlen = 0; /* number of length code lengths */ - this.ndist = 0; /* number of distance code lengths */ - this.have = 0; /* number of code lengths in lens[] */ - this.next = null; /* next available space in codes[] */ - - this.lens = new require$$0.Buf16(320); /* temporary storage for code lengths */ - this.work = new require$$0.Buf16(288); /* work area for code table building */ - - /* - because we don't have pointers in js, we use lencode and distcode directly - as buffers so we don't need codes - */ - //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ - this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ - this.distdyn = null; /* dynamic table for distance codes (JS specific) */ - this.sane = 0; /* if false, allow invalid distance too far */ - this.back = 0; /* bits back of last unprocessed length/lit */ - this.was = 0; /* initial length of match */ + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; } - - function inflateResetKeep(strm) { - var state; - - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - strm.total_in = strm.total_out = state.total = 0; - strm.msg = ''; /*Z_NULL*/ - if (state.wrap) { /* to support ill-conceived Java test suite */ - strm.adler = state.wrap & 1; + else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; } - state.mode = HEAD; - state.last = 0; - state.havedict = 0; - state.dmax = 32768; - state.head = null/*Z_NULL*/; - state.hold = 0; - state.bits = 0; - //state.lencode = state.distcode = state.next = state.codes; - state.lencode = state.lendyn = new require$$0.Buf32(ENOUGH_LENS); - state.distcode = state.distdyn = new require$$0.Buf32(ENOUGH_DISTS); - - state.sane = 1; - state.back = -1; - //Tracev((stderr, "inflate: reset\n")); - return Z_OK; } - function inflateReset(strm) { - var state; - - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - state.wsize = 0; - state.whave = 0; - state.wnext = 0; - return inflateResetKeep(strm); - + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; } - - function inflateReset2(strm, windowBits) { - var wrap; - var state; - - /* get the state */ - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; - if (windowBits < 48) { - windowBits &= 15; - } - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) { - return Z_STREAM_ERROR; - } - if (state.window !== null && state.wbits !== windowBits) { - state.window = null; - } - - /* update state and reset the rest of it */ - state.wrap = wrap; - state.wbits = windowBits; - return inflateReset(strm); + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; } - function inflateInit2(strm, windowBits) { - var ret; - var state; + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +} - if (!strm) { return Z_STREAM_ERROR; } - //strm.msg = Z_NULL; /* in case we return an error */ +function inflateInit2(strm, windowBits) { + var ret; + var state; - state = new InflateState(); + if (!strm) { return Z_STREAM_ERROR; } + //strm.msg = Z_NULL; /* in case we return an error */ - //if (state === Z_NULL) return Z_MEM_ERROR; - //Tracev((stderr, "inflate: allocated\n")); - strm.state = state; - state.window = null/*Z_NULL*/; - ret = inflateReset2(strm, windowBits); - if (ret !== Z_OK) { - strm.state = null/*Z_NULL*/; - } - return ret; - } + state = new InflateState(); - function inflateInit(strm) { - return inflateInit2(strm, DEF_WBITS); + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null/*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null/*Z_NULL*/; } + return ret; +} +function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); +} - /* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ - var virgin = true; - var lenfix, distfix; // We have no pointers in JS, so keep tables separate +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +var virgin = true; - function fixedtables(state) { - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - var sym; +var lenfix, distfix; // We have no pointers in JS, so keep tables separate - lenfix = new require$$0.Buf32(512); - distfix = new require$$0.Buf32(32); +function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; - /* literal/length table */ - sym = 0; - while (sym < 144) { state.lens[sym++] = 8; } - while (sym < 256) { state.lens[sym++] = 9; } - while (sym < 280) { state.lens[sym++] = 7; } - while (sym < 288) { state.lens[sym++] = 8; } + lenfix = new require$$0.Buf32(512); + distfix = new require$$0.Buf32(32); - inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); + /* literal/length table */ + sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } - /* distance table */ - sym = 0; - while (sym < 32) { state.lens[sym++] = 5; } + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 }); - inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } - /* do this just once */ - virgin = false; - } + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 }); - state.lencode = lenfix; - state.lenbits = 9; - state.distcode = distfix; - state.distbits = 5; + /* do this just once */ + virgin = false; } + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +} - /* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ - function updatewindow(strm, src, end, copy) { - var dist; - var state = strm.state; - /* if it hasn't been done already, allocate space for the window */ - if (state.window === null) { - state.wsize = 1 << state.wbits; - state.wnext = 0; - state.whave = 0; +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new require$$0.Buf8(state.wsize); + } - state.window = new require$$0.Buf8(state.wsize); + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + require$$0.arraySet(state.window, src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state.wsize) { - require$$0.arraySet(state.window, src, end - state.wsize, state.wsize, 0); - state.wnext = 0; + //zmemcpy(state->window + state->wnext, end - copy, dist); + require$$0.arraySet(state.window, src, end - copy, dist, state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + require$$0.arraySet(state.window, src, end - copy, copy, 0); + state.wnext = copy; state.whave = state.wsize; } else { - dist = state.wsize - state.wnext; - if (dist > copy) { - dist = copy; - } - //zmemcpy(state->window + state->wnext, end - copy, dist); - require$$0.arraySet(state.window, src, end - copy, dist, state.wnext); - copy -= dist; - if (copy) { - //zmemcpy(state->window, end - copy, copy); - require$$0.arraySet(state.window, src, end - copy, copy, 0); - state.wnext = copy; - state.whave = state.wsize; - } - else { - state.wnext += dist; - if (state.wnext === state.wsize) { state.wnext = 0; } - if (state.whave < state.wsize) { state.whave += dist; } - } + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } } - return 0; } + return 0; +} - function inflate$2(strm, flush) { - var state; - var input, output; // input/output buffers - var next; /* next input INDEX */ - var put; /* next output INDEX */ - var have, left; /* available input and output */ - var hold; /* bit buffer */ - var bits; /* bits in bit buffer */ - var _in, _out; /* save starting available input and output */ - var copy; /* number of stored or match bytes to copy */ - var from; /* where to copy match bytes from */ - var from_source; - var here = 0; /* current decoding table entry */ - var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) - //var last; /* parent table entry */ - var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) - var len; /* length to copy for repeats, bits to drop */ - var ret; /* return code */ - var hbuf = new require$$0.Buf8(4); /* buffer for gzip header crc calculation */ - var opts; - - var n; // temporary var for NEED_BITS - - var order = /* permutation of code lengths */ - [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; - - - if (!strm || !strm.state || !strm.output || - (!strm.input && strm.avail_in !== 0)) { - return Z_STREAM_ERROR; - } +function inflate$2(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new require$$0.Buf8(4); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = /* permutation of code lengths */ + [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ]; + + + if (!strm || !strm.state || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR; + } - state = strm.state; - if (state.mode === TYPE$1) { state.mode = TYPEDO; } /* skip check */ - - - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - _in = have; - _out = left; - ret = Z_OK; - - inf_leave: // goto emulation - for (;;) { - switch (state.mode) { - case HEAD: - if (state.wrap === 0) { - state.mode = TYPEDO; - break; - } - //=== NEEDBITS(16); - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } + state = strm.state; + if (state.mode === TYPE$1) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); //===// - if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ - state.check = 0/*crc32(0L, Z_NULL, 0)*/; - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = FLAGS; - break; - } - state.flags = 0; /* expect zlib header */ - if (state.head) { - state.head.done = false; - } - if (!(state.wrap & 1) || /* check if zlib header allowed */ - (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { - strm.msg = 'incorrect header check'; - state.mode = BAD; - break; - } - if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - len = (hold & 0x0f)/*BITS(4)*/ + 8; - if (state.wbits === 0) { - state.wbits = len; - } - else if (len > state.wbits) { - strm.msg = 'invalid window size'; - state.mode = BAD; - break; - } - state.dmax = 1 << len; - //Tracev((stderr, "inflate: zlib header ok\n")); - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = hold & 0x200 ? DICTID : TYPE$1; //=== INITBITS(); hold = 0; bits = 0; //===// + state.mode = FLAGS; break; - case FLAGS: - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.flags = hold; - if ((state.flags & 0xff) !== Z_DEFLATED) { - strm.msg = 'unknown compression method'; - state.mode = BAD; - break; - } - if (state.flags & 0xe000) { - strm.msg = 'unknown header flags set'; - state.mode = BAD; - break; - } - if (state.head) { - state.head.text = ((hold >> 8) & 1); - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = TIME; - /* falls through */ - case TIME: - //=== NEEDBITS(32); */ - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + else if (len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE$1; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); //===// - if (state.head) { - state.head.time = hold; - } - if (state.flags & 0x0200) { - //=== CRC4(state.check, hold) - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - hbuf[2] = (hold >>> 16) & 0xff; - hbuf[3] = (hold >>> 24) & 0xff; - state.check = crc32(state.check, hbuf, 4, 0); - //=== - } - //=== INITBITS(); - hold = 0; - bits = 0; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); //===// - state.mode = OS; - /* falls through */ - case OS: + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { //=== NEEDBITS(16); */ while (bits < 16) { if (have === 0) { break inf_leave; } @@ -8008,9 +7476,9 @@ var serviceContext = (function (shared, vue) { bits += 8; } //===// + state.length = hold; if (state.head) { - state.head.xflags = (hold & 0xff); - state.head.os = (hold >> 8); + state.head.extra_len = hold; } if (state.flags & 0x0200) { //=== CRC2(state.check, hold); @@ -8023,198 +7491,305 @@ var serviceContext = (function (shared, vue) { hold = 0; bits = 0; //===// - state.mode = EXLEN; - /* falls through */ - case EXLEN: - if (state.flags & 0x0400) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length = hold; + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { if (state.head) { - state.head.extra_len = hold; - } - if (state.flags & 0x0200) { - //=== CRC2(state.check, hold); - hbuf[0] = hold & 0xff; - hbuf[1] = (hold >>> 8) & 0xff; - state.check = crc32(state.check, hbuf, 2, 0); - //===// - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - } - else if (state.head) { - state.head.extra = null/*Z_NULL*/; - } - state.mode = EXTRA; - /* falls through */ - case EXTRA: - if (state.flags & 0x0400) { - copy = state.length; - if (copy > have) { copy = have; } - if (copy) { - if (state.head) { - len = state.head.extra_len - state.length; - if (!state.head.extra) { - // Use untyped array for more convenient processing later - state.head.extra = new Array(state.head.extra_len); - } - require$$0.arraySet( - state.head.extra, - input, - next, - // extra field is limited to 65536 bytes - // - no need for additional size check - copy, - /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ - len - ); - //zmemcpy(state.head.extra + len, next, - // len + copy > state.head.extra_max ? - // state.head.extra_max - len : copy); + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more convenient processing later + state.head.extra = new Array(state.head.extra_len); } - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); - } - have -= copy; - next += copy; - state.length -= copy; + require$$0.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); } - if (state.length) { break inf_leave; } - } - state.length = 0; - state.mode = NAME; - /* falls through */ - case NAME: - if (state.flags & 0x0800) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - // TODO: 2 or 1 bytes? - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.name_max*/)) { - state.head.name += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 0x0200) { state.check = crc32(state.check, input, copy, next); } have -= copy; next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.name = null; + state.length -= copy; } - state.length = 0; - state.mode = COMMENT; - /* falls through */ - case COMMENT: - if (state.flags & 0x1000) { - if (have === 0) { break inf_leave; } - copy = 0; - do { - len = input[next + copy++]; - /* use constant limit because in js we should not preallocate memory */ - if (state.head && len && - (state.length < 65536 /*state.head.comm_max*/)) { - state.head.comment += String.fromCharCode(len); - } - } while (len && copy < have); - if (state.flags & 0x0200) { - state.check = crc32(state.check, input, copy, next); + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); } - have -= copy; - next += copy; - if (len) { break inf_leave; } - } - else if (state.head) { - state.head.comment = null; - } - state.mode = HCRC; - /* falls through */ - case HCRC: + } while (len && copy < have); + if (state.flags & 0x0200) { - //=== NEEDBITS(16); */ - while (bits < 16) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (hold !== (state.check & 0xffff)) { - strm.msg = 'header crc mismatch'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// + state.check = crc32(state.check, input, copy, next); } - if (state.head) { - state.head.hcrc = ((state.flags >> 9) & 1); - state.head.done = true; + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); } - strm.adler = state.check = 0; - state.mode = TYPE$1; - break; - case DICTID: - //=== NEEDBITS(32); */ - while (bits < 32) { + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { if (have === 0) { break inf_leave; } have--; hold += input[next++] << bits; bits += 8; } //===// - strm.adler = state.check = zswap32(hold); + if (hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } //=== INITBITS(); hold = 0; bits = 0; //===// - state.mode = DICT; - /* falls through */ - case DICT: - if (state.havedict === 0) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - return Z_NEED_DICT; - } - strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; - state.mode = TYPE$1; - /* falls through */ - case TYPE$1: - if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } - /* falls through */ - case TYPEDO: - if (state.last) { - //--- BYTEBITS() ---// - hold >>>= bits & 7; - bits -= bits & 7; - //---// - state.mode = CHECK; + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0; + state.mode = TYPE$1; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = zswap32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE$1; + /* falls through */ + case TYPE$1: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; break; - } - //=== NEEDBITS(3); */ + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + require$$0.arraySet(output, input, next, copy, put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE$1; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); while (bits < 3) { if (have === 0) { break inf_leave; } have--; @@ -8222,358 +7797,243 @@ var serviceContext = (function (shared, vue) { bits += 8; } //===// - state.last = (hold & 0x01)/*BITS(1)*/; - //--- DROPBITS(1) ---// - hold >>>= 1; - bits -= 1; - //---// - - switch ((hold & 0x03)/*BITS(2)*/) { - case 0: /* stored block */ - //Tracev((stderr, "inflate: stored block%s\n", - // state.last ? " (last)" : "")); - state.mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - //Tracev((stderr, "inflate: fixed codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = LEN_; /* decode codes */ - if (flush === Z_TREES) { - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - break inf_leave; - } - break; - case 2: /* dynamic block */ - //Tracev((stderr, "inflate: dynamic codes block%s\n", - // state.last ? " (last)" : "")); - state.mode = TABLE; - break; - case 3: - strm.msg = 'invalid block type'; - state.mode = BAD; - } - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = { bits: state.lenbits }; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; break; - case STORED: - //--- BYTEBITS() ---// /* go to byte boundary */ - hold >>>= bits & 7; - bits -= bits & 7; - //---// - //=== NEEDBITS(32); */ - while (bits < 32) { + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// if (have === 0) { break inf_leave; } have--; hold += input[next++] << bits; bits += 8; - } - //===// - if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { - strm.msg = 'invalid stored block lengths'; - state.mode = BAD; - break; - } - state.length = hold & 0xffff; - //Tracev((stderr, "inflate: stored length %u\n", - // state.length)); - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - state.mode = COPY_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case COPY_: - state.mode = COPY; - /* falls through */ - case COPY: - copy = state.length; - if (copy) { - if (copy > have) { copy = have; } - if (copy > left) { copy = left; } - if (copy === 0) { break inf_leave; } - //--- zmemcpy(put, next, copy); --- - require$$0.arraySet(output, input, next, copy, put); //---// - have -= copy; - next += copy; - left -= copy; - put += copy; - state.length -= copy; - break; - } - //Tracev((stderr, "inflate: stored end\n")); - state.mode = TYPE$1; - break; - case TABLE: - //=== NEEDBITS(14); */ - while (bits < 14) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; } - //===// - state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; - //--- DROPBITS(5) ---// - hold >>>= 5; - bits -= 5; - //---// - state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; - //--- DROPBITS(4) ---// - hold >>>= 4; - bits -= 4; - //---// - //#ifndef PKZIP_BUG_WORKAROUND - if (state.nlen > 286 || state.ndist > 30) { - strm.msg = 'too many length or distance symbols'; - state.mode = BAD; - break; - } - //#endif - //Tracev((stderr, "inflate: table sizes ok\n")); - state.have = 0; - state.mode = LENLENS; - /* falls through */ - case LENLENS: - while (state.have < state.ncode) { - //=== NEEDBITS(3); - while (bits < 3) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; //---// + state.lens[state.have++] = here_val; } - while (state.have < 19) { - state.lens[order[state.have++]] = 0; - } - // We have separate tables & no pointers. 2 commented lines below not needed. - //state.next = state.codes; - //state.lencode = state.next; - // Switch to use dynamic table - state.lencode = state.lendyn; - state.lenbits = 7; - - opts = { bits: state.lenbits }; - ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); - state.lenbits = opts.bits; - - if (ret) { - strm.msg = 'invalid code lengths set'; - state.mode = BAD; - break; - } - //Tracev((stderr, "inflate: code lengths ok\n")); - state.have = 0; - state.mode = CODELENS; - /* falls through */ - case CODELENS: - while (state.have < state.nlen + state.ndist) { - for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - if (here_val < 16) { + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// //--- DROPBITS(here.bits) ---// hold >>>= here_bits; bits -= here_bits; //---// - state.lens[state.have++] = here_val; - } - else { - if (here_val === 16) { - //=== NEEDBITS(here.bits + 2); - n = here_bits + 2; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - if (state.have === 0) { - strm.msg = 'invalid bit length repeat'; - state.mode = BAD; - break; - } - len = state.lens[state.have - 1]; - copy = 3 + (hold & 0x03);//BITS(2); - //--- DROPBITS(2) ---// - hold >>>= 2; - bits -= 2; - //---// - } - else if (here_val === 17) { - //=== NEEDBITS(here.bits + 3); - n = here_bits + 3; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 3 + (hold & 0x07);//BITS(3); - //--- DROPBITS(3) ---// - hold >>>= 3; - bits -= 3; - //---// - } - else { - //=== NEEDBITS(here.bits + 7); - n = here_bits + 7; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; - //---// - len = 0; - copy = 11 + (hold & 0x7f);//BITS(7); - //--- DROPBITS(7) ---// - hold >>>= 7; - bits -= 7; - //---// - } - if (state.have + copy > state.nlen + state.ndist) { + if (state.have === 0) { strm.msg = 'invalid bit length repeat'; state.mode = BAD; break; } - while (copy--) { - state.lens[state.have++] = len; + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; } } + } - /* handle error breaks in while */ - if (state.mode === BAD) { break; } - - /* check for end-of-block code (better have one) */ - if (state.lens[256] === 0) { - strm.msg = 'invalid code -- missing end-of-block'; - state.mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state.lenbits = 9; + /* handle error breaks in while */ + if (state.mode === BAD) { break; } - opts = { bits: state.lenbits }; - ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.lenbits = opts.bits; - // state.lencode = state.next; + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } - if (ret) { - strm.msg = 'invalid literal/lengths set'; - state.mode = BAD; - break; - } + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = { bits: state.lenbits }; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } - state.distbits = 6; - //state.distcode.copy(state.codes); - // Switch to use dynamic table - state.distcode = state.distdyn; - opts = { bits: state.distbits }; - ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); - // We have separate tables & no pointers. 2 commented lines below not needed. - // state.next_index = opts.table_index; - state.distbits = opts.bits; - // state.distcode = state.next; - - if (ret) { - strm.msg = 'invalid distances set'; - state.mode = BAD; - break; - } - //Tracev((stderr, 'inflate: codes ok\n')); - state.mode = LEN_; - if (flush === Z_TREES) { break inf_leave; } - /* falls through */ - case LEN_: - state.mode = LEN; - /* falls through */ - case LEN: - if (have >= 6 && left >= 258) { - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - inflate_fast(strm, _out); - //--- LOAD() --- - put = strm.next_out; - output = strm.output; - left = strm.avail_out; - next = strm.next_in; - input = strm.input; - have = strm.avail_in; - hold = state.hold; - bits = state.bits; - //--- - - if (state.mode === TYPE$1) { - state.back = -1; - } - break; + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = { bits: state.distbits }; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE$1) { + state.back = -1; } - state.back = 0; + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; for (;;) { - here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/ + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; here_bits = here >>> 24; here_op = (here >>> 16) & 0xff; here_val = here & 0xffff; - if (here_bits <= bits) { break; } + if ((last_bits + here_bits) <= bits) { break; } //--- PULLBYTE() ---// if (have === 0) { break inf_leave; } have--; @@ -8581,88 +8041,88 @@ var serviceContext = (function (shared, vue) { bits += 8; //---// } - if (here_op && (here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.lencode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; //---// - state.back += here_bits; - state.length = here_val; - if (here_op === 0) { - //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - // "inflate: literal '%c'\n" : - // "inflate: literal 0x%02x\n", here.val)); - state.mode = LIT; - break; - } - if (here_op & 32) { - //Tracevv((stderr, "inflate: end of block\n")); - state.back = -1; - state.mode = TYPE$1; - break; - } - if (here_op & 64) { - strm.msg = 'invalid literal/length code'; - state.mode = BAD; - break; - } - state.extra = here_op & 15; - state.mode = LENEXT; - /* falls through */ - case LENEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE$1; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; } - //Tracevv((stderr, "inflate: length %u\n", state.length)); - state.was = state.length; - state.mode = DIST; - /* falls through */ - case DIST: + //===// + state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; for (;;) { - here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/ + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; here_bits = here >>> 24; here_op = (here >>> 16) & 0xff; here_val = here & 0xffff; - if ((here_bits) <= bits) { break; } + if ((last_bits + here_bits) <= bits) { break; } //--- PULLBYTE() ---// if (have === 0) { break inf_leave; } have--; @@ -8670,11417 +8130,11390 @@ var serviceContext = (function (shared, vue) { bits += 8; //---// } - if ((here_op & 0xf0) === 0) { - last_bits = here_bits; - last_op = here_op; - last_val = here_val; - for (;;) { - here = state.distcode[last_val + - ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)]; - here_bits = here >>> 24; - here_op = (here >>> 16) & 0xff; - here_val = here & 0xffff; - - if ((last_bits + here_bits) <= bits) { break; } - //--- PULLBYTE() ---// - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - //---// - } - //--- DROPBITS(last.bits) ---// - hold >>>= last_bits; - bits -= last_bits; - //---// - state.back += last_bits; - } - //--- DROPBITS(here.bits) ---// - hold >>>= here_bits; - bits -= here_bits; + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; //---// - state.back += here_bits; - if (here_op & 64) { - strm.msg = 'invalid distance code'; - state.mode = BAD; - break; + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; } - state.offset = here_val; - state.extra = (here_op) & 15; - state.mode = DISTEXT; - /* falls through */ - case DISTEXT: - if (state.extra) { - //=== NEEDBITS(state.extra); - n = state.extra; - while (bits < n) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; + //===// + state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; } - //===// - state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/; - //--- DROPBITS(state.extra) ---// - hold >>>= state.extra; - bits -= state.extra; - //---// - state.back += state.extra; +// (!) This block is disabled in zlib defaults, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif } - //#ifdef INFLATE_STRICT - if (state.offset > state.dmax) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; } - //#endif - //Tracevv((stderr, "inflate: distance %u\n", state.offset)); - state.mode = MATCH; - /* falls through */ - case MATCH: - if (left === 0) { break inf_leave; } - copy = _out - left; - if (state.offset > copy) { /* copy from window */ - copy = state.offset - copy; - if (copy > state.whave) { - if (state.sane) { - strm.msg = 'invalid distance too far back'; - state.mode = BAD; - break; - } - // (!) This block is disabled in zlib defaults, - // don't enable it for binary compatibility - //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - // Trace((stderr, "inflate.c too far\n")); - // copy -= state.whave; - // if (copy > state.length) { copy = state.length; } - // if (copy > left) { copy = left; } - // left -= copy; - // state.length -= copy; - // do { - // output[put++] = 0; - // } while (--copy); - // if (state.length === 0) { state.mode = LEN; } - // break; - //#endif - } - if (copy > state.wnext) { - copy -= state.wnext; - from = state.wsize - copy; - } - else { - from = state.wnext - copy; - } - if (copy > state.length) { copy = state.length; } - from_source = state.window; + else { + from = state.wnext - copy; } - else { /* copy from output */ - from_source = output; - from = put - state.offset; - copy = state.length; + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' instead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; } - if (copy > left) { copy = left; } - left -= copy; - state.length -= copy; - do { - output[put++] = from_source[from++]; - } while (--copy); - if (state.length === 0) { state.mode = LEN; } - break; - case LIT: - if (left === 0) { break inf_leave; } - output[put++] = state.length; - left--; - state.mode = LEN; - break; - case CHECK: - if (state.wrap) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - // Use '|' instead of '+' to make sure that result is signed - hold |= input[next++] << bits; - bits += 8; - } - //===// - _out -= left; - strm.total_out += _out; - state.total += _out; - if (_out) { - strm.adler = state.check = - /*UPDATE(state.check, put - _out, _out);*/ - (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); - } - _out = left; - // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too - if ((state.flags ? hold : zswap32(hold)) !== state.check) { - strm.msg = 'incorrect data check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: check matches trailer\n")); } - state.mode = LENGTH; - /* falls through */ - case LENGTH: - if (state.wrap && state.flags) { - //=== NEEDBITS(32); - while (bits < 32) { - if (have === 0) { break inf_leave; } - have--; - hold += input[next++] << bits; - bits += 8; - } - //===// - if (hold !== (state.total & 0xffffffff)) { - strm.msg = 'incorrect length check'; - state.mode = BAD; - break; - } - //=== INITBITS(); - hold = 0; - bits = 0; - //===// - //Tracev((stderr, "inflate: length matches trailer\n")); + _out = left; + // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too + if ((state.flags ? hold : zswap32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; } - state.mode = DONE; - /* falls through */ - case DONE: - ret = Z_STREAM_END; - break inf_leave; - case BAD: - ret = Z_DATA_ERROR; - break inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - /* falls through */ - default: - return Z_STREAM_ERROR; - } + //===// + if (hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; } + } - // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ - //--- RESTORE() --- - strm.next_out = put; - strm.avail_out = left; - strm.next_in = next; - strm.avail_in = have; - state.hold = hold; - state.bits = bits; - //--- - - if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && - (state.mode < CHECK || flush !== Z_FINISH))) { - if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; - } - _in -= strm.avail_in; - _out -= strm.avail_out; - strm.total_in += _in; - strm.total_out += _out; - state.total += _out; - if (state.wrap && _out) { - strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ - (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); - } - strm.data_type = state.bits + (state.last ? 64 : 0) + - (state.mode === TYPE$1 ? 128 : 0) + - (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); - if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { - ret = Z_BUF_ERROR; - } - return ret; + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ; } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE$1 ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; +} - function inflateEnd(strm) { +function inflateEnd(strm) { - if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { - return Z_STREAM_ERROR; - } + if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { + return Z_STREAM_ERROR; + } - var state = strm.state; - if (state.window) { - state.window = null; - } - strm.state = null; - return Z_OK; + var state = strm.state; + if (state.window) { + state.window = null; } + strm.state = null; + return Z_OK; +} - function inflateGetHeader(strm, head) { - var state; +function inflateGetHeader(strm, head) { + var state; - /* check state */ - if (!strm || !strm.state) { return Z_STREAM_ERROR; } - state = strm.state; - if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } + /* check state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } - /* save header structure */ - state.head = head; - head.done = false; - return Z_OK; - } + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; +} - function inflateSetDictionary(strm, dictionary) { - var dictLength = dictionary.length; +function inflateSetDictionary(strm, dictionary) { + var dictLength = dictionary.length; - var state; - var dictid; - var ret; + var state; + var dictid; + var ret; - /* check state */ - if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } - state = strm.state; + /* check state */ + if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; } + state = strm.state; - if (state.wrap !== 0 && state.mode !== DICT) { - return Z_STREAM_ERROR; - } + if (state.wrap !== 0 && state.mode !== DICT) { + return Z_STREAM_ERROR; + } - /* check for correct dictionary identifier */ - if (state.mode === DICT) { - dictid = 1; /* adler32(0, null, 0)*/ - /* dictid = adler32(dictid, dictionary, dictLength); */ - dictid = adler32(dictid, dictionary, dictLength, 0); - if (dictid !== state.check) { - return Z_DATA_ERROR; - } + /* check for correct dictionary identifier */ + if (state.mode === DICT) { + dictid = 1; /* adler32(0, null, 0)*/ + /* dictid = adler32(dictid, dictionary, dictLength); */ + dictid = adler32(dictid, dictionary, dictLength, 0); + if (dictid !== state.check) { + return Z_DATA_ERROR; } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary, dictLength, dictLength); - if (ret) { - state.mode = MEM; - return Z_MEM_ERROR; - } - state.havedict = 1; - // Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; } + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary, dictLength, dictLength); + if (ret) { + state.mode = MEM; + return Z_MEM_ERROR; + } + state.havedict = 1; + // Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +var inflateReset_1 = inflateReset; +var inflateReset2_1 = inflateReset2; +var inflateResetKeep_1 = inflateResetKeep; +var inflateInit_1 = inflateInit; +var inflateInit2_1 = inflateInit2; +var inflate_2$1 = inflate$2; +var inflateEnd_1 = inflateEnd; +var inflateGetHeader_1 = inflateGetHeader; +var inflateSetDictionary_1 = inflateSetDictionary; +var inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +exports.inflateCopy = inflateCopy; +exports.inflateGetDictionary = inflateGetDictionary; +exports.inflateMark = inflateMark; +exports.inflatePrime = inflatePrime; +exports.inflateSync = inflateSync; +exports.inflateSyncPoint = inflateSyncPoint; +exports.inflateUndermine = inflateUndermine; +*/ + +var inflate_1$1 = { + inflateReset: inflateReset_1, + inflateReset2: inflateReset2_1, + inflateResetKeep: inflateResetKeep_1, + inflateInit: inflateInit_1, + inflateInit2: inflateInit2_1, + inflate: inflate_2$1, + inflateEnd: inflateEnd_1, + inflateGetHeader: inflateGetHeader_1, + inflateSetDictionary: inflateSetDictionary_1, + inflateInfo: inflateInfo +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +var constants$1 = { - var inflateReset_1 = inflateReset; - var inflateReset2_1 = inflateReset2; - var inflateResetKeep_1 = inflateResetKeep; - var inflateInit_1 = inflateInit; - var inflateInit2_1 = inflateInit2; - var inflate_2$1 = inflate$2; - var inflateEnd_1 = inflateEnd; - var inflateGetHeader_1 = inflateGetHeader; - var inflateSetDictionary_1 = inflateSetDictionary; - var inflateInfo = 'pako inflate (from Nodeca project)'; - - /* Not implemented - exports.inflateCopy = inflateCopy; - exports.inflateGetDictionary = inflateGetDictionary; - exports.inflateMark = inflateMark; - exports.inflatePrime = inflatePrime; - exports.inflateSync = inflateSync; - exports.inflateSyncPoint = inflateSyncPoint; - exports.inflateUndermine = inflateUndermine; + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type +}; + +// (C) 1995-2013 Jean-loup Gailly and Mark Adler +// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. + +function GZheader$1() { + /* true if compressed data believed to be text */ + this.text = 0; + /* modification time */ + this.time = 0; + /* extra flags (not used when writing a gzip file) */ + this.xflags = 0; + /* operating system */ + this.os = 0; + /* pointer to extra field or Z_NULL if none */ + this.extra = null; + /* extra field length (valid if extra != Z_NULL) */ + this.extra_len = 0; // Actually, we don't need it in JS, + // but leave for few code modifications - var inflate_1$1 = { - inflateReset: inflateReset_1, - inflateReset2: inflateReset2_1, - inflateResetKeep: inflateResetKeep_1, - inflateInit: inflateInit_1, - inflateInit2: inflateInit2_1, - inflate: inflate_2$1, - inflateEnd: inflateEnd_1, - inflateGetHeader: inflateGetHeader_1, - inflateSetDictionary: inflateSetDictionary_1, - inflateInfo: inflateInfo - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. - // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: - // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - var constants$1 = { - - /* Allowed flush values; see deflate() and inflate() below for details */ - Z_NO_FLUSH: 0, - Z_PARTIAL_FLUSH: 1, - Z_SYNC_FLUSH: 2, - Z_FULL_FLUSH: 3, - Z_FINISH: 4, - Z_BLOCK: 5, - Z_TREES: 6, - - /* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - Z_OK: 0, - Z_STREAM_END: 1, - Z_NEED_DICT: 2, - Z_ERRNO: -1, - Z_STREAM_ERROR: -2, - Z_DATA_ERROR: -3, - //Z_MEM_ERROR: -4, - Z_BUF_ERROR: -5, - //Z_VERSION_ERROR: -6, - - /* compression levels */ - Z_NO_COMPRESSION: 0, - Z_BEST_SPEED: 1, - Z_BEST_COMPRESSION: 9, - Z_DEFAULT_COMPRESSION: -1, - - - Z_FILTERED: 1, - Z_HUFFMAN_ONLY: 2, - Z_RLE: 3, - Z_FIXED: 4, - Z_DEFAULT_STRATEGY: 0, - - /* Possible values of the data_type field (though see inflate()) */ - Z_BINARY: 0, - Z_TEXT: 1, - //Z_ASCII: 1, // = Z_TEXT (deprecated) - Z_UNKNOWN: 2, - - /* The deflate compression method */ - Z_DEFLATED: 8 - //Z_NULL: null // Use -1 or null inline, depending on var type - }; - - // (C) 1995-2013 Jean-loup Gailly and Mark Adler - // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin - // - // This software is provided 'as-is', without any express or implied - // warranty. In no event will the authors be held liable for any damages - // arising from the use of this software. // - // Permission is granted to anyone to use this software for any purpose, - // including commercial applications, and to alter it and redistribute it - // freely, subject to the following restrictions: + // Setup limits is not necessary because in js we should not preallocate memory + // for inflate use constant limit in 65536 bytes // - // 1. The origin of this software must not be misrepresented; you must not - // claim that you wrote the original software. If you use this software - // in a product, an acknowledgment in the product documentation would be - // appreciated but is not required. - // 2. Altered source versions must be plainly marked as such, and must not be - // misrepresented as being the original software. - // 3. This notice may not be removed or altered from any source distribution. - - function GZheader$1() { - /* true if compressed data believed to be text */ - this.text = 0; - /* modification time */ - this.time = 0; - /* extra flags (not used when writing a gzip file) */ - this.xflags = 0; - /* operating system */ - this.os = 0; - /* pointer to extra field or Z_NULL if none */ - this.extra = null; - /* extra field length (valid if extra != Z_NULL) */ - this.extra_len = 0; // Actually, we don't need it in JS, - // but leave for few code modifications - // - // Setup limits is not necessary because in js we should not preallocate memory - // for inflate use constant limit in 65536 bytes - // + /* space at extra (only when reading header) */ + // this.extra_max = 0; + /* pointer to zero-terminated file name or Z_NULL */ + this.name = ''; + /* space at name (only when reading header) */ + // this.name_max = 0; + /* pointer to zero-terminated comment or Z_NULL */ + this.comment = ''; + /* space at comment (only when reading header) */ + // this.comm_max = 0; + /* true if there was or will be a header crc */ + this.hcrc = 0; + /* true when done reading gzip header (not used when writing a gzip file) */ + this.done = false; +} - /* space at extra (only when reading header) */ - // this.extra_max = 0; - /* pointer to zero-terminated file name or Z_NULL */ - this.name = ''; - /* space at name (only when reading header) */ - // this.name_max = 0; - /* pointer to zero-terminated comment or Z_NULL */ - this.comment = ''; - /* space at comment (only when reading header) */ - // this.comm_max = 0; - /* true if there was or will be a header crc */ - this.hcrc = 0; - /* true when done reading gzip header (not used when writing a gzip file) */ - this.done = false; +var gzheader = GZheader$1; + +var zlib_inflate = inflate_1$1; + +var constants = constants$1; + +var GZheader = gzheader; + +var toString$1 = Object.prototype.toString; + +/** + * class Inflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[inflate]] + * and [[inflateRaw]]. + **/ + +/* internal + * inflate.chunks -> Array + * + * Chunks of output data, if [[Inflate#onData]] not overridden. + **/ + +/** + * Inflate.result -> Uint8Array|Array|String + * + * Uncompressed result, generated by default [[Inflate#onData]] + * and [[Inflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you + * push a chunk with explicit flush (call [[Inflate#push]] with + * `Z_SYNC_FLUSH` param). + **/ + +/** + * Inflate.err -> Number + * + * Error code after inflate finished. 0 (Z_OK) on success. + * Should be checked if broken data possible. + **/ + +/** + * Inflate.msg -> String + * + * Error message, if [[Inflate.err]] != 0 + **/ + + +/** + * new Inflate(options) + * - options (Object): zlib inflate options. + * + * Creates new inflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `windowBits` + * - `dictionary` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw inflate + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * By default, when no options set, autodetect deflate/gzip data format via + * wrapper header. + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var inflate = new pako.Inflate({ level: 3}); + * + * inflate.push(chunk1, false); + * inflate.push(chunk2, true); // true -> last chunk + * + * if (inflate.err) { throw new Error(inflate.err); } + * + * console.log(inflate.result); + * ``` + **/ +function Inflate(options) { + if (!(this instanceof Inflate)) return new Inflate(options); + + this.options = require$$0.assign({ + chunkSize: 16384, + windowBits: 0, + to: '' + }, options || {}); + + var opt = this.options; + + // Force window size for `raw` data, if not set directly, + // because we have no header for autodetect. + if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { + opt.windowBits = -opt.windowBits; + if (opt.windowBits === 0) { opt.windowBits = -15; } } - var gzheader = GZheader$1; - - var zlib_inflate = inflate_1$1; - - var constants = constants$1; - - var GZheader = gzheader; - - var toString$1 = Object.prototype.toString; - - /** - * class Inflate - * - * Generic JS-style wrapper for zlib calls. If you don't need - * streaming behaviour - use more simple functions: [[inflate]] - * and [[inflateRaw]]. - **/ - - /* internal - * inflate.chunks -> Array - * - * Chunks of output data, if [[Inflate#onData]] not overridden. - **/ - - /** - * Inflate.result -> Uint8Array|Array|String - * - * Uncompressed result, generated by default [[Inflate#onData]] - * and [[Inflate#onEnd]] handlers. Filled after you push last chunk - * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you - * push a chunk with explicit flush (call [[Inflate#push]] with - * `Z_SYNC_FLUSH` param). - **/ - - /** - * Inflate.err -> Number - * - * Error code after inflate finished. 0 (Z_OK) on success. - * Should be checked if broken data possible. - **/ - - /** - * Inflate.msg -> String - * - * Error message, if [[Inflate.err]] != 0 - **/ - - - /** - * new Inflate(options) - * - options (Object): zlib inflate options. - * - * Creates new inflator instance with specified params. Throws exception - * on bad params. Supported options: - * - * - `windowBits` - * - `dictionary` - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information on these. - * - * Additional options, for internal needs: - * - * - `chunkSize` - size of generated data chunks (16K by default) - * - `raw` (Boolean) - do raw inflate - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * By default, when no options set, autodetect deflate/gzip data format via - * wrapper header. - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) - * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); - * - * var inflate = new pako.Inflate({ level: 3}); - * - * inflate.push(chunk1, false); - * inflate.push(chunk2, true); // true -> last chunk - * - * if (inflate.err) { throw new Error(inflate.err); } - * - * console.log(inflate.result); - * ``` - **/ - function Inflate(options) { - if (!(this instanceof Inflate)) return new Inflate(options); - - this.options = require$$0.assign({ - chunkSize: 16384, - windowBits: 0, - to: '' - }, options || {}); - - var opt = this.options; - - // Force window size for `raw` data, if not set directly, - // because we have no header for autodetect. - if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { - opt.windowBits = -opt.windowBits; - if (opt.windowBits === 0) { opt.windowBits = -15; } - } - - // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate - if ((opt.windowBits >= 0) && (opt.windowBits < 16) && - !(options && options.windowBits)) { - opt.windowBits += 32; - } + // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate + if ((opt.windowBits >= 0) && (opt.windowBits < 16) && + !(options && options.windowBits)) { + opt.windowBits += 32; + } - // Gzip header has no info about windows size, we can do autodetect only - // for deflate. So, if window size not set, force it to max when gzip possible - if ((opt.windowBits > 15) && (opt.windowBits < 48)) { - // bit 3 (16) -> gzipped data - // bit 4 (32) -> autodetect gzip/deflate - if ((opt.windowBits & 15) === 0) { - opt.windowBits |= 15; - } + // Gzip header has no info about windows size, we can do autodetect only + // for deflate. So, if window size not set, force it to max when gzip possible + if ((opt.windowBits > 15) && (opt.windowBits < 48)) { + // bit 3 (16) -> gzipped data + // bit 4 (32) -> autodetect gzip/deflate + if ((opt.windowBits & 15) === 0) { + opt.windowBits |= 15; } + } - this.err = 0; // error code, if happens (0 = Z_OK) - this.msg = ''; // error message - this.ended = false; // used to avoid multiple onEnd() calls - this.chunks = []; // chunks of compressed data + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data - this.strm = new ZStream(); - this.strm.avail_out = 0; + this.strm = new ZStream(); + this.strm.avail_out = 0; - var status = zlib_inflate.inflateInit2( - this.strm, - opt.windowBits - ); + var status = zlib_inflate.inflateInit2( + this.strm, + opt.windowBits + ); - if (status !== constants.Z_OK) { - throw new Error(msg[status]); - } + if (status !== constants.Z_OK) { + throw new Error(msg[status]); + } - this.header = new GZheader(); + this.header = new GZheader(); - zlib_inflate.inflateGetHeader(this.strm, this.header); + zlib_inflate.inflateGetHeader(this.strm, this.header); - // Setup dictionary - if (opt.dictionary) { - // Convert data if needed - if (typeof opt.dictionary === 'string') { - opt.dictionary = strings.string2buf(opt.dictionary); - } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') { - opt.dictionary = new Uint8Array(opt.dictionary); - } - if (opt.raw) { //In raw mode we need to set the dictionary early - status = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary); - if (status !== constants.Z_OK) { - throw new Error(msg[status]); - } + // Setup dictionary + if (opt.dictionary) { + // Convert data if needed + if (typeof opt.dictionary === 'string') { + opt.dictionary = strings.string2buf(opt.dictionary); + } else if (toString$1.call(opt.dictionary) === '[object ArrayBuffer]') { + opt.dictionary = new Uint8Array(opt.dictionary); + } + if (opt.raw) { //In raw mode we need to set the dictionary early + status = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary); + if (status !== constants.Z_OK) { + throw new Error(msg[status]); } } } +} - /** - * Inflate#push(data[, mode]) -> Boolean - * - data (Uint8Array|Array|ArrayBuffer|String): input data - * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. - * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. - * - * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with - * new output chunks. Returns `true` on success. The last data block must have - * mode Z_FINISH (or `true`). That will flush internal pending buffers and call - * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you - * can use mode Z_SYNC_FLUSH, keeping the decompression context. - * - * On fail call [[Inflate#onEnd]] with error code and return false. - * - * We strongly recommend to use `Uint8Array` on input for best speed (output - * format is detected automatically). Also, don't skip last param and always - * use the same type in your code (boolean or number). That will improve JS speed. - * - * For regular `Array`-s make sure all elements are [0..255]. - * - * ##### Example - * - * ```javascript - * push(chunk, false); // push one of data chunks - * ... - * push(chunk, true); // push last chunk - * ``` - **/ - Inflate.prototype.push = function (data, mode) { - var strm = this.strm; - var chunkSize = this.options.chunkSize; - var dictionary = this.options.dictionary; - var status, _mode; - var next_out_utf8, tail, utf8str; - - // Flag to properly process Z_BUF_ERROR on testing inflate call - // when we check that all output data was flushed. - var allowBufError = false; - - if (this.ended) { return false; } - _mode = (mode === ~~mode) ? mode : ((mode === true) ? constants.Z_FINISH : constants.Z_NO_FLUSH); - - // Convert data if needed - if (typeof data === 'string') { - // Only binary strings can be decompressed on practice - strm.input = strings.binstring2buf(data); - } else if (toString$1.call(data) === '[object ArrayBuffer]') { - strm.input = new Uint8Array(data); - } else { - strm.input = data; - } +/** + * Inflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|ArrayBuffer|String): input data + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. + * + * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with + * new output chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That will flush internal pending buffers and call + * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you + * can use mode Z_SYNC_FLUSH, keeping the decompression context. + * + * On fail call [[Inflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Inflate.prototype.push = function (data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var dictionary = this.options.dictionary; + var status, _mode; + var next_out_utf8, tail, utf8str; + + // Flag to properly process Z_BUF_ERROR on testing inflate call + // when we check that all output data was flushed. + var allowBufError = false; + + if (this.ended) { return false; } + _mode = (mode === ~~mode) ? mode : ((mode === true) ? constants.Z_FINISH : constants.Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // Only binary strings can be decompressed on practice + strm.input = strings.binstring2buf(data); + } else if (toString$1.call(data) === '[object ArrayBuffer]') { + strm.input = new Uint8Array(data); + } else { + strm.input = data; + } - strm.next_in = 0; - strm.avail_in = strm.input.length; + strm.next_in = 0; + strm.avail_in = strm.input.length; - do { - if (strm.avail_out === 0) { - strm.output = new require$$0.Buf8(chunkSize); - strm.next_out = 0; - strm.avail_out = chunkSize; - } + do { + if (strm.avail_out === 0) { + strm.output = new require$$0.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } - status = zlib_inflate.inflate(strm, constants.Z_NO_FLUSH); /* no bad return value */ + status = zlib_inflate.inflate(strm, constants.Z_NO_FLUSH); /* no bad return value */ - if (status === constants.Z_NEED_DICT && dictionary) { - status = zlib_inflate.inflateSetDictionary(this.strm, dictionary); - } + if (status === constants.Z_NEED_DICT && dictionary) { + status = zlib_inflate.inflateSetDictionary(this.strm, dictionary); + } - if (status === constants.Z_BUF_ERROR && allowBufError === true) { - status = constants.Z_OK; - allowBufError = false; - } + if (status === constants.Z_BUF_ERROR && allowBufError === true) { + status = constants.Z_OK; + allowBufError = false; + } - if (status !== constants.Z_STREAM_END && status !== constants.Z_OK) { - this.onEnd(status); - this.ended = true; - return false; - } + if (status !== constants.Z_STREAM_END && status !== constants.Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } - if (strm.next_out) { - if (strm.avail_out === 0 || status === constants.Z_STREAM_END || (strm.avail_in === 0 && (_mode === constants.Z_FINISH || _mode === constants.Z_SYNC_FLUSH))) { + if (strm.next_out) { + if (strm.avail_out === 0 || status === constants.Z_STREAM_END || (strm.avail_in === 0 && (_mode === constants.Z_FINISH || _mode === constants.Z_SYNC_FLUSH))) { - if (this.options.to === 'string') { + if (this.options.to === 'string') { - next_out_utf8 = strings.utf8border(strm.output, strm.next_out); + next_out_utf8 = strings.utf8border(strm.output, strm.next_out); - tail = strm.next_out - next_out_utf8; - utf8str = strings.buf2string(strm.output, next_out_utf8); + tail = strm.next_out - next_out_utf8; + utf8str = strings.buf2string(strm.output, next_out_utf8); - // move tail - strm.next_out = tail; - strm.avail_out = chunkSize - tail; - if (tail) { require$$0.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); } + // move tail + strm.next_out = tail; + strm.avail_out = chunkSize - tail; + if (tail) { require$$0.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); } - this.onData(utf8str); + this.onData(utf8str); - } else { - this.onData(require$$0.shrinkBuf(strm.output, strm.next_out)); - } + } else { + this.onData(require$$0.shrinkBuf(strm.output, strm.next_out)); } } - - // When no more input data, we should check that internal inflate buffers - // are flushed. The only way to do it when avail_out = 0 - run one more - // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR. - // Here we set flag to process this error properly. - // - // NOTE. Deflate does not return error in this case and does not needs such - // logic. - if (strm.avail_in === 0 && strm.avail_out === 0) { - allowBufError = true; - } - - } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== constants.Z_STREAM_END); - - if (status === constants.Z_STREAM_END) { - _mode = constants.Z_FINISH; } - // Finalize on the last chunk. - if (_mode === constants.Z_FINISH) { - status = zlib_inflate.inflateEnd(this.strm); - this.onEnd(status); - this.ended = true; - return status === constants.Z_OK; + // When no more input data, we should check that internal inflate buffers + // are flushed. The only way to do it when avail_out = 0 - run one more + // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR. + // Here we set flag to process this error properly. + // + // NOTE. Deflate does not return error in this case and does not needs such + // logic. + if (strm.avail_in === 0 && strm.avail_out === 0) { + allowBufError = true; } - // callback interim results if Z_SYNC_FLUSH. - if (_mode === constants.Z_SYNC_FLUSH) { - this.onEnd(constants.Z_OK); - strm.avail_out = 0; - return true; - } + } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== constants.Z_STREAM_END); + + if (status === constants.Z_STREAM_END) { + _mode = constants.Z_FINISH; + } + // Finalize on the last chunk. + if (_mode === constants.Z_FINISH) { + status = zlib_inflate.inflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === constants.Z_OK; + } + + // callback interim results if Z_SYNC_FLUSH. + if (_mode === constants.Z_SYNC_FLUSH) { + this.onEnd(constants.Z_OK); + strm.avail_out = 0; return true; - }; - - - /** - * Inflate#onData(chunk) -> Void - * - chunk (Uint8Array|Array|String): output data. Type of array depends - * on js engine support. When string output requested, each chunk - * will be string. - * - * By default, stores data blocks in `chunks[]` property and glue - * those in `onEnd`. Override this handler, if you need another behaviour. - **/ - Inflate.prototype.onData = function (chunk) { - this.chunks.push(chunk); - }; - - - /** - * Inflate#onEnd(status) -> Void - * - status (Number): inflate status. 0 (Z_OK) on success, - * other if not. - * - * Called either after you tell inflate that the input stream is - * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) - * or if an error happened. By default - join collected chunks, - * free memory and fill `results` / `err` properties. - **/ - Inflate.prototype.onEnd = function (status) { - // On success - join - if (status === constants.Z_OK) { - if (this.options.to === 'string') { - // Glue & convert here, until we teach pako to send - // utf8 aligned strings to onData - this.result = this.chunks.join(''); - } else { - this.result = require$$0.flattenChunks(this.chunks); - } + } + + return true; +}; + + +/** + * Inflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): output data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Inflate.prototype.onData = function (chunk) { + this.chunks.push(chunk); +}; + + +/** + * Inflate#onEnd(status) -> Void + * - status (Number): inflate status. 0 (Z_OK) on success, + * other if not. + * + * Called either after you tell inflate that the input stream is + * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) + * or if an error happened. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Inflate.prototype.onEnd = function (status) { + // On success - join + if (status === constants.Z_OK) { + if (this.options.to === 'string') { + // Glue & convert here, until we teach pako to send + // utf8 aligned strings to onData + this.result = this.chunks.join(''); + } else { + this.result = require$$0.flattenChunks(this.chunks); } - this.chunks = []; - this.err = status; - this.msg = this.strm.msg; - }; - - - /** - * inflate(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to decompress. - * - options (Object): zlib inflate options. - * - * Decompress `data` with inflate/ungzip and `options`. Autodetect - * format via wrapper header by default. That's why we don't provide - * separate `ungzip` method. - * - * Supported options are: - * - * - windowBits - * - * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) - * for more information. - * - * Sugar (options): - * - * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify - * negative windowBits implicitly. - * - `to` (String) - if equal to 'string', then result will be converted - * from utf8 to utf16 (javascript) string. When string output requested, - * chunk length can differ from `chunkSize`, depending on content. - * - * - * ##### Example: - * - * ```javascript - * var pako = require('pako') - * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) - * , output; - * - * try { - * output = pako.inflate(input); - * } catch (err) - * console.log(err); - * } - * ``` - **/ - function inflate$1(input, options) { - var inflator = new Inflate(options); - - inflator.push(input, true); - - // That will never happens, if you don't cheat with options :) - if (inflator.err) { throw inflator.msg || msg[inflator.err]; } - - return inflator.result; } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * inflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Decompress `data` with inflate/ungzip and `options`. Autodetect + * format via wrapper header by default. That's why we don't provide + * separate `ungzip` method. + * + * Supported options are: + * + * - windowBits + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) + * , output; + * + * try { + * output = pako.inflate(input); + * } catch (err) + * console.log(err); + * } + * ``` + **/ +function inflate$1(input, options) { + var inflator = new Inflate(options); + + inflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (inflator.err) { throw inflator.msg || msg[inflator.err]; } + + return inflator.result; +} - /** - * inflateRaw(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to decompress. - * - options (Object): zlib inflate options. - * - * The same as [[inflate]], but creates raw data, without wrapper - * (header and adler32 crc). - **/ - function inflateRaw(input, options) { - options = options || {}; - options.raw = true; - return inflate$1(input, options); - } +/** + * inflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * The same as [[inflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function inflateRaw(input, options) { + options = options || {}; + options.raw = true; + return inflate$1(input, options); +} - /** - * ungzip(data[, options]) -> Uint8Array|Array|String - * - data (Uint8Array|Array|String): input data to decompress. - * - options (Object): zlib inflate options. - * - * Just shortcut to [[inflate]], because it autodetects format - * by header.content. Done for convenience. - **/ - - - var Inflate_1 = Inflate; - var inflate_2 = inflate$1; - var inflateRaw_1 = inflateRaw; - var ungzip = inflate$1; - - var inflate_1 = { - Inflate: Inflate_1, - inflate: inflate_2, - inflateRaw: inflateRaw_1, - ungzip: ungzip - }; - - var deflate = deflate_1; - - var inflate = inflate_1; - - var assign = require$$0.assign; - - - - - - var pako = {}; - - assign(pako, deflate, inflate, constants); - - var pako_1 = pako; - - const API_UPX2PX = 'upx2px'; - const Upx2pxProtocol = [ - { - name: 'upx', - type: [Number, String], - required: true, - }, - ]; - - const EPS = 1e-4; - const BASE_DEVICE_WIDTH = 750; - let isIOS$1 = false; - let deviceWidth = 0; - let deviceDPR = 0; - function checkDeviceWidth() { - const { platform, pixelRatio, windowWidth } = getBaseSystemInfo(); - deviceWidth = windowWidth; - deviceDPR = pixelRatio; - isIOS$1 = platform === 'ios'; - } - function checkValue(value, defaultValue) { - const newValue = Number(value); - return isNaN(newValue) ? defaultValue : newValue; - } - const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { - if (deviceWidth === 0) { - checkDeviceWidth(); - } - number = Number(number); - if (number === 0) { - return 0; - } - let width = newDeviceWidth || deviceWidth; - { - const config = __uniConfig.globalStyle || {}; - // ignore rpxCalcIncludeWidth - const maxWidth = checkValue(config.rpxCalcMaxDeviceWidth, 960); - const baseWidth = checkValue(config.rpxCalcBaseDeviceWidth, 375); - width = width <= maxWidth ? width : baseWidth; - } - let result = (number / BASE_DEVICE_WIDTH) * width; - if (result < 0) { - result = -result; - } - result = Math.floor(result + EPS); - if (result === 0) { - if (deviceDPR === 1 || !isIOS$1) { - result = 1; - } - else { - result = 0.5; - } - } - return number < 0 ? -result : result; - }, Upx2pxProtocol); - - const API_ADD_INTERCEPTOR = 'addInterceptor'; - const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; - const AddInterceptorProtocol = [ - { - name: 'method', - type: [String, Object], - required: true, - }, - ]; - const RemoveInterceptorProtocol = AddInterceptorProtocol; - - function mergeInterceptorHook(interceptors, interceptor) { - Object.keys(interceptor).forEach((hook) => { - if (shared.isFunction(interceptor[hook])) { - interceptors[hook] = mergeHook(interceptors[hook], interceptor[hook]); - } - }); - } - function removeInterceptorHook(interceptors, interceptor) { - if (!interceptors || !interceptor) { - return; - } - Object.keys(interceptor).forEach((hook) => { - if (shared.isFunction(interceptor[hook])) { - removeHook(interceptors[hook], interceptor[hook]); - } - }); - } - function mergeHook(parentVal, childVal) { - const res = childVal - ? parentVal - ? parentVal.concat(childVal) - : shared.isArray(childVal) - ? childVal - : [childVal] - : parentVal; - return res ? dedupeHooks(res) : res; - } - function dedupeHooks(hooks) { - const res = []; - for (let i = 0; i < hooks.length; i++) { - if (res.indexOf(hooks[i]) === -1) { - res.push(hooks[i]); - } - } - return res; - } - function removeHook(hooks, hook) { - if (!hooks) { - return; - } - const index = hooks.indexOf(hook); - if (index !== -1) { - hooks.splice(index, 1); - } - } - const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { - if (typeof method === 'string' && shared.isPlainObject(interceptor)) { - mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); - } - else if (shared.isPlainObject(method)) { - mergeInterceptorHook(globalInterceptors, method); - } - }, AddInterceptorProtocol); - const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { - if (typeof method === 'string') { - if (shared.isPlainObject(interceptor)) { - removeInterceptorHook(scopedInterceptors[method], interceptor); - } - else { - delete scopedInterceptors[method]; - } - } - else if (shared.isPlainObject(method)) { - removeInterceptorHook(globalInterceptors, method); - } - }, RemoveInterceptorProtocol); - const interceptors = {}; - - const API_ON = '$on'; - const OnProtocol = [ - { - name: 'event', - type: String, - required: true, - }, - { - name: 'callback', - type: Function, - required: true, - }, - ]; - const API_ONCE = '$once'; - const OnceProtocol = OnProtocol; - const API_OFF = '$off'; - const OffProtocol = [ - { - name: 'event', - type: [String, Array], - }, - { - name: 'callback', - type: Function, - }, - ]; - const API_EMIT = '$emit'; - const EmitProtocol = [ - { - name: 'event', - type: String, - required: true, - }, - ]; - - const emitter = new Emitter(); - const $on = defineSyncApi(API_ON, (name, callback) => { - emitter.on(name, callback); - return () => emitter.off(name, callback); - }, OnProtocol); - const $once = defineSyncApi(API_ONCE, (name, callback) => { - emitter.once(name, callback); - return () => emitter.off(name, callback); - }, OnceProtocol); - const $off = defineSyncApi(API_OFF, (name, callback) => { - if (!name) { - emitter.e = {}; - return; - } - if (!Array.isArray(name)) - name = [name]; - name.forEach((n) => emitter.off(n, callback)); - }, OffProtocol); - const $emit = defineSyncApi(API_EMIT, (name, ...args) => { - emitter.emit(name, ...args); - }, EmitProtocol); - - const validator = [ - { - name: 'id', - type: String, - required: true, - }, - ]; - /* export const API_CREATE_AUDIO_CONTEXT = 'createAudioContext' - export type API_TYPE_CREATE_AUDIO_CONTEXT = typeof uni.createAudioContext - export const CreateAudioContextProtocol = validator */ - const API_CREATE_VIDEO_CONTEXT = 'createVideoContext'; - const API_CREATE_MAP_CONTEXT = 'createMapContext'; - const CreateMapContextProtocol = validator; - const API_CREATE_CANVAS_CONTEXT = 'createCanvasContext'; - const CreateCanvasContextProtocol = [ - { - name: 'canvasId', - type: String, - required: true, - }, - { - name: 'componentInstance', - type: Object, - }, - ]; - const API_CREATE_INNER_AUDIO_CONTEXT = 'createInnerAudioContext'; - const API_CREATE_LIVE_PUSHER_CONTEXT = 'createLivePusherContext'; - const CreateLivePusherContextProtocol = validator.concat({ - name: 'componentInstance', - type: Object, - }); - - const RATES = [0.5, 0.8, 1.0, 1.25, 1.5, 2.0]; - class VideoContext { - constructor(id, pageId) { - this.id = id; - this.pageId = pageId; - } - play() { - operateVideoPlayer(this.id, this.pageId, 'play'); - } - pause() { - operateVideoPlayer(this.id, this.pageId, 'pause'); - } - stop() { - operateVideoPlayer(this.id, this.pageId, 'stop'); - } - seek(position) { - operateVideoPlayer(this.id, this.pageId, 'seek', { - position, - }); - } - sendDanmu(args) { - operateVideoPlayer(this.id, this.pageId, 'sendDanmu', args); - } - playbackRate(rate) { - if (!~RATES.indexOf(rate)) { - rate = 1.0; - } - operateVideoPlayer(this.id, this.pageId, 'playbackRate', { - rate, - }); - } - requestFullScreen(args = {}) { - operateVideoPlayer(this.id, this.pageId, 'requestFullScreen', args); - } - exitFullScreen() { - operateVideoPlayer(this.id, this.pageId, 'exitFullScreen'); - } - showStatusBar() { - operateVideoPlayer(this.id, this.pageId, 'showStatusBar'); - } - hideStatusBar() { - operateVideoPlayer(this.id, this.pageId, 'hideStatusBar'); - } - } - const createVideoContext = defineSyncApi(API_CREATE_VIDEO_CONTEXT, (id, context) => { - if (context) { - return new VideoContext(id, getPageIdByVm(context)); - } - return new VideoContext(id, getPageIdByVm(getCurrentPageVm())); - }); - - const operateMapCallback = (options, res) => { - const errMsg = res.errMsg || ''; - if (new RegExp('\\:\\s*fail').test(errMsg)) { - options.fail && options.fail(res); - } - else { - options.success && options.success(res); - } - options.complete && options.complete(res); - }; - const operateMapWrap = (id, pageId, type, options) => { - operateMap(id, pageId, type, options, (res) => { - options && operateMapCallback(options, res); - }); - }; - class MapContext { - constructor(id, pageId) { - this.id = id; - this.pageId = pageId; - } - getCenterLocation(options) { - operateMapWrap(this.id, this.pageId, 'getCenterLocation', options); - } - moveToLocation(options) { - operateMapWrap(this.id, this.pageId, 'moveToLocation', options); - } - getScale(options) { - operateMapWrap(this.id, this.pageId, 'getScale', options); - } - getRegion(options) { - operateMapWrap(this.id, this.pageId, 'getRegion', options); - } - includePoints(options) { - operateMapWrap(this.id, this.pageId, 'includePoints', options); - } - translateMarker(options) { - operateMapWrap(this.id, this.pageId, 'translateMarker', options); - } - $getAppMap() { - { - return plus.maps.getMapById(this.pageId + '-map-' + this.id); - } - } - addCustomLayer(options) { - operateMapWrap(this.id, this.pageId, 'addCustomLayer', options); - } - removeCustomLayer(options) { - operateMapWrap(this.id, this.pageId, 'removeCustomLayer', options); - } - addGroundOverlay(options) { - operateMapWrap(this.id, this.pageId, 'addGroundOverlay', options); - } - removeGroundOverlay(options) { - operateMapWrap(this.id, this.pageId, 'removeGroundOverlay', options); - } - updateGroundOverlay(options) { - operateMapWrap(this.id, this.pageId, 'updateGroundOverlay', options); - } - initMarkerCluster(options) { - operateMapWrap(this.id, this.pageId, 'initMarkerCluster', options); - } - addMarkers(options) { - operateMapWrap(this.id, this.pageId, 'addMarkers', options); - } - removeMarkers(options) { - operateMapWrap(this.id, this.pageId, 'removeMarkers', options); - } - moveAlong(options) { - operateMapWrap(this.id, this.pageId, 'moveAlong', options); - } - openMapApp(options) { - operateMapWrap(this.id, this.pageId, 'openMapApp', options); - } - on(options) { - operateMapWrap(this.id, this.pageId, 'on', options); - } - } - const createMapContext = defineSyncApi(API_CREATE_MAP_CONTEXT, (id, context) => { - if (context) { - return new MapContext(id, getPageIdByVm(context)); - } - return new MapContext(id, getPageIdByVm(getCurrentPageVm())); - }, CreateMapContextProtocol); - - function getInt(name, defaultValue) { - return function (value, params) { - if (value) { - params[name] = Math.round(value); - } - else if (typeof defaultValue !== 'undefined') { - params[name] = defaultValue; - } - }; - } - const formatWidth = getInt('width'); - const formatHeight = getInt('height'); - //#region getImageDataOptions - const API_CANVAS_GET_IMAGE_DATA = 'canvasGetImageData'; - const CanvasGetImageDataOptions = { - formatArgs: { - x: getInt('x'), - y: getInt('y'), - width: formatWidth, - height: formatHeight, - }, - }; - const CanvasGetImageDataProtocol = { - canvasId: { - type: String, - required: true, - }, - x: { - type: Number, - required: true, - }, - y: { - type: Number, - required: true, - }, - width: { - type: Number, - required: true, - }, - height: { - type: Number, - required: true, - }, - }; - //#endregion - //#region putImageData - const API_CANVAS_PUT_IMAGE_DATA = 'canvasPutImageData'; - const CanvasPutImageDataOptions = CanvasGetImageDataOptions; - const CanvasPutImageDataProtocol = - /*#__PURE__*/ shared.extend({ - data: { - type: Uint8ClampedArray, - required: true, - }, - }, CanvasGetImageDataProtocol, { - height: { - type: Number, - }, - }); - //#endregion - //#region toTempFilePath - const fileTypes = { - PNG: 'png', - JPG: 'jpg', - JPEG: 'jpg', - }; - const API_CANVAS_TO_TEMP_FILE_PATH = 'canvasToTempFilePath'; - const CanvasToTempFilePathOptions = { - formatArgs: { - x: getInt('x', 0), - y: getInt('y', 0), - width: formatWidth, - height: formatHeight, - destWidth: getInt('destWidth'), - destHeight: getInt('destHeight'), - fileType(value, params) { - value = (value || '').toUpperCase(); - let type = fileTypes[value]; - if (!type) { - type = fileTypes.PNG; - } - params.fileType = type; - }, - quality(value, params) { - params.quality = value && value > 0 && value < 1 ? value : 1; - }, - }, - }; - const CanvasToTempFilePathProtocol = { - x: Number, - y: Number, - width: Number, - height: Number, - destWidth: Number, - destHeight: Number, - canvasId: { - type: String, - required: true, - }, - fileType: String, - quality: Number, - }; - - //#region import - //#endregion - //#region UniServiceJSBridge - function operateCanvas(canvasId, pageId, type, data, callback) { - UniServiceJSBridge.invokeViewMethod(`canvas.${canvasId}`, { - type, - data, - }, pageId, (data) => { - if (callback) - callback(data); - }); - } - //#endregion - //#region methods - var methods1 = ['scale', 'rotate', 'translate', 'setTransform', 'transform']; - var methods2 = [ - 'drawImage', - 'fillText', - 'fill', - 'stroke', - 'fillRect', - 'strokeRect', - 'clearRect', - 'strokeText', - ]; - var methods3 = [ - 'setFillStyle', - 'setTextAlign', - 'setStrokeStyle', - 'setGlobalAlpha', - 'setShadow', - 'setFontSize', - 'setLineCap', - 'setLineJoin', - 'setLineWidth', - 'setMiterLimit', - 'setTextBaseline', - 'setLineDash', - ]; - function measureText(text, font) { - const canvas = document.createElement('canvas'); - const c2d = canvas.getContext('2d'); - c2d.font = font; - return c2d.measureText(text).width || 0; - } - //#endregion - //#region checkColor - const predefinedColor = { - aliceblue: '#f0f8ff', - antiquewhite: '#faebd7', - aqua: '#00ffff', - aquamarine: '#7fffd4', - azure: '#f0ffff', - beige: '#f5f5dc', - bisque: '#ffe4c4', - black: '#000000', - blanchedalmond: '#ffebcd', - blue: '#0000ff', - blueviolet: '#8a2be2', - brown: '#a52a2a', - burlywood: '#deb887', - cadetblue: '#5f9ea0', - chartreuse: '#7fff00', - chocolate: '#d2691e', - coral: '#ff7f50', - cornflowerblue: '#6495ed', - cornsilk: '#fff8dc', - crimson: '#dc143c', - cyan: '#00ffff', - darkblue: '#00008b', - darkcyan: '#008b8b', - darkgoldenrod: '#b8860b', - darkgray: '#a9a9a9', - darkgrey: '#a9a9a9', - darkgreen: '#006400', - darkkhaki: '#bdb76b', - darkmagenta: '#8b008b', - darkolivegreen: '#556b2f', - darkorange: '#ff8c00', - darkorchid: '#9932cc', - darkred: '#8b0000', - darksalmon: '#e9967a', - darkseagreen: '#8fbc8f', - darkslateblue: '#483d8b', - darkslategray: '#2f4f4f', - darkslategrey: '#2f4f4f', - darkturquoise: '#00ced1', - darkviolet: '#9400d3', - deeppink: '#ff1493', - deepskyblue: '#00bfff', - dimgray: '#696969', - dimgrey: '#696969', - dodgerblue: '#1e90ff', - firebrick: '#b22222', - floralwhite: '#fffaf0', - forestgreen: '#228b22', - fuchsia: '#ff00ff', - gainsboro: '#dcdcdc', - ghostwhite: '#f8f8ff', - gold: '#ffd700', - goldenrod: '#daa520', - gray: '#808080', - grey: '#808080', - green: '#008000', - greenyellow: '#adff2f', - honeydew: '#f0fff0', - hotpink: '#ff69b4', - indianred: '#cd5c5c', - indigo: '#4b0082', - ivory: '#fffff0', - khaki: '#f0e68c', - lavender: '#e6e6fa', - lavenderblush: '#fff0f5', - lawngreen: '#7cfc00', - lemonchiffon: '#fffacd', - lightblue: '#add8e6', - lightcoral: '#f08080', - lightcyan: '#e0ffff', - lightgoldenrodyellow: '#fafad2', - lightgray: '#d3d3d3', - lightgrey: '#d3d3d3', - lightgreen: '#90ee90', - lightpink: '#ffb6c1', - lightsalmon: '#ffa07a', - lightseagreen: '#20b2aa', - lightskyblue: '#87cefa', - lightslategray: '#778899', - lightslategrey: '#778899', - lightsteelblue: '#b0c4de', - lightyellow: '#ffffe0', - lime: '#00ff00', - limegreen: '#32cd32', - linen: '#faf0e6', - magenta: '#ff00ff', - maroon: '#800000', - mediumaquamarine: '#66cdaa', - mediumblue: '#0000cd', - mediumorchid: '#ba55d3', - mediumpurple: '#9370db', - mediumseagreen: '#3cb371', - mediumslateblue: '#7b68ee', - mediumspringgreen: '#00fa9a', - mediumturquoise: '#48d1cc', - mediumvioletred: '#c71585', - midnightblue: '#191970', - mintcream: '#f5fffa', - mistyrose: '#ffe4e1', - moccasin: '#ffe4b5', - navajowhite: '#ffdead', - navy: '#000080', - oldlace: '#fdf5e6', - olive: '#808000', - olivedrab: '#6b8e23', - orange: '#ffa500', - orangered: '#ff4500', - orchid: '#da70d6', - palegoldenrod: '#eee8aa', - palegreen: '#98fb98', - paleturquoise: '#afeeee', - palevioletred: '#db7093', - papayawhip: '#ffefd5', - peachpuff: '#ffdab9', - peru: '#cd853f', - pink: '#ffc0cb', - plum: '#dda0dd', - powderblue: '#b0e0e6', - purple: '#800080', - rebeccapurple: '#663399', - red: '#ff0000', - rosybrown: '#bc8f8f', - royalblue: '#4169e1', - saddlebrown: '#8b4513', - salmon: '#fa8072', - sandybrown: '#f4a460', - seagreen: '#2e8b57', - seashell: '#fff5ee', - sienna: '#a0522d', - silver: '#c0c0c0', - skyblue: '#87ceeb', - slateblue: '#6a5acd', - slategray: '#708090', - slategrey: '#708090', - snow: '#fffafa', - springgreen: '#00ff7f', - steelblue: '#4682b4', - tan: '#d2b48c', - teal: '#008080', - thistle: '#d8bfd8', - tomato: '#ff6347', - turquoise: '#40e0d0', - violet: '#ee82ee', - wheat: '#f5deb3', - white: '#ffffff', - whitesmoke: '#f5f5f5', - yellow: '#ffff00', - yellowgreen: '#9acd32', - transparent: '#00000000', - }; - function checkColor(e) { - // 其他开发者适配的echarts会传入一个undefined到这里 - e = e || '#000000'; - var t = null; - if ((t = /^#([0-9|A-F|a-f]{6})$/.exec(e)) != null) { - const n = parseInt(t[1].slice(0, 2), 16); - const o = parseInt(t[1].slice(2, 4), 16); - const r = parseInt(t[1].slice(4), 16); - return [n, o, r, 255]; - } - if ((t = /^#([0-9|A-F|a-f]{3})$/.exec(e)) != null) { - let n = t[1].slice(0, 1); - let o = t[1].slice(1, 2); - let r = t[1].slice(2, 3); - n = parseInt(n + n, 16); - o = parseInt(o + o, 16); - r = parseInt(r + r, 16); - return [n, o, r, 255]; - } - if ((t = /^rgb\((.+)\)$/.exec(e)) != null) { - return t[1] - .split(',') - .map(function (e) { - return Math.min(255, parseInt(e.trim())); - }) - .concat(255); - } - if ((t = /^rgba\((.+)\)$/.exec(e)) != null) { - return t[1].split(',').map(function (e, t) { - return t === 3 - ? Math.floor(255 * parseFloat(e.trim())) - : Math.min(255, parseInt(e.trim())); - }); - } - var i = e.toLowerCase(); - if (shared.hasOwn(predefinedColor, i)) { - t = /^#([0-9|A-F|a-f]{6,8})$/.exec(predefinedColor[i]); - const n = parseInt(t[1].slice(0, 2), 16); - const o = parseInt(t[1].slice(2, 4), 16); - const r = parseInt(t[1].slice(4, 6), 16); - let a = parseInt(t[1].slice(6, 8), 16); - a = a >= 0 ? a : 255; - return [n, o, r, a]; - } - console.error('unsupported color:' + e); - return [0, 0, 0, 255]; - } - //#endregion - //#region Class - class CanvasGradient { - constructor(type, data) { - this.type = type; - this.data = data; - this.colorStop = []; - } - addColorStop(position, color) { - this.colorStop.push([position, checkColor(color)]); - } - } - class Pattern { - constructor(image, repetition) { - this.type = 'pattern'; - this.data = image; - this.colorStop = repetition; - } - } - class TextMetrics { - constructor(width) { - this.width = width; - } - } - class CanvasContext { - constructor(id, pageId) { - this.id = id; - this.pageId = pageId; - this.actions = []; - this.path = []; - this.subpath = []; - // this.currentTransform = [] - // this.currentStepAnimates = [] - this.drawingState = []; - this.state = { - lineDash: [0, 0], - shadowOffsetX: 0, - shadowOffsetY: 0, - shadowBlur: 0, - shadowColor: [0, 0, 0, 0], - font: '10px sans-serif', - fontSize: 10, - fontWeight: 'normal', - fontStyle: 'normal', - fontFamily: 'sans-serif', - }; - } - draw(reserve = false, callback) { - var actions = [...this.actions]; - this.actions = []; - this.path = []; - operateCanvas(this.id, this.pageId, 'actionsChanged', { - actions, - reserve, - }, callback); - } - createLinearGradient(x0, y0, x1, y1) { - return new CanvasGradient('linear', [x0, y0, x1, y1]); - } - createCircularGradient(x, y, r) { - return new CanvasGradient('radial', [x, y, r]); - } - createPattern(image, repetition) { - if (undefined === repetition) { - console.error("Failed to execute 'createPattern' on 'CanvasContext': 2 arguments required, but only 1 present."); - } - else if (['repeat', 'repeat-x', 'repeat-y', 'no-repeat'].indexOf(repetition) < 0) { - console.error("Failed to execute 'createPattern' on 'CanvasContext': The provided type ('" + - repetition + - "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'."); - } - else { - return new Pattern(image, repetition); - } - } - measureText(text) { - const font = this.state.font; - let width = 0; - { - const webview = plus.webview - .all() - .find((webview) => webview.getURL().endsWith('www/__uniappview.html')); - if (webview) { - width = Number(webview.evalJSSync(`(${measureText.toString()})(${JSON.stringify(text)},${JSON.stringify(font)})`)); - } - } - return new TextMetrics(width); - } - save() { - this.actions.push({ - method: 'save', - data: [], - }); - this.drawingState.push(this.state); - } - restore() { - this.actions.push({ - method: 'restore', - data: [], - }); - this.state = this.drawingState.pop() || { - lineDash: [0, 0], - shadowOffsetX: 0, - shadowOffsetY: 0, - shadowBlur: 0, - shadowColor: [0, 0, 0, 0], - font: '10px sans-serif', - fontSize: 10, - fontWeight: 'normal', - fontStyle: 'normal', - fontFamily: 'sans-serif', - }; - } - beginPath() { - this.path = []; - this.subpath = []; - } - moveTo(x, y) { - this.path.push({ - method: 'moveTo', - data: [x, y], - }); - this.subpath = [[x, y]]; - } - lineTo(x, y) { - if (this.path.length === 0 && this.subpath.length === 0) { - this.path.push({ - method: 'moveTo', - data: [x, y], - }); - } - else { - this.path.push({ - method: 'lineTo', - data: [x, y], - }); - } - this.subpath.push([x, y]); - } - quadraticCurveTo(cpx, cpy, x, y) { - this.path.push({ - method: 'quadraticCurveTo', - data: [cpx, cpy, x, y], - }); - this.subpath.push([x, y]); - } - bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) { - this.path.push({ - method: 'bezierCurveTo', - data: [cp1x, cp1y, cp2x, cp2y, x, y], - }); - this.subpath.push([x, y]); - } - arc(x, y, r, sAngle, eAngle, counterclockwise = false) { - this.path.push({ - method: 'arc', - data: [x, y, r, sAngle, eAngle, counterclockwise], - }); - this.subpath.push([x, y]); - } - rect(x, y, width, height) { - this.path.push({ - method: 'rect', - data: [x, y, width, height], - }); - this.subpath = [[x, y]]; - } - arcTo(x1, y1, x2, y2, radius) { - this.path.push({ - method: 'arcTo', - data: [x1, y1, x2, y2, radius], - }); - this.subpath.push([x2, y2]); - } - clip() { - this.actions.push({ - method: 'clip', - data: [...this.path], - }); - } - closePath() { - this.path.push({ - method: 'closePath', - data: [], - }); - if (this.subpath.length) { - this.subpath = [this.subpath.shift()]; - } - } - clearActions() { - this.actions = []; - this.path = []; - this.subpath = []; - } - getActions() { - var actions = [...this.actions]; - this.clearActions(); - return actions; - } - set lineDashOffset(value) { - this.actions.push({ - method: 'setLineDashOffset', - data: [value], - }); - } - set globalCompositeOperation(type) { - this.actions.push({ - method: 'setGlobalCompositeOperation', - data: [type], - }); - } - set shadowBlur(level) { - this.actions.push({ - method: 'setShadowBlur', - data: [level], - }); - } - set shadowColor(color) { - this.actions.push({ - method: 'setShadowColor', - data: [color], - }); - } - set shadowOffsetX(x) { - this.actions.push({ - method: 'setShadowOffsetX', - data: [x], - }); - } - set shadowOffsetY(y) { - this.actions.push({ - method: 'setShadowOffsetY', - data: [y], - }); - } - set font(value) { - var self = this; - this.state.font = value; - // eslint-disable-next-line - var fontFormat = value.match(/^(([\w\-]+\s)*)(\d+r?px)(\/(\d+\.?\d*(r?px)?))?\s+(.*)/); - if (fontFormat) { - var style = fontFormat[1].trim().split(/\s/); - var fontSize = parseFloat(fontFormat[3]); - var fontFamily = fontFormat[7]; - var actions = []; - style.forEach(function (value, index) { - if (['italic', 'oblique', 'normal'].indexOf(value) > -1) { - actions.push({ - method: 'setFontStyle', - data: [value], - }); - self.state.fontStyle = value; - } - else if (['bold', 'normal'].indexOf(value) > -1) { - actions.push({ - method: 'setFontWeight', - data: [value], - }); - self.state.fontWeight = value; - } - else if (index === 0) { - actions.push({ - method: 'setFontStyle', - data: ['normal'], - }); - self.state.fontStyle = 'normal'; - } - else if (index === 1) { - pushAction(); - } - }); - if (style.length === 1) { - pushAction(); - } - style = actions - .map(function (action) { - return action.data[0]; - }) - .join(' '); - this.state.fontSize = fontSize; - this.state.fontFamily = fontFamily; - this.actions.push({ - method: 'setFont', - data: [`${style} ${fontSize}px ${fontFamily}`], - }); - } - else { - console.warn("Failed to set 'font' on 'CanvasContext': invalid format."); - } - function pushAction() { - actions.push({ - method: 'setFontWeight', - data: ['normal'], - }); - self.state.fontWeight = 'normal'; - } - } - get font() { - return this.state.font; - } - set fillStyle(color) { - this.setFillStyle(color); - } - set strokeStyle(color) { - this.setStrokeStyle(color); - } - set globalAlpha(value) { - value = Math.floor(255 * parseFloat(value)); - this.actions.push({ - method: 'setGlobalAlpha', - data: [value], - }); - } - set textAlign(align) { - this.actions.push({ - method: 'setTextAlign', - data: [align], - }); - } - set lineCap(type) { - this.actions.push({ - method: 'setLineCap', - data: [type], - }); - } - set lineJoin(type) { - this.actions.push({ - method: 'setLineJoin', - data: [type], - }); - } - set lineWidth(value) { - this.actions.push({ - method: 'setLineWidth', - data: [value], - }); - } - set miterLimit(value) { - this.actions.push({ - method: 'setMiterLimit', - data: [value], - }); - } - set textBaseline(type) { - this.actions.push({ - method: 'setTextBaseline', - data: [type], - }); - } - } - const initCanvasContextProperty = /*#__PURE__*/ once(() => { - [...methods1, ...methods2].forEach(function (method) { - function get(method) { - switch (method) { - case 'fill': - case 'stroke': - return function () { - // @ts-ignore - this.actions.push({ - method: method + 'Path', - // @ts-ignore - data: [...this.path], - }); - }; - case 'fillRect': - return function (x, y, width, height) { - // @ts-ignore - this.actions.push({ - method: 'fillPath', - data: [ - { - method: 'rect', - data: [x, y, width, height], - }, - ], - }); - }; - case 'strokeRect': - return function (x, y, width, height) { - // @ts-ignore - this.actions.push({ - method: 'strokePath', - data: [ - { - method: 'rect', - data: [x, y, width, height], - }, - ], - }); - }; - case 'fillText': - case 'strokeText': - return function (text, x, y, maxWidth) { - var data = [text.toString(), x, y]; - if (typeof maxWidth === 'number') { - data.push(maxWidth); - } - // @ts-ignore - this.actions.push({ - method, - data, - }); - }; - case 'drawImage': - return function (imageResource, dx, dy, dWidth, dHeight, sx, sy, sWidth, sHeight) { - if (sHeight === undefined) { - sx = dx; - sy = dy; - sWidth = dWidth; - sHeight = dHeight; - dx = undefined; - dy = undefined; - dWidth = undefined; - dHeight = undefined; - } - var data; - function isNumber(e) { - return typeof e === 'number'; - } - data = - isNumber(dx) && - isNumber(dy) && - isNumber(dWidth) && - isNumber(dHeight) - ? [ - imageResource, - sx, - sy, - sWidth, - sHeight, - dx, - dy, - dWidth, - dHeight, - ] - : isNumber(sWidth) && isNumber(sHeight) - ? [imageResource, sx, sy, sWidth, sHeight] - : [imageResource, sx, sy]; - // @ts-ignore - this.actions.push({ - method, - data, - }); - }; - default: - return function (...data) { - // @ts-ignore - this.actions.push({ - method, - data, - }); - }; - } - } - CanvasContext.prototype[method] = get(method); - }); - methods3.forEach(function (method) { - function get(method) { - switch (method) { - case 'setFillStyle': - case 'setStrokeStyle': - return function (color) { - if (typeof color !== 'object') { - // @ts-ignore - this.actions.push({ - method, - data: ['normal', checkColor(color)], - }); - } - else { - // @ts-ignore - this.actions.push({ - method, - data: [color.type, color.data, color.colorStop], - }); - } - }; - case 'setGlobalAlpha': - return function (alpha) { - alpha = Math.floor(255 * parseFloat(alpha)); - // @ts-ignore - this.actions.push({ - method, - data: [alpha], - }); - }; - case 'setShadow': - return function (offsetX, offsetY, blur, color) { - color = checkColor(color); - // @ts-ignore - this.actions.push({ - method, - data: [offsetX, offsetY, blur, color], - }); - // @ts-ignore - this.state.shadowBlur = blur; - // @ts-ignore - this.state.shadowColor = color; - // @ts-ignore - this.state.shadowOffsetX = offsetX; - // @ts-ignore - this.state.shadowOffsetY = offsetY; - }; - case 'setLineDash': - return function (pattern, offset) { - pattern = pattern || [0, 0]; - offset = offset || 0; - // @ts-ignore - this.actions.push({ - method, - data: [pattern, offset], - }); - // @ts-ignore - this.state.lineDash = pattern; - }; - case 'setFontSize': - return function (fontSize) { - // @ts-ignore - this.state.font = this.state.font.replace(/\d+\.?\d*px/, fontSize + 'px'); - // @ts-ignore - this.state.fontSize = fontSize; - // @ts-ignore - this.actions.push({ - method, - data: [fontSize], - }); - }; - default: - return function (...data) { - // @ts-ignore - this.actions.push({ - method, - data, - }); - }; - } - } - CanvasContext.prototype[method] = get(method); - }); - }); - const createCanvasContext = defineSyncApi(API_CREATE_CANVAS_CONTEXT, (canvasId, componentInstance) => { - initCanvasContextProperty(); - if (componentInstance) { - return new CanvasContext(canvasId, getPageIdByVm(componentInstance)); - } - const pageId = getPageIdByVm(getCurrentPageVm()); - if (pageId) { - return new CanvasContext(canvasId, pageId); - } - else { - UniServiceJSBridge.emit(ON_ERROR, 'createCanvasContext:fail'); - } - }, CreateCanvasContextProtocol); - const canvasGetImageData = defineAsyncApi(API_CANVAS_GET_IMAGE_DATA, ({ canvasId, x, y, width, height }, { resolve, reject }) => { - const pageId = getPageIdByVm(getCurrentPageVm()); - if (!pageId) { - reject(); - return; - } - function callback(data) { - if (data.errMsg && data.errMsg.indexOf('fail') !== -1) { - reject('', data); - return; - } - let imgData = data.data; - if (imgData && imgData.length) { - if (data.compressed) { - imgData = pako_1.inflateRaw(imgData); - } - data.data = new Uint8ClampedArray(imgData); - } - delete data.compressed; - resolve(data); - } - operateCanvas(canvasId, pageId, 'getImageData', { - x, - y, - width, - height, - }, callback); - }, CanvasGetImageDataProtocol, CanvasGetImageDataOptions); - const canvasPutImageData = defineAsyncApi(API_CANVAS_PUT_IMAGE_DATA, ({ canvasId, data, x, y, width, height }, { resolve, reject }) => { - var pageId = getPageIdByVm(getCurrentPageVm()); - if (!pageId) { - reject(); - return; - } - let compressed; - const operate = () => { - operateCanvas(canvasId, pageId, 'putImageData', { - data, - x, - y, - width, - height, - compressed, - }, (data) => { - if (data.errMsg && data.errMsg.indexOf('fail') !== -1) { - reject(); - return; - } - resolve(data); - }); - }; - // iOS真机非调试模式压缩太慢暂时排除 - if ((plus.os.name !== 'iOS' || typeof __WEEX_DEVTOOL__ === 'boolean')) { - data = pako_1.deflateRaw(data, { to: 'string' }); - compressed = true; - } - else { - // fix ... 操作符 - data = Array.prototype.slice.call(data); - } - operate(); - }, CanvasPutImageDataProtocol, CanvasPutImageDataOptions); - const canvasToTempFilePath = defineAsyncApi(API_CANVAS_TO_TEMP_FILE_PATH, ({ x = 0, y = 0, width, height, destWidth, destHeight, canvasId, fileType, quality, }, { resolve, reject }) => { - var pageId = getPageIdByVm(getCurrentPageVm()); - if (!pageId) { - reject(); - return; - } - const dirname = `${TEMP_PATH}/canvas`; - operateCanvas(canvasId, pageId, 'toTempFilePath', { - x, - y, - width, - height, - destWidth, - destHeight, - fileType, - quality, - dirname, - }, (res) => { - if (res.errMsg && res.errMsg.indexOf('fail') !== -1) { - reject('', res); - return; - } - resolve(res); - }); - }, CanvasToTempFilePathProtocol, CanvasToTempFilePathOptions); - - //#endregion - /** - * 可以批量设置的监听事件 - */ - const innerAudioContextEventNames = [ - 'onCanplay', - 'onPlay', - 'onPause', - 'onStop', - 'onEnded', - 'onTimeUpdate', - 'onError', - 'onWaiting', - 'onSeeking', - 'onSeeked', - ]; - const innerAudioContextOffEventNames = [ - 'offCanplay', - 'offPlay', - 'offPause', - 'offStop', - 'offEnded', - 'offTimeUpdate', - 'offError', - 'offWaiting', - 'offSeeking', - 'offSeeked', - ]; - - const defaultOptions = { - thresholds: [0], - initialRatio: 0, - observeAll: false, - }; - const MARGINS = ['top', 'right', 'bottom', 'left']; - let reqComponentObserverId$1 = 1; - function normalizeRootMargin(margins = {}) { - return MARGINS.map((name) => `${Number(margins[name]) || 0}px`).join(' '); - } - class ServiceIntersectionObserver { - constructor(component, options) { - this._pageId = getPageIdByVm(component); - this._component = component; - this._options = shared.extend({}, defaultOptions, options); - } - relativeTo(selector, margins) { - this._options.relativeToSelector = selector; - this._options.rootMargin = normalizeRootMargin(margins); - return this; - } - relativeToViewport(margins) { - this._options.relativeToSelector = undefined; - this._options.rootMargin = normalizeRootMargin(margins); - return this; - } - observe(selector, callback) { - if (!shared.isFunction(callback)) { - return; - } - this._options.selector = selector; - this._reqId = reqComponentObserverId$1++; - addIntersectionObserver({ - reqId: this._reqId, - component: this._component, - options: this._options, - callback, - }, this._pageId); - } - disconnect() { - this._reqId && - removeIntersectionObserver({ reqId: this._reqId, component: this._component }, this._pageId); - } - } - const createIntersectionObserver = defineSyncApi('createIntersectionObserver', (context, options) => { - context = resolveComponentInstance(context); - if (context && !getPageIdByVm(context)) { - options = context; - context = null; - } - if (context) { - return new ServiceIntersectionObserver(context, options); - } - return new ServiceIntersectionObserver(getCurrentPageVm(), options); - }); - - let reqComponentObserverId = 1; - class ServiceMediaQueryObserver { - constructor(component) { - this._pageId = component.$page && component.$page.id; - this._component = component; - } - observe(options, callback) { - if (!shared.isFunction(callback)) { - return; - } - this._reqId = reqComponentObserverId++; - addMediaQueryObserver({ - reqId: this._reqId, - component: this._component, - options, - callback, - }, this._pageId); - } - disconnect() { - this._reqId && - removeMediaQueryObserver({ - reqId: this._reqId, - component: this._component, - }, this._pageId); - } - } - const createMediaQueryObserver = defineSyncApi('createMediaQueryObserver', (context) => { - context = resolveComponentInstance(context); - if (context && !getPageIdByVm(context)) { - context = null; - } - if (context) { - return new ServiceMediaQueryObserver(context); - } - return new ServiceMediaQueryObserver(getCurrentPageVm()); - }); - - // let eventReady = false - let index$3 = 0; - let optionsCache = {}; - function operateEditor(componentId, pageId, type, options) { - const data = { options }; - const needCallOptions = options && - ('success' in options || 'fail' in options || 'complete' in options); - if (needCallOptions) { - const callbackId = String(index$3++); - data.callbackId = callbackId; - optionsCache[callbackId] = options; - } - UniServiceJSBridge.invokeViewMethod(`editor.${componentId}`, { - type, - data, - }, pageId, ({ callbackId, data }) => { - if (needCallOptions) { - callOptions(optionsCache[callbackId], data); - delete optionsCache[callbackId]; - } - }); - } - class EditorContext { - constructor(id, pageId) { - this.id = id; - this.pageId = pageId; - } - format(name, value) { - this._exec('format', { - name, - value, - }); - } - insertDivider() { - this._exec('insertDivider'); - } - insertImage(options) { - this._exec('insertImage', options); - } - insertText(options) { - this._exec('insertText', options); - } - setContents(options) { - this._exec('setContents', options); - } - getContents(options) { - this._exec('getContents', options); - } - clear(options) { - this._exec('clear', options); - } - removeFormat(options) { - this._exec('removeFormat', options); - } - undo(options) { - this._exec('undo', options); - } - redo(options) { - this._exec('redo', options); - } - blur(options) { - this._exec('blur', options); - } - getSelectionText(options) { - this._exec('getSelectionText', options); - } - scrollIntoView(options) { - this._exec('scrollIntoView', options); - } - _exec(method, options) { - operateEditor(this.id, this.pageId, method, options); - } - } +/** + * ungzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Just shortcut to [[inflate]], because it autodetects format + * by header.content. Done for convenience. + **/ + + +var Inflate_1 = Inflate; +var inflate_2 = inflate$1; +var inflateRaw_1 = inflateRaw; +var ungzip = inflate$1; + +var inflate_1 = { + Inflate: Inflate_1, + inflate: inflate_2, + inflateRaw: inflateRaw_1, + ungzip: ungzip +}; + +var deflate = deflate_1; + +var inflate = inflate_1; + +var assign = require$$0.assign; + + + + + +var pako = {}; + +assign(pako, deflate, inflate, constants); + +var pako_1 = pako; + +const API_UPX2PX = 'upx2px'; +const Upx2pxProtocol = [ + { + name: 'upx', + type: [Number, String], + required: true, + }, +]; + +const EPS = 1e-4; +const BASE_DEVICE_WIDTH = 750; +let isIOS$1 = false; +let deviceWidth = 0; +let deviceDPR = 0; +function checkDeviceWidth() { + const { platform, pixelRatio, windowWidth } = getBaseSystemInfo(); + deviceWidth = windowWidth; + deviceDPR = pixelRatio; + isIOS$1 = platform === 'ios'; +} +function checkValue(value, defaultValue) { + const newValue = Number(value); + return isNaN(newValue) ? defaultValue : newValue; +} +const upx2px = defineSyncApi(API_UPX2PX, (number, newDeviceWidth) => { + if (deviceWidth === 0) { + checkDeviceWidth(); + } + number = Number(number); + if (number === 0) { + return 0; + } + let width = newDeviceWidth || deviceWidth; + { + const config = __uniConfig.globalStyle || {}; + // ignore rpxCalcIncludeWidth + const maxWidth = checkValue(config.rpxCalcMaxDeviceWidth, 960); + const baseWidth = checkValue(config.rpxCalcBaseDeviceWidth, 375); + width = width <= maxWidth ? width : baseWidth; + } + let result = (number / BASE_DEVICE_WIDTH) * width; + if (result < 0) { + result = -result; + } + result = Math.floor(result + EPS); + if (result === 0) { + if (deviceDPR === 1 || !isIOS$1) { + result = 1; + } + else { + result = 0.5; + } + } + return number < 0 ? -result : result; +}, Upx2pxProtocol); + +const API_ADD_INTERCEPTOR = 'addInterceptor'; +const API_REMOVE_INTERCEPTOR = 'removeInterceptor'; +const AddInterceptorProtocol = [ + { + name: 'method', + type: [String, Object], + required: true, + }, +]; +const RemoveInterceptorProtocol = AddInterceptorProtocol; + +function mergeInterceptorHook(interceptors, interceptor) { + Object.keys(interceptor).forEach((hook) => { + if (isFunction(interceptor[hook])) { + interceptors[hook] = mergeHook(interceptors[hook], interceptor[hook]); + } + }); +} +function removeInterceptorHook(interceptors, interceptor) { + if (!interceptors || !interceptor) { + return; + } + Object.keys(interceptor).forEach((hook) => { + if (isFunction(interceptor[hook])) { + removeHook(interceptors[hook], interceptor[hook]); + } + }); +} +function mergeHook(parentVal, childVal) { + const res = childVal + ? parentVal + ? parentVal.concat(childVal) + : isArray$1(childVal) + ? childVal + : [childVal] + : parentVal; + return res ? dedupeHooks(res) : res; +} +function dedupeHooks(hooks) { + const res = []; + for (let i = 0; i < hooks.length; i++) { + if (res.indexOf(hooks[i]) === -1) { + res.push(hooks[i]); + } + } + return res; +} +function removeHook(hooks, hook) { + if (!hooks) { + return; + } + const index = hooks.indexOf(hook); + if (index !== -1) { + hooks.splice(index, 1); + } +} +const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { + if (typeof method === 'string' && isPlainObject(interceptor)) { + mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); + } + else if (isPlainObject(method)) { + mergeInterceptorHook(globalInterceptors, method); + } +}, AddInterceptorProtocol); +const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { + if (typeof method === 'string') { + if (isPlainObject(interceptor)) { + removeInterceptorHook(scopedInterceptors[method], interceptor); + } + else { + delete scopedInterceptors[method]; + } + } + else if (isPlainObject(method)) { + removeInterceptorHook(globalInterceptors, method); + } +}, RemoveInterceptorProtocol); +const interceptors = {}; + +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + +const validator = [ + { + name: 'id', + type: String, + required: true, + }, +]; +/* export const API_CREATE_AUDIO_CONTEXT = 'createAudioContext' +export type API_TYPE_CREATE_AUDIO_CONTEXT = typeof uni.createAudioContext +export const CreateAudioContextProtocol = validator */ +const API_CREATE_VIDEO_CONTEXT = 'createVideoContext'; +const API_CREATE_MAP_CONTEXT = 'createMapContext'; +const CreateMapContextProtocol = validator; +const API_CREATE_CANVAS_CONTEXT = 'createCanvasContext'; +const CreateCanvasContextProtocol = [ + { + name: 'canvasId', + type: String, + required: true, + }, + { + name: 'componentInstance', + type: Object, + }, +]; +const API_CREATE_INNER_AUDIO_CONTEXT = 'createInnerAudioContext'; +const API_CREATE_LIVE_PUSHER_CONTEXT = 'createLivePusherContext'; +const CreateLivePusherContextProtocol = validator.concat({ + name: 'componentInstance', + type: Object, +}); + +const RATES = [0.5, 0.8, 1.0, 1.25, 1.5, 2.0]; +class VideoContext { + constructor(id, pageId) { + this.id = id; + this.pageId = pageId; + } + play() { + operateVideoPlayer(this.id, this.pageId, 'play'); + } + pause() { + operateVideoPlayer(this.id, this.pageId, 'pause'); + } + stop() { + operateVideoPlayer(this.id, this.pageId, 'stop'); + } + seek(position) { + operateVideoPlayer(this.id, this.pageId, 'seek', { + position, + }); + } + sendDanmu(args) { + operateVideoPlayer(this.id, this.pageId, 'sendDanmu', args); + } + playbackRate(rate) { + if (!~RATES.indexOf(rate)) { + rate = 1.0; + } + operateVideoPlayer(this.id, this.pageId, 'playbackRate', { + rate, + }); + } + requestFullScreen(args = {}) { + operateVideoPlayer(this.id, this.pageId, 'requestFullScreen', args); + } + exitFullScreen() { + operateVideoPlayer(this.id, this.pageId, 'exitFullScreen'); + } + showStatusBar() { + operateVideoPlayer(this.id, this.pageId, 'showStatusBar'); + } + hideStatusBar() { + operateVideoPlayer(this.id, this.pageId, 'hideStatusBar'); + } +} +const createVideoContext = defineSyncApi(API_CREATE_VIDEO_CONTEXT, (id, context) => { + if (context) { + return new VideoContext(id, getPageIdByVm(context)); + } + return new VideoContext(id, getPageIdByVm(getCurrentPageVm())); +}); + +const operateMapCallback = (options, res) => { + const errMsg = res.errMsg || ''; + if (new RegExp('\\:\\s*fail').test(errMsg)) { + options.fail && options.fail(res); + } + else { + options.success && options.success(res); + } + options.complete && options.complete(res); +}; +const operateMapWrap = (id, pageId, type, options) => { + operateMap(id, pageId, type, options, (res) => { + options && operateMapCallback(options, res); + }); +}; +class MapContext { + constructor(id, pageId) { + this.id = id; + this.pageId = pageId; + } + getCenterLocation(options) { + operateMapWrap(this.id, this.pageId, 'getCenterLocation', options); + } + moveToLocation(options) { + operateMapWrap(this.id, this.pageId, 'moveToLocation', options); + } + getScale(options) { + operateMapWrap(this.id, this.pageId, 'getScale', options); + } + getRegion(options) { + operateMapWrap(this.id, this.pageId, 'getRegion', options); + } + includePoints(options) { + operateMapWrap(this.id, this.pageId, 'includePoints', options); + } + translateMarker(options) { + operateMapWrap(this.id, this.pageId, 'translateMarker', options); + } + $getAppMap() { + { + return plus.maps.getMapById(this.pageId + '-map-' + this.id); + } + } + addCustomLayer(options) { + operateMapWrap(this.id, this.pageId, 'addCustomLayer', options); + } + removeCustomLayer(options) { + operateMapWrap(this.id, this.pageId, 'removeCustomLayer', options); + } + addGroundOverlay(options) { + operateMapWrap(this.id, this.pageId, 'addGroundOverlay', options); + } + removeGroundOverlay(options) { + operateMapWrap(this.id, this.pageId, 'removeGroundOverlay', options); + } + updateGroundOverlay(options) { + operateMapWrap(this.id, this.pageId, 'updateGroundOverlay', options); + } + initMarkerCluster(options) { + operateMapWrap(this.id, this.pageId, 'initMarkerCluster', options); + } + addMarkers(options) { + operateMapWrap(this.id, this.pageId, 'addMarkers', options); + } + removeMarkers(options) { + operateMapWrap(this.id, this.pageId, 'removeMarkers', options); + } + moveAlong(options) { + operateMapWrap(this.id, this.pageId, 'moveAlong', options); + } + openMapApp(options) { + operateMapWrap(this.id, this.pageId, 'openMapApp', options); + } + on(options) { + operateMapWrap(this.id, this.pageId, 'on', options); + } +} +const createMapContext = defineSyncApi(API_CREATE_MAP_CONTEXT, (id, context) => { + if (context) { + return new MapContext(id, getPageIdByVm(context)); + } + return new MapContext(id, getPageIdByVm(getCurrentPageVm())); +}, CreateMapContextProtocol); + +function getInt(name, defaultValue) { + return function (value, params) { + if (value) { + params[name] = Math.round(value); + } + else if (typeof defaultValue !== 'undefined') { + params[name] = defaultValue; + } + }; +} +const formatWidth = getInt('width'); +const formatHeight = getInt('height'); +//#region getImageDataOptions +const API_CANVAS_GET_IMAGE_DATA = 'canvasGetImageData'; +const CanvasGetImageDataOptions = { + formatArgs: { + x: getInt('x'), + y: getInt('y'), + width: formatWidth, + height: formatHeight, + }, +}; +const CanvasGetImageDataProtocol = { + canvasId: { + type: String, + required: true, + }, + x: { + type: Number, + required: true, + }, + y: { + type: Number, + required: true, + }, + width: { + type: Number, + required: true, + }, + height: { + type: Number, + required: true, + }, +}; +//#endregion +//#region putImageData +const API_CANVAS_PUT_IMAGE_DATA = 'canvasPutImageData'; +const CanvasPutImageDataOptions = CanvasGetImageDataOptions; +const CanvasPutImageDataProtocol = +/*#__PURE__*/ extend({ + data: { + type: Uint8ClampedArray, + required: true, + }, +}, CanvasGetImageDataProtocol, { + height: { + type: Number, + }, +}); +//#endregion +//#region toTempFilePath +const fileTypes = { + PNG: 'png', + JPG: 'jpg', + JPEG: 'jpg', +}; +const API_CANVAS_TO_TEMP_FILE_PATH = 'canvasToTempFilePath'; +const CanvasToTempFilePathOptions = { + formatArgs: { + x: getInt('x', 0), + y: getInt('y', 0), + width: formatWidth, + height: formatHeight, + destWidth: getInt('destWidth'), + destHeight: getInt('destHeight'), + fileType(value, params) { + value = (value || '').toUpperCase(); + let type = fileTypes[value]; + if (!type) { + type = fileTypes.PNG; + } + params.fileType = type; + }, + quality(value, params) { + params.quality = value && value > 0 && value < 1 ? value : 1; + }, + }, +}; +const CanvasToTempFilePathProtocol = { + x: Number, + y: Number, + width: Number, + height: Number, + destWidth: Number, + destHeight: Number, + canvasId: { + type: String, + required: true, + }, + fileType: String, + quality: Number, +}; + +//#region import +//#endregion +//#region UniServiceJSBridge +function operateCanvas(canvasId, pageId, type, data, callback) { + UniServiceJSBridge.invokeViewMethod(`canvas.${canvasId}`, { + type, + data, + }, pageId, (data) => { + if (callback) + callback(data); + }); +} +//#endregion +//#region methods +var methods1 = ['scale', 'rotate', 'translate', 'setTransform', 'transform']; +var methods2 = [ + 'drawImage', + 'fillText', + 'fill', + 'stroke', + 'fillRect', + 'strokeRect', + 'clearRect', + 'strokeText', +]; +var methods3 = [ + 'setFillStyle', + 'setTextAlign', + 'setStrokeStyle', + 'setGlobalAlpha', + 'setShadow', + 'setFontSize', + 'setLineCap', + 'setLineJoin', + 'setLineWidth', + 'setMiterLimit', + 'setTextBaseline', + 'setLineDash', +]; +function measureText(text, font) { + const canvas = document.createElement('canvas'); + const c2d = canvas.getContext('2d'); + c2d.font = font; + return c2d.measureText(text).width || 0; +} +//#endregion +//#region checkColor +const predefinedColor = { + aliceblue: '#f0f8ff', + antiquewhite: '#faebd7', + aqua: '#00ffff', + aquamarine: '#7fffd4', + azure: '#f0ffff', + beige: '#f5f5dc', + bisque: '#ffe4c4', + black: '#000000', + blanchedalmond: '#ffebcd', + blue: '#0000ff', + blueviolet: '#8a2be2', + brown: '#a52a2a', + burlywood: '#deb887', + cadetblue: '#5f9ea0', + chartreuse: '#7fff00', + chocolate: '#d2691e', + coral: '#ff7f50', + cornflowerblue: '#6495ed', + cornsilk: '#fff8dc', + crimson: '#dc143c', + cyan: '#00ffff', + darkblue: '#00008b', + darkcyan: '#008b8b', + darkgoldenrod: '#b8860b', + darkgray: '#a9a9a9', + darkgrey: '#a9a9a9', + darkgreen: '#006400', + darkkhaki: '#bdb76b', + darkmagenta: '#8b008b', + darkolivegreen: '#556b2f', + darkorange: '#ff8c00', + darkorchid: '#9932cc', + darkred: '#8b0000', + darksalmon: '#e9967a', + darkseagreen: '#8fbc8f', + darkslateblue: '#483d8b', + darkslategray: '#2f4f4f', + darkslategrey: '#2f4f4f', + darkturquoise: '#00ced1', + darkviolet: '#9400d3', + deeppink: '#ff1493', + deepskyblue: '#00bfff', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1e90ff', + firebrick: '#b22222', + floralwhite: '#fffaf0', + forestgreen: '#228b22', + fuchsia: '#ff00ff', + gainsboro: '#dcdcdc', + ghostwhite: '#f8f8ff', + gold: '#ffd700', + goldenrod: '#daa520', + gray: '#808080', + grey: '#808080', + green: '#008000', + greenyellow: '#adff2f', + honeydew: '#f0fff0', + hotpink: '#ff69b4', + indianred: '#cd5c5c', + indigo: '#4b0082', + ivory: '#fffff0', + khaki: '#f0e68c', + lavender: '#e6e6fa', + lavenderblush: '#fff0f5', + lawngreen: '#7cfc00', + lemonchiffon: '#fffacd', + lightblue: '#add8e6', + lightcoral: '#f08080', + lightcyan: '#e0ffff', + lightgoldenrodyellow: '#fafad2', + lightgray: '#d3d3d3', + lightgrey: '#d3d3d3', + lightgreen: '#90ee90', + lightpink: '#ffb6c1', + lightsalmon: '#ffa07a', + lightseagreen: '#20b2aa', + lightskyblue: '#87cefa', + lightslategray: '#778899', + lightslategrey: '#778899', + lightsteelblue: '#b0c4de', + lightyellow: '#ffffe0', + lime: '#00ff00', + limegreen: '#32cd32', + linen: '#faf0e6', + magenta: '#ff00ff', + maroon: '#800000', + mediumaquamarine: '#66cdaa', + mediumblue: '#0000cd', + mediumorchid: '#ba55d3', + mediumpurple: '#9370db', + mediumseagreen: '#3cb371', + mediumslateblue: '#7b68ee', + mediumspringgreen: '#00fa9a', + mediumturquoise: '#48d1cc', + mediumvioletred: '#c71585', + midnightblue: '#191970', + mintcream: '#f5fffa', + mistyrose: '#ffe4e1', + moccasin: '#ffe4b5', + navajowhite: '#ffdead', + navy: '#000080', + oldlace: '#fdf5e6', + olive: '#808000', + olivedrab: '#6b8e23', + orange: '#ffa500', + orangered: '#ff4500', + orchid: '#da70d6', + palegoldenrod: '#eee8aa', + palegreen: '#98fb98', + paleturquoise: '#afeeee', + palevioletred: '#db7093', + papayawhip: '#ffefd5', + peachpuff: '#ffdab9', + peru: '#cd853f', + pink: '#ffc0cb', + plum: '#dda0dd', + powderblue: '#b0e0e6', + purple: '#800080', + rebeccapurple: '#663399', + red: '#ff0000', + rosybrown: '#bc8f8f', + royalblue: '#4169e1', + saddlebrown: '#8b4513', + salmon: '#fa8072', + sandybrown: '#f4a460', + seagreen: '#2e8b57', + seashell: '#fff5ee', + sienna: '#a0522d', + silver: '#c0c0c0', + skyblue: '#87ceeb', + slateblue: '#6a5acd', + slategray: '#708090', + slategrey: '#708090', + snow: '#fffafa', + springgreen: '#00ff7f', + steelblue: '#4682b4', + tan: '#d2b48c', + teal: '#008080', + thistle: '#d8bfd8', + tomato: '#ff6347', + turquoise: '#40e0d0', + violet: '#ee82ee', + wheat: '#f5deb3', + white: '#ffffff', + whitesmoke: '#f5f5f5', + yellow: '#ffff00', + yellowgreen: '#9acd32', + transparent: '#00000000', +}; +function checkColor(e) { + // 其他开发者适配的echarts会传入一个undefined到这里 + e = e || '#000000'; + var t = null; + if ((t = /^#([0-9|A-F|a-f]{6})$/.exec(e)) != null) { + const n = parseInt(t[1].slice(0, 2), 16); + const o = parseInt(t[1].slice(2, 4), 16); + const r = parseInt(t[1].slice(4), 16); + return [n, o, r, 255]; + } + if ((t = /^#([0-9|A-F|a-f]{3})$/.exec(e)) != null) { + let n = t[1].slice(0, 1); + let o = t[1].slice(1, 2); + let r = t[1].slice(2, 3); + n = parseInt(n + n, 16); + o = parseInt(o + o, 16); + r = parseInt(r + r, 16); + return [n, o, r, 255]; + } + if ((t = /^rgb\((.+)\)$/.exec(e)) != null) { + return t[1] + .split(',') + .map(function (e) { + return Math.min(255, parseInt(e.trim())); + }) + .concat(255); + } + if ((t = /^rgba\((.+)\)$/.exec(e)) != null) { + return t[1].split(',').map(function (e, t) { + return t === 3 + ? Math.floor(255 * parseFloat(e.trim())) + : Math.min(255, parseInt(e.trim())); + }); + } + var i = e.toLowerCase(); + if (hasOwn$1(predefinedColor, i)) { + t = /^#([0-9|A-F|a-f]{6,8})$/.exec(predefinedColor[i]); + const n = parseInt(t[1].slice(0, 2), 16); + const o = parseInt(t[1].slice(2, 4), 16); + const r = parseInt(t[1].slice(4, 6), 16); + let a = parseInt(t[1].slice(6, 8), 16); + a = a >= 0 ? a : 255; + return [n, o, r, a]; + } + console.error('unsupported color:' + e); + return [0, 0, 0, 255]; +} +//#endregion +//#region Class +class CanvasGradient { + constructor(type, data) { + this.type = type; + this.data = data; + this.colorStop = []; + } + addColorStop(position, color) { + this.colorStop.push([position, checkColor(color)]); + } +} +class Pattern { + constructor(image, repetition) { + this.type = 'pattern'; + this.data = image; + this.colorStop = repetition; + } +} +class TextMetrics { + constructor(width) { + this.width = width; + } +} +class CanvasContext { + constructor(id, pageId) { + this.id = id; + this.pageId = pageId; + this.actions = []; + this.path = []; + this.subpath = []; + // this.currentTransform = [] + // this.currentStepAnimates = [] + this.drawingState = []; + this.state = { + lineDash: [0, 0], + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowBlur: 0, + shadowColor: [0, 0, 0, 0], + font: '10px sans-serif', + fontSize: 10, + fontWeight: 'normal', + fontStyle: 'normal', + fontFamily: 'sans-serif', + }; + } + draw(reserve = false, callback) { + var actions = [...this.actions]; + this.actions = []; + this.path = []; + operateCanvas(this.id, this.pageId, 'actionsChanged', { + actions, + reserve, + }, callback); + } + createLinearGradient(x0, y0, x1, y1) { + return new CanvasGradient('linear', [x0, y0, x1, y1]); + } + createCircularGradient(x, y, r) { + return new CanvasGradient('radial', [x, y, r]); + } + createPattern(image, repetition) { + if (undefined === repetition) { + console.error("Failed to execute 'createPattern' on 'CanvasContext': 2 arguments required, but only 1 present."); + } + else if (['repeat', 'repeat-x', 'repeat-y', 'no-repeat'].indexOf(repetition) < 0) { + console.error("Failed to execute 'createPattern' on 'CanvasContext': The provided type ('" + + repetition + + "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'."); + } + else { + return new Pattern(image, repetition); + } + } + measureText(text) { + const font = this.state.font; + let width = 0; + { + const webview = plus.webview + .all() + .find((webview) => webview.getURL().endsWith('www/__uniappview.html')); + if (webview) { + width = Number(webview.evalJSSync(`(${measureText.toString()})(${JSON.stringify(text)},${JSON.stringify(font)})`)); + } + } + return new TextMetrics(width); + } + save() { + this.actions.push({ + method: 'save', + data: [], + }); + this.drawingState.push(this.state); + } + restore() { + this.actions.push({ + method: 'restore', + data: [], + }); + this.state = this.drawingState.pop() || { + lineDash: [0, 0], + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowBlur: 0, + shadowColor: [0, 0, 0, 0], + font: '10px sans-serif', + fontSize: 10, + fontWeight: 'normal', + fontStyle: 'normal', + fontFamily: 'sans-serif', + }; + } + beginPath() { + this.path = []; + this.subpath = []; + } + moveTo(x, y) { + this.path.push({ + method: 'moveTo', + data: [x, y], + }); + this.subpath = [[x, y]]; + } + lineTo(x, y) { + if (this.path.length === 0 && this.subpath.length === 0) { + this.path.push({ + method: 'moveTo', + data: [x, y], + }); + } + else { + this.path.push({ + method: 'lineTo', + data: [x, y], + }); + } + this.subpath.push([x, y]); + } + quadraticCurveTo(cpx, cpy, x, y) { + this.path.push({ + method: 'quadraticCurveTo', + data: [cpx, cpy, x, y], + }); + this.subpath.push([x, y]); + } + bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) { + this.path.push({ + method: 'bezierCurveTo', + data: [cp1x, cp1y, cp2x, cp2y, x, y], + }); + this.subpath.push([x, y]); + } + arc(x, y, r, sAngle, eAngle, counterclockwise = false) { + this.path.push({ + method: 'arc', + data: [x, y, r, sAngle, eAngle, counterclockwise], + }); + this.subpath.push([x, y]); + } + rect(x, y, width, height) { + this.path.push({ + method: 'rect', + data: [x, y, width, height], + }); + this.subpath = [[x, y]]; + } + arcTo(x1, y1, x2, y2, radius) { + this.path.push({ + method: 'arcTo', + data: [x1, y1, x2, y2, radius], + }); + this.subpath.push([x2, y2]); + } + clip() { + this.actions.push({ + method: 'clip', + data: [...this.path], + }); + } + closePath() { + this.path.push({ + method: 'closePath', + data: [], + }); + if (this.subpath.length) { + this.subpath = [this.subpath.shift()]; + } + } + clearActions() { + this.actions = []; + this.path = []; + this.subpath = []; + } + getActions() { + var actions = [...this.actions]; + this.clearActions(); + return actions; + } + set lineDashOffset(value) { + this.actions.push({ + method: 'setLineDashOffset', + data: [value], + }); + } + set globalCompositeOperation(type) { + this.actions.push({ + method: 'setGlobalCompositeOperation', + data: [type], + }); + } + set shadowBlur(level) { + this.actions.push({ + method: 'setShadowBlur', + data: [level], + }); + } + set shadowColor(color) { + this.actions.push({ + method: 'setShadowColor', + data: [color], + }); + } + set shadowOffsetX(x) { + this.actions.push({ + method: 'setShadowOffsetX', + data: [x], + }); + } + set shadowOffsetY(y) { + this.actions.push({ + method: 'setShadowOffsetY', + data: [y], + }); + } + set font(value) { + var self = this; + this.state.font = value; + // eslint-disable-next-line + var fontFormat = value.match(/^(([\w\-]+\s)*)(\d+r?px)(\/(\d+\.?\d*(r?px)?))?\s+(.*)/); + if (fontFormat) { + var style = fontFormat[1].trim().split(/\s/); + var fontSize = parseFloat(fontFormat[3]); + var fontFamily = fontFormat[7]; + var actions = []; + style.forEach(function (value, index) { + if (['italic', 'oblique', 'normal'].indexOf(value) > -1) { + actions.push({ + method: 'setFontStyle', + data: [value], + }); + self.state.fontStyle = value; + } + else if (['bold', 'normal'].indexOf(value) > -1) { + actions.push({ + method: 'setFontWeight', + data: [value], + }); + self.state.fontWeight = value; + } + else if (index === 0) { + actions.push({ + method: 'setFontStyle', + data: ['normal'], + }); + self.state.fontStyle = 'normal'; + } + else if (index === 1) { + pushAction(); + } + }); + if (style.length === 1) { + pushAction(); + } + style = actions + .map(function (action) { + return action.data[0]; + }) + .join(' '); + this.state.fontSize = fontSize; + this.state.fontFamily = fontFamily; + this.actions.push({ + method: 'setFont', + data: [`${style} ${fontSize}px ${fontFamily}`], + }); + } + else { + console.warn("Failed to set 'font' on 'CanvasContext': invalid format."); + } + function pushAction() { + actions.push({ + method: 'setFontWeight', + data: ['normal'], + }); + self.state.fontWeight = 'normal'; + } + } + get font() { + return this.state.font; + } + set fillStyle(color) { + this.setFillStyle(color); + } + set strokeStyle(color) { + this.setStrokeStyle(color); + } + set globalAlpha(value) { + value = Math.floor(255 * parseFloat(value)); + this.actions.push({ + method: 'setGlobalAlpha', + data: [value], + }); + } + set textAlign(align) { + this.actions.push({ + method: 'setTextAlign', + data: [align], + }); + } + set lineCap(type) { + this.actions.push({ + method: 'setLineCap', + data: [type], + }); + } + set lineJoin(type) { + this.actions.push({ + method: 'setLineJoin', + data: [type], + }); + } + set lineWidth(value) { + this.actions.push({ + method: 'setLineWidth', + data: [value], + }); + } + set miterLimit(value) { + this.actions.push({ + method: 'setMiterLimit', + data: [value], + }); + } + set textBaseline(type) { + this.actions.push({ + method: 'setTextBaseline', + data: [type], + }); + } +} +const initCanvasContextProperty = /*#__PURE__*/ once(() => { + [...methods1, ...methods2].forEach(function (method) { + function get(method) { + switch (method) { + case 'fill': + case 'stroke': + return function () { + // @ts-ignore + this.actions.push({ + method: method + 'Path', + // @ts-ignore + data: [...this.path], + }); + }; + case 'fillRect': + return function (x, y, width, height) { + // @ts-ignore + this.actions.push({ + method: 'fillPath', + data: [ + { + method: 'rect', + data: [x, y, width, height], + }, + ], + }); + }; + case 'strokeRect': + return function (x, y, width, height) { + // @ts-ignore + this.actions.push({ + method: 'strokePath', + data: [ + { + method: 'rect', + data: [x, y, width, height], + }, + ], + }); + }; + case 'fillText': + case 'strokeText': + return function (text, x, y, maxWidth) { + var data = [text.toString(), x, y]; + if (typeof maxWidth === 'number') { + data.push(maxWidth); + } + // @ts-ignore + this.actions.push({ + method, + data, + }); + }; + case 'drawImage': + return function (imageResource, dx, dy, dWidth, dHeight, sx, sy, sWidth, sHeight) { + if (sHeight === undefined) { + sx = dx; + sy = dy; + sWidth = dWidth; + sHeight = dHeight; + dx = undefined; + dy = undefined; + dWidth = undefined; + dHeight = undefined; + } + var data; + function isNumber(e) { + return typeof e === 'number'; + } + data = + isNumber(dx) && + isNumber(dy) && + isNumber(dWidth) && + isNumber(dHeight) + ? [ + imageResource, + sx, + sy, + sWidth, + sHeight, + dx, + dy, + dWidth, + dHeight, + ] + : isNumber(sWidth) && isNumber(sHeight) + ? [imageResource, sx, sy, sWidth, sHeight] + : [imageResource, sx, sy]; + // @ts-ignore + this.actions.push({ + method, + data, + }); + }; + default: + return function (...data) { + // @ts-ignore + this.actions.push({ + method, + data, + }); + }; + } + } + CanvasContext.prototype[method] = get(method); + }); + methods3.forEach(function (method) { + function get(method) { + switch (method) { + case 'setFillStyle': + case 'setStrokeStyle': + return function (color) { + if (typeof color !== 'object') { + // @ts-ignore + this.actions.push({ + method, + data: ['normal', checkColor(color)], + }); + } + else { + // @ts-ignore + this.actions.push({ + method, + data: [color.type, color.data, color.colorStop], + }); + } + }; + case 'setGlobalAlpha': + return function (alpha) { + alpha = Math.floor(255 * parseFloat(alpha)); + // @ts-ignore + this.actions.push({ + method, + data: [alpha], + }); + }; + case 'setShadow': + return function (offsetX, offsetY, blur, color) { + color = checkColor(color); + // @ts-ignore + this.actions.push({ + method, + data: [offsetX, offsetY, blur, color], + }); + // @ts-ignore + this.state.shadowBlur = blur; + // @ts-ignore + this.state.shadowColor = color; + // @ts-ignore + this.state.shadowOffsetX = offsetX; + // @ts-ignore + this.state.shadowOffsetY = offsetY; + }; + case 'setLineDash': + return function (pattern, offset) { + pattern = pattern || [0, 0]; + offset = offset || 0; + // @ts-ignore + this.actions.push({ + method, + data: [pattern, offset], + }); + // @ts-ignore + this.state.lineDash = pattern; + }; + case 'setFontSize': + return function (fontSize) { + // @ts-ignore + this.state.font = this.state.font.replace(/\d+\.?\d*px/, fontSize + 'px'); + // @ts-ignore + this.state.fontSize = fontSize; + // @ts-ignore + this.actions.push({ + method, + data: [fontSize], + }); + }; + default: + return function (...data) { + // @ts-ignore + this.actions.push({ + method, + data, + }); + }; + } + } + CanvasContext.prototype[method] = get(method); + }); +}); +const createCanvasContext = defineSyncApi(API_CREATE_CANVAS_CONTEXT, (canvasId, componentInstance) => { + initCanvasContextProperty(); + if (componentInstance) { + return new CanvasContext(canvasId, getPageIdByVm(componentInstance)); + } + const pageId = getPageIdByVm(getCurrentPageVm()); + if (pageId) { + return new CanvasContext(canvasId, pageId); + } + else { + UniServiceJSBridge.emit(ON_ERROR, 'createCanvasContext:fail'); + } +}, CreateCanvasContextProtocol); +const canvasGetImageData = defineAsyncApi(API_CANVAS_GET_IMAGE_DATA, ({ canvasId, x, y, width, height }, { resolve, reject }) => { + const pageId = getPageIdByVm(getCurrentPageVm()); + if (!pageId) { + reject(); + return; + } + function callback(data) { + if (data.errMsg && data.errMsg.indexOf('fail') !== -1) { + reject('', data); + return; + } + let imgData = data.data; + if (imgData && imgData.length) { + if (data.compressed) { + imgData = pako_1.inflateRaw(imgData); + } + data.data = new Uint8ClampedArray(imgData); + } + delete data.compressed; + resolve(data); + } + operateCanvas(canvasId, pageId, 'getImageData', { + x, + y, + width, + height, + }, callback); +}, CanvasGetImageDataProtocol, CanvasGetImageDataOptions); +const canvasPutImageData = defineAsyncApi(API_CANVAS_PUT_IMAGE_DATA, ({ canvasId, data, x, y, width, height }, { resolve, reject }) => { + var pageId = getPageIdByVm(getCurrentPageVm()); + if (!pageId) { + reject(); + return; + } + let compressed; + const operate = () => { + operateCanvas(canvasId, pageId, 'putImageData', { + data, + x, + y, + width, + height, + compressed, + }, (data) => { + if (data.errMsg && data.errMsg.indexOf('fail') !== -1) { + reject(); + return; + } + resolve(data); + }); + }; + // iOS真机非调试模式压缩太慢暂时排除 + if ((plus.os.name !== 'iOS' || typeof __WEEX_DEVTOOL__ === 'boolean')) { + data = pako_1.deflateRaw(data, { to: 'string' }); + compressed = true; + } + else { + // fix ... 操作符 + data = Array.prototype.slice.call(data); + } + operate(); +}, CanvasPutImageDataProtocol, CanvasPutImageDataOptions); +const canvasToTempFilePath = defineAsyncApi(API_CANVAS_TO_TEMP_FILE_PATH, ({ x = 0, y = 0, width, height, destWidth, destHeight, canvasId, fileType, quality, }, { resolve, reject }) => { + var pageId = getPageIdByVm(getCurrentPageVm()); + if (!pageId) { + reject(); + return; + } + const dirname = `${TEMP_PATH}/canvas`; + operateCanvas(canvasId, pageId, 'toTempFilePath', { + x, + y, + width, + height, + destWidth, + destHeight, + fileType, + quality, + dirname, + }, (res) => { + if (res.errMsg && res.errMsg.indexOf('fail') !== -1) { + reject('', res); + return; + } + resolve(res); + }); +}, CanvasToTempFilePathProtocol, CanvasToTempFilePathOptions); + +//#endregion +/** + * 可以批量设置的监听事件 + */ +const innerAudioContextEventNames = [ + 'onCanplay', + 'onPlay', + 'onPause', + 'onStop', + 'onEnded', + 'onTimeUpdate', + 'onError', + 'onWaiting', + 'onSeeking', + 'onSeeked', +]; +const innerAudioContextOffEventNames = [ + 'offCanplay', + 'offPlay', + 'offPause', + 'offStop', + 'offEnded', + 'offTimeUpdate', + 'offError', + 'offWaiting', + 'offSeeking', + 'offSeeked', +]; + +const defaultOptions = { + thresholds: [0], + initialRatio: 0, + observeAll: false, +}; +const MARGINS = ['top', 'right', 'bottom', 'left']; +let reqComponentObserverId$1 = 1; +function normalizeRootMargin(margins = {}) { + return MARGINS.map((name) => `${Number(margins[name]) || 0}px`).join(' '); +} +class ServiceIntersectionObserver { + constructor(component, options) { + this._pageId = getPageIdByVm(component); + this._component = component; + this._options = extend({}, defaultOptions, options); + } + relativeTo(selector, margins) { + this._options.relativeToSelector = selector; + this._options.rootMargin = normalizeRootMargin(margins); + return this; + } + relativeToViewport(margins) { + this._options.relativeToSelector = undefined; + this._options.rootMargin = normalizeRootMargin(margins); + return this; + } + observe(selector, callback) { + if (!isFunction(callback)) { + return; + } + this._options.selector = selector; + this._reqId = reqComponentObserverId$1++; + addIntersectionObserver({ + reqId: this._reqId, + component: this._component, + options: this._options, + callback, + }, this._pageId); + } + disconnect() { + this._reqId && + removeIntersectionObserver({ reqId: this._reqId, component: this._component }, this._pageId); + } +} +const createIntersectionObserver = defineSyncApi('createIntersectionObserver', (context, options) => { + context = resolveComponentInstance(context); + if (context && !getPageIdByVm(context)) { + options = context; + context = null; + } + if (context) { + return new ServiceIntersectionObserver(context, options); + } + return new ServiceIntersectionObserver(getCurrentPageVm(), options); +}); + +let reqComponentObserverId = 1; +class ServiceMediaQueryObserver { + constructor(component) { + this._pageId = component.$page && component.$page.id; + this._component = component; + } + observe(options, callback) { + if (!isFunction(callback)) { + return; + } + this._reqId = reqComponentObserverId++; + addMediaQueryObserver({ + reqId: this._reqId, + component: this._component, + options, + callback, + }, this._pageId); + } + disconnect() { + this._reqId && + removeMediaQueryObserver({ + reqId: this._reqId, + component: this._component, + }, this._pageId); + } +} +const createMediaQueryObserver = defineSyncApi('createMediaQueryObserver', (context) => { + context = resolveComponentInstance(context); + if (context && !getPageIdByVm(context)) { + context = null; + } + if (context) { + return new ServiceMediaQueryObserver(context); + } + return new ServiceMediaQueryObserver(getCurrentPageVm()); +}); + +// let eventReady = false +let index$3 = 0; +let optionsCache = {}; +function operateEditor(componentId, pageId, type, options) { + const data = { options }; + const needCallOptions = options && + ('success' in options || 'fail' in options || 'complete' in options); + if (needCallOptions) { + const callbackId = String(index$3++); + data.callbackId = callbackId; + optionsCache[callbackId] = options; + } + UniServiceJSBridge.invokeViewMethod(`editor.${componentId}`, { + type, + data, + }, pageId, ({ callbackId, data }) => { + if (needCallOptions) { + callOptions(optionsCache[callbackId], data); + delete optionsCache[callbackId]; + } + }); +} +class EditorContext { + constructor(id, pageId) { + this.id = id; + this.pageId = pageId; + } + format(name, value) { + this._exec('format', { + name, + value, + }); + } + insertDivider() { + this._exec('insertDivider'); + } + insertImage(options) { + this._exec('insertImage', options); + } + insertText(options) { + this._exec('insertText', options); + } + setContents(options) { + this._exec('setContents', options); + } + getContents(options) { + this._exec('getContents', options); + } + clear(options) { + this._exec('clear', options); + } + removeFormat(options) { + this._exec('removeFormat', options); + } + undo(options) { + this._exec('undo', options); + } + redo(options) { + this._exec('redo', options); + } + blur(options) { + this._exec('blur', options); + } + getSelectionText(options) { + this._exec('getSelectionText', options); + } + scrollIntoView(options) { + this._exec('scrollIntoView', options); + } + _exec(method, options) { + operateEditor(this.id, this.pageId, method, options); + } +} - const ContextClasss = { - canvas: CanvasContext, - map: MapContext, - video: VideoContext, - editor: EditorContext, - }; - function convertContext(result) { - if (result && result.contextInfo) { - const { id, type, page } = result.contextInfo; - const ContextClass = ContextClasss[type]; - result.context = new ContextClass(id, page); - delete result.contextInfo; - } - } - class NodesRef { - constructor(selectorQuery, component, selector, single) { - this._selectorQuery = selectorQuery; - this._component = component; - this._selector = selector; - this._single = single; - } - boundingClientRect(callback) { - this._selectorQuery._push(this._selector, this._component, this._single, { - id: true, - dataset: true, - rect: true, - size: true, - }, callback); - return this._selectorQuery; - } - fields(fields, callback) { - this._selectorQuery._push(this._selector, this._component, this._single, fields, callback); - return this._selectorQuery; - } - scrollOffset(callback) { - this._selectorQuery._push(this._selector, this._component, this._single, { - id: true, - dataset: true, - scrollOffset: true, - }, callback); - return this._selectorQuery; - } - context(callback) { - this._selectorQuery._push(this._selector, this._component, this._single, { - context: true, - }, callback); - return this._selectorQuery; - } - node(_callback) { - // TODO - return this._selectorQuery; - } - } - class SelectorQuery { - constructor(page) { - this._component = undefined; - this._page = page; - this._queue = []; - this._queueCb = []; - } - exec(callback) { - requestComponentInfo(this._page, this._queue, (res) => { - const queueCbs = this._queueCb; - res.forEach((result, index) => { - if (Array.isArray(result)) { - result.forEach(convertContext); - } - else { - convertContext(result); - } - const queueCb = queueCbs[index]; - if (typeof queueCb === 'function') { - queueCb.call(this, result); - } - }); - // isFn(callback) && - if (typeof callback === 'function') { - callback.call(this, res); - } - }); - // TODO - return this._nodesRef; - } - in(component) { - this._component = resolveComponentInstance(component); - return this; - } - select(selector) { - return (this._nodesRef = new NodesRef(this, this._component, selector, true)); - } - selectAll(selector) { - return (this._nodesRef = new NodesRef(this, this._component, selector, false)); - } - selectViewport() { - return (this._nodesRef = new NodesRef(this, null, '', true)); - } - _push(selector, component, single, fields, callback) { - this._queue.push({ - component, - selector, - single, - fields, - }); - this._queueCb.push(callback); - } - } - const createSelectorQuery = (defineSyncApi('createSelectorQuery', (context) => { - context = resolveComponentInstance(context); - if (context && !getPageIdByVm(context)) { - context = null; - } - return new SelectorQuery(context || getCurrentPageVm()); - })); - - // import { elemInArray } from '../../helpers/protocol' - const API_CREATE_ANIMATION = 'createAnimation'; - // const timingFunctions: API_TYPE_CREATE_ANIMATION_Timing_Function[] = [ - // 'linear', - // 'ease', - // 'ease-in', - // 'ease-in-out', - // 'ease-out', - // 'step-start', - // 'step-end', - // ] - const CreateAnimationOptions = { - // 目前参数校验不支持此api校验 - formatArgs: { - /* duration: 400, - timingFunction(timingFunction, params) { - params.timingFunction = elemInArray(timingFunction, timingFunctions) - }, - delay: 0, - transformOrigin: '50% 50% 0', */ - }, - }; - const CreateAnimationProtocol = { - duration: Number, - timingFunction: String, - delay: Number, - transformOrigin: String, - }; - - const defaultOption = { - duration: 400, - timingFunction: 'linear', - delay: 0, - transformOrigin: '50% 50% 0', - }; - class MPAnimation { - constructor(option) { - this.actions = []; - this.currentTransform = {}; - this.currentStepAnimates = []; - this.option = shared.extend({}, defaultOption, option); - } - _getOption(option) { - const _option = { - transition: shared.extend({}, this.option, option), - transformOrigin: '', - }; - _option.transformOrigin = _option.transition.transformOrigin; - delete _option.transition.transformOrigin; - return _option; - } - _pushAnimates(type, args) { - this.currentStepAnimates.push({ - type: type, - args: args, - }); - } - _converType(type) { - return type.replace(/[A-Z]/g, (text) => { - return `-${text.toLowerCase()}`; - }); - } - _getValue(value) { - return typeof value === 'number' ? `${value}px` : value; - } - export() { - const actions = this.actions; - this.actions = []; - return { - actions, - }; - } - step(option) { - this.currentStepAnimates.forEach((animate) => { - if (animate.type !== 'style') { - this.currentTransform[animate.type] = animate; - } - else { - this.currentTransform[`${animate.type}.${animate.args[0]}`] = animate; - } - }); - this.actions.push({ - animates: Object.values(this.currentTransform), - option: this._getOption(option), - }); - this.currentStepAnimates = []; - return this; - } - } - const initAnimationProperty = /*#__PURE__*/ once(() => { - const animateTypes1 = [ - 'matrix', - 'matrix3d', - 'rotate', - 'rotate3d', - 'rotateX', - 'rotateY', - 'rotateZ', - 'scale', - 'scale3d', - 'scaleX', - 'scaleY', - 'scaleZ', - 'skew', - 'skewX', - 'skewY', - 'translate', - 'translate3d', - 'translateX', - 'translateY', - 'translateZ', - ]; - const animateTypes2 = ['opacity', 'backgroundColor']; - const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']; - animateTypes1.concat(animateTypes2, animateTypes3).forEach((type) => { - MPAnimation.prototype[type] = function (...args) { - if (animateTypes2.concat(animateTypes3).includes(type)) { - this._pushAnimates('style', [ - this._converType(type), - animateTypes3.includes(type) ? this._getValue(args[0]) : args[0], - ]); - } - else { - this._pushAnimates(type, args); - } - return this; - }; - }); - }); - const createAnimation = defineSyncApi(API_CREATE_ANIMATION, (option) => { - initAnimationProperty(); - return new MPAnimation(option); - }, CreateAnimationProtocol, CreateAnimationOptions); - - const API_ON_TAB_BAR_MID_BUTTON_TAP = 'onTabBarMidButtonTap'; - const onTabBarMidButtonTap = defineOnApi(API_ON_TAB_BAR_MID_BUTTON_TAP, () => { - // noop - }); - - const API_ON_WINDOW_RESIZE = 'onWindowResize'; - const API_OFF_WINDOW_RESIZE = 'offWindowResize'; - - /** - * 监听窗口大小变化 - */ - const onWindowResize = defineOnApi(API_ON_WINDOW_RESIZE, () => { - // 生命周期包括onResize,框架直接监听resize - // window.addEventListener('resize', onResize) - }); - /** - * 取消监听窗口大小变化 - */ - const offWindowResize = defineOffApi(API_OFF_WINDOW_RESIZE, () => { - // window.removeEventListener('resize', onResize) - }); - - const API_SET_LOCALE = 'setLocale'; - const API_GET_LOCALE = 'getLocale'; - const API_ON_LOCALE_CHANGE = 'onLocaleChange'; - const getLocale = defineSyncApi(API_GET_LOCALE, () => { - // 优先使用 $locale - const app = getApp({ allowDefault: true }); - if (app && app.$vm) { - return app.$vm.$locale; - } - return useI18n().getLocale(); - }); - const onLocaleChange = defineOnApi(API_ON_LOCALE_CHANGE, () => { }); - const setLocale = defineSyncApi(API_SET_LOCALE, (locale) => { - const app = getApp(); - if (!app) { - return false; - } - const oldLocale = app.$vm.$locale; - if (oldLocale !== locale) { - app.$vm.$locale = locale; - { - const pages = getCurrentPages(); - pages.forEach((page) => { - UniServiceJSBridge.publishHandler(API_SET_LOCALE, locale, page.$page.id); - }); - weex.requireModule('plus').setLanguage(locale); - } - // 执行 uni.onLocaleChange - UniServiceJSBridge.invokeOnCallback(API_ON_LOCALE_CHANGE, { locale }); - return true; - } - return false; - }); - - const API_SET_PAGE_META = 'setPageMeta'; - const setPageMeta = defineAsyncApi(API_SET_PAGE_META, (options, { resolve }) => { - resolve(setCurrentPageMeta(getCurrentPageVm(), options)); - }); - - const API_GET_SELECTED_TEXT_RANGE = 'getSelectedTextRange'; - - const getSelectedTextRange = defineAsyncApi(API_GET_SELECTED_TEXT_RANGE, (_, { resolve, reject }) => { - UniServiceJSBridge.invokeViewMethod('getSelectedTextRange', {}, getCurrentPageId(), (res) => { - if (typeof res.end === 'undefined' && - typeof res.start === 'undefined') { - reject('no focused'); - } - else { - resolve(res); - } - }); - }); - - const appLaunchHooks = []; - function onAppLaunch(hook) { - const app = getApp({ allowDefault: true }); - if (app && app.$vm) { - return vue.injectHook(ON_LAUNCH, hook, app.$vm.$); - } - appLaunchHooks.push(hook); - } - function injectAppLaunchHooks(appInstance) { - appLaunchHooks.forEach((hook) => { - vue.injectHook(ON_LAUNCH, hook, appInstance); - }); - } - const API_GET_ENTER_OPTIONS_SYNC = 'getEnterOptionsSync'; - const getEnterOptionsSync = defineSyncApi(API_GET_ENTER_OPTIONS_SYNC, () => { - return getEnterOptions(); - }); - const API_GET_LAUNCH_OPTIONS_SYNC = 'getLaunchOptionsSync'; - const getLaunchOptionsSync = defineSyncApi(API_GET_LAUNCH_OPTIONS_SYNC, () => { - return getLaunchOptions(); - }); - - let cid = ''; - /** - * @private - * @param args - */ - function invokePushCallback(args) { - if (args.type === 'clientId') { - cid = args.cid; - invokeGetPushCidCallbacks(cid); - } - else if (args.type === 'pushMsg') { - onPushMessageCallbacks.forEach((callback) => { - callback({ data: args.message }); - }); - } - } - const getPushCidCallbacks = []; - function invokeGetPushCidCallbacks(cid) { - getPushCidCallbacks.forEach((callback) => { - callback(cid); - }); - getPushCidCallbacks.length = 0; - } - function getPushCid(args) { - if (!shared.isPlainObject(args)) { - args = {}; - } - const { success, fail, complete } = getApiCallbacks(args); - const hasSuccess = shared.isFunction(success); - const hasFail = shared.isFunction(fail); - const hasComplete = shared.isFunction(complete); - getPushCidCallbacks.push((cid) => { - let res; - if (cid) { - res = { errMsg: 'getPushCid:ok', cid }; - hasSuccess && success(res); - } - else { - res = { errMsg: 'getPushCid:fail' }; - hasFail && fail(res); - } - hasComplete && complete(res); - }); - if (cid) { - Promise.resolve().then(() => invokeGetPushCidCallbacks(cid)); - } - } - const onPushMessageCallbacks = []; - // 不使用 defineOnApi 实现,是因为 defineOnApi 依赖 UniServiceJSBridge ,该对象目前在小程序上未提供,故简单实现 - const onPushMessage = (fn) => { - if (onPushMessageCallbacks.indexOf(fn) === -1) { - onPushMessageCallbacks.push(fn); - } - }; - const offPushMessage = (fn) => { - if (!fn) { - onPushMessageCallbacks.length = 0; - } - else { - const index = onPushMessageCallbacks.indexOf(fn); - if (index > -1) { - onPushMessageCallbacks.splice(index, 1); - } - } - }; - - const API_GET_BACKGROUND_AUDIO_MANAGER = 'getBackgroundAudioManager'; - - const API_MAKE_PHONE_CALL = 'makePhoneCall'; - const MakePhoneCallProtocol = { - phoneNumber: String, - }; - - const API_ADD_PHONE_CONTACT = 'addPhoneContact'; - const AddPhoneContactOptions = { - formatArgs: { - firstName(firstName) { - if (!firstName) - return 'addPhoneContact:fail parameter error: parameter.firstName should not be empty;'; - }, - }, - }; - const AddPhoneContactProtocol = { - firstName: { - type: String, - required: true, - }, - photoFilePath: String, - nickName: String, - lastName: String, - middleName: String, - remark: String, - mobilePhoneNumber: String, - weChatNumber: String, - addressCountry: String, - addressState: String, - addressCity: String, - addressStreet: String, - addressPostalCode: String, - organization: String, - title: String, - workFaxNumber: String, - workPhoneNumber: String, - hostNumber: String, - email: String, - url: String, - workAddressCountry: String, - workAddressState: String, - workAddressCity: String, - workAddressStreet: String, - workAddressPostalCode: String, - homeFaxNumber: String, - homePhoneNumber: String, - homeAddressCountry: String, - homeAddressState: String, - homeAddressCity: String, - homeAddressStreet: String, - homeAddressPostalCode: String, - }; - - const API_GET_CLIPBOARD_DATA = 'getClipboardData'; - const API_SET_CLIPBOARD_DATA = 'setClipboardData'; - const SetClipboardDataOptions = { - formatArgs: { - showToast: true, - }, - beforeInvoke() { - initI18nSetClipboardDataMsgsOnce(); - }, - beforeSuccess(res, params) { - if (!params.showToast) - return; - const { t } = useI18n(); - const title = t('uni.setClipboardData.success'); - if (title) { - uni.showToast({ - title: title, - icon: 'success', - mask: false, - }); - } - }, - }; - const SetClipboardDataProtocol = { - data: { - type: String, - required: true, - }, - showToast: { - type: Boolean, - }, - }; - - const API_ON_ACCELEROMETER = 'onAccelerometer'; - const API_OFF_ACCELEROMETER = 'offAccelerometer'; - const API_START_ACCELEROMETER = 'startAccelerometer'; - const API_STOP_ACCELEROMETER = 'stopAccelerometer'; - - const API_ON_COMPASS = 'onCompass'; - const API_OFF_COMPASS = 'offCompass'; - const API_START_COMPASS = 'startCompass'; - const API_STOP_COMPASS = 'stopCompass'; - - const API_VIBRATE_SHORT = 'vibrateShort'; - const API_VIBRATE_LONG = 'vibrateLong'; - - const API_ON_BLUETOOTH_DEVICE_FOUND = 'onBluetoothDeviceFound'; - const API_ON_BLUETOOTH_ADAPTER_STATE_CHANGE = 'onBluetoothAdapterStateChange'; - const API_ON_BLE_CONNECTION_STATE_CHANGE = 'onBLEConnectionStateChange'; - const API_ON_BLE_CHARACTERISTIC_VALUE_CHANGE = 'onBLECharacteristicValueChange'; - const API_START_BLUETOOTH_DEVICES_DISCOVERY = 'startBluetoothDevicesDiscovery'; - const StartBluetoothDevicesDiscoveryProtocol = { - services: Array, - allowDuplicatesKey: Boolean, - interval: Number, - }; - const API_GET_CONNECTED_BLUETOOTH_DEVICES = 'getConnectedBluetoothDevices'; - const GetConnectedBluetoothDevicesProtocol = { - services: { - type: Array, - required: true, - }, - }; - const API_CREATE_BLE_CONNECTION = 'createBLEConnection'; - const CreateBLEConnectionProtocol = { - deviceId: { - type: String, - required: true, - }, - }; - const API_CLOSE_BLE_CONNECTION = 'closeBLEConnection'; - const CloseBLEConnectionProtocol = { - deviceId: { - type: String, - required: true, - }, - }; - const API_GET_BLE_DEVICE_SERVICES = 'getBLEDeviceServices'; - const GetBLEDeviceServicesProtocol = { - deviceId: { - type: String, - required: true, - }, - }; - const API_GET_BLE_DEVICE_CHARACTERISTICS = 'getBLEDeviceCharacteristics'; - const GetBLEDeviceCharacteristicsProtocol = { - deviceId: { - type: String, - required: true, - }, - serviceId: { - type: String, - required: true, - }, - }; - const API_NOTIFY_BLE_CHARACTERISTIC_VALUE_CHANGE = 'notifyBLECharacteristicValueChange'; - const NotifyBLECharacteristicValueChangeProtocol = { - deviceId: { - type: String, - required: true, - }, - serviceId: { - type: String, - required: true, - }, - characteristicId: { - type: String, - required: true, - }, - state: { - type: Boolean, - required: true, - }, - }; - const API_READ_BLE_CHARACTERISTIC_VALUE = 'readBLECharacteristicValue'; - const ReadBLECharacteristicValueProtocol = { - deviceId: { - type: String, - required: true, - }, - serviceId: { - type: String, - required: true, - }, - characteristicId: { - type: String, - required: true, - }, - }; - const API_WRITE_BLE_CHARACTERISTIC_VALUE = 'writeBLECharacteristicValue'; - const WriteBLECharacteristicValueProtocol = { - deviceId: { - type: String, - required: true, - }, - serviceId: { - type: String, - required: true, - }, - characteristicId: { - type: String, - required: true, - }, - value: { - type: Array, - required: true, - }, - }; - const API_SET_BLE_MTU = 'setBLEMTU'; - const SetBLEMTUProtocol = { - deviceId: { - type: String, - required: true, - }, - mtu: { - type: Number, - required: true, - }, - }; - const API_GET_BLE_DEVICE_RSSI = 'getBLEDeviceRSSI'; - const GetBLEDeviceRSSIProtocol = { - deviceId: { - type: String, - required: true, - }, - }; - - const API_ON_BEACON_UPDATE = 'onBeaconUpdate'; - const API_ON_BEACON_SERVICE_CHANGE = 'onBeaconServiceChange'; - const API_GET_BEACONS = 'getBeacons'; - const API_START_BEACON_DISCOVERY = 'startBeaconDiscovery'; - const StartBeaconDiscoveryProtocol = { - uuids: { - type: Array, - required: true, - }, - }; - const API_STOP_BEACON_DISCOVERY = 'stopBeaconDiscovery'; - - const API_GET_SCREEN_BRIGHTNESS = 'getScreenBrightness'; - const API_SET_SCREEN_BRIGHTNESS = 'setScreenBrightness'; - const API_SET_KEEP_SCREEN_ON = 'setKeepScreenOn'; - - const API_CHECK_IS_SUPPORT_SOTER_AUTHENTICATION = 'soterAuthentication'; - const API_CHECK_IS_SOTER_ENROLLED_IN_DEVICE = 'checkIsSoterEnrolledInDevice'; - const CheckAuthModes = [ - 'fingerPrint', - 'facial', - 'speech', - ]; - const CheckIsSoterEnrolledInDeviceOptions = { - formatArgs: { - checkAuthMode(value, params) { - if (!value || !CheckAuthModes.includes(value)) - return 'checkAuthMode 填写错误'; - }, - }, - }; - const CheckIsSoterEnrolledInDeviceProtocols = { - checkAuthMode: String, - }; - const API_START_SOTER_AUTHENTICATION = 'checkIsSoterEnrolledInDevice'; - const StartSoterAuthenticationOptions = { - formatArgs: { - requestAuthModes(value, params) { - if (!value.includes('fingerPrint') && !value.includes('facial')) - return 'requestAuthModes 填写错误'; - }, - }, - }; - const StartSoterAuthenticationProtocols = { - requestAuthModes: { - type: Array, - required: true, - }, - challenge: String, - authContent: String, - }; - - const API_SCAN_CODE = 'scanCode'; - const ScanCodeProtocol = { - onlyFromCamera: Boolean, - scanType: Array, - autoDecodeCharSet: Boolean, - }; - - const API_GET_STORAGE = 'getStorage'; - const GetStorageProtocol = { - key: { - type: String, - required: true, - }, - }; - const API_GET_STORAGE_SYNC = 'getStorageSync'; - const GetStorageSyncProtocol = [ - { - name: 'key', - type: String, - required: true, - }, - ]; - const API_SET_STORAGE = 'setStorage'; - const SetStorageProtocol = { - key: { - type: String, - required: true, - }, - data: { - required: true, - }, - }; - const API_SET_STORAGE_SYNC = 'setStorageSync'; - const SetStorageSyncProtocol = [ - { - name: 'key', - type: String, - required: true, - }, - { - name: 'data', - required: true, - }, - ]; - const API_REMOVE_STORAGE = 'removeStorage'; - const RemoveStorageProtocol = GetStorageProtocol; - const RemoveStorageSyncProtocol = GetStorageSyncProtocol; - - const API_SAVE_FILE = 'saveFile'; - const SaveFileOptions = { - formatArgs: { - tempFilePath(savedFilePath, params) { - params.tempFilePath = getRealPath(savedFilePath); - }, - }, - }; - const SaveFileProtocol = { - tempFilePath: { - type: String, - required: true, - }, - }; - - const API_GET_FILE_INFO = 'getFileInfo'; - const GetFileInfoOptions = { - formatArgs: { - filePath(filePath, params) { - params.filePath = getRealPath(filePath); - }, - }, - }; - const GetFileInfoProtocol = { - filePath: { - type: String, - required: true, - }, - }; - - const API_OPEN_DOCUMENT = 'openDocument'; - const OpenDocumentOptions = { - formatArgs: { - filePath(filePath, params) { - params.filePath = getRealPath(filePath); - }, - }, - }; - const OpenDocumentProtocol = { - filePath: { - type: String, - required: true, - }, - fileType: String, - }; - - const API_HIDE_KEYBOARD = 'hideKeyboard'; - const API_SHOW_KEYBOARD = 'showKeyboard'; - - const API_CHOOSE_LOCATION = 'chooseLocation'; - const ChooseLocationProtocol = { - keyword: String, - latitude: Number, - longitude: Number, - }; - - const API_GET_LOCATION = 'getLocation'; - const coordTypes = ['wgs84', 'gcj02']; - const GetLocationOptions = { - formatArgs: { - type(value, params) { - value = (value || '').toLowerCase(); - if (coordTypes.indexOf(value) === -1) { - params.type = coordTypes[0]; - } - else { - params.type = value; - } - }, - altitude(value, params) { - params.altitude = value ? value : false; - }, - }, - }; - const GetLocationProtocol = { - type: String, - altitude: Boolean, - }; - - const API_OPEN_LOCATION = 'openLocation'; - const OpenLocationOptions = { - formatArgs: { - scale(value, params) { - value = Math.floor(value); - params.scale = value >= 5 && value <= 18 ? value : 18; - }, - }, - }; - const OpenLocationProtocol = { - latitude: { - type: Number, - required: true, - }, - longitude: { - type: Number, - required: true, - }, - scale: Number, - name: String, - address: String, - }; - - const API_CHOOSE_IMAGE = 'chooseImage'; - const ChooseImageOptions = { - formatArgs: { - count(value, params) { - if (!value || value <= 0) { - params.count = 9; - } - }, - sizeType(sizeType, params) { - params.sizeType = elemsInArray(sizeType, CHOOSE_SIZE_TYPES); - }, - sourceType(sourceType, params) { - params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES); - }, - extension(extension, params) { - if (extension instanceof Array && extension.length === 0) { - return 'param extension should not be empty.'; - } - if (!extension) - params.extension = ['*']; - }, - }, - }; - const ChooseImageProtocol = { - count: Number, - sizeType: [Array, String], - sourceType: Array, - extension: Array, - }; - - const API_CHOOSE_VIDEO = 'chooseVideo'; - const ChooseVideoOptions = { - formatArgs: { - sourceType(sourceType, params) { - params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES); - }, - compressed: true, - maxDuration: 60, - camera: 'back', - extension(extension, params) { - if (extension instanceof Array && extension.length === 0) { - return 'param extension should not be empty.'; - } - if (!extension) - params.extension = ['*']; - }, - }, - }; - const ChooseVideoProtocol = { - sourceType: Array, - compressed: Boolean, - maxDuration: Number, - camera: String, - extension: Array, - }; - - const API_GET_IMAGE_INFO = 'getImageInfo'; - const GetImageInfoOptions = { - formatArgs: { - src(src, params) { - params.src = getRealPath(src); - }, - }, - }; - const GetImageInfoProtocol = { - src: { - type: String, - required: true, - }, - }; - - const API_PREVIEW_IMAGE = 'previewImage'; - const PreviewImageOptions = { - formatArgs: { - urls(urls, params) { - params.urls = urls.map((url) => typeof url === 'string' && url ? getRealPath(url) : ''); - }, - current(current, params) { - if (typeof current === 'number') { - params.current = - current > 0 && current < params.urls.length ? current : 0; - } - else if (typeof current === 'string' && current) { - params.current = getRealPath(current); - } - }, - }, - }; - const PreviewImageProtocol = { - urls: { - type: Array, - required: true, - }, - current: { - type: [Number, String], - }, - }; - const API_CLOSE_PREVIEW_IMAGE = 'closePreviewImage'; - - const API_GET_VIDEO_INFO = 'getVideoInfo'; - const GetVideoInfoOptions = { - formatArgs: { - src(src, params) { - params.src = getRealPath(src); - }, - }, - }; - const GetVideoInfoProtocol = { - src: { - type: String, - required: true, - }, - }; - - const API_SAVE_IMAGE_TO_PHOTOS_ALBUM = 'saveImageToPhotosAlbum'; - const SaveImageToPhotosAlbumOptions = { - formatArgs: { - filePath(filePath, params) { - params.filePath = getRealPath(filePath); - }, - }, - }; - const SaveImageToPhotosAlbumProtocol = { - filePath: { - type: String, - required: true, - }, - }; - - const API_SAVE_VIDEO_TO_PHOTOS_ALBUM = 'saveVideoToPhotosAlbum'; - const SaveVideoToPhotosAlbumOptions = { - formatArgs: { - filePath(filePath, params) { - params.filePath = getRealPath(filePath); - }, - }, - }; - const SaveVideoToPhotosAlbumProtocol = { - filePath: { - type: String, - required: true, - }, - }; - - const API_GET_RECORDER_MANAGER = 'getRecorderManager'; - - const API_COMPRESS_IMAGE = 'compressImage'; - const CompressImageOptions = { - formatArgs: { - src(src, params) { - params.src = getRealPath(src); - }, - }, - }; - const CompressImageProtocol = { - src: { - type: String, - required: true, - }, - }; - - const API_COMPRESS_VIDEO = 'compressVideo'; - const CompressVideoOptions = { - formatArgs: { - src(src, params) { - params.src = getRealPath(src); - }, - }, - }; - const CompressVideoProtocol = { - src: { - type: String, - required: true, - }, - quality: String, - bitrate: Number, - fps: Number, - resolution: Number, - }; - - const API_REQUEST = 'request'; - const dataType = { - JSON: 'json', - }; - const RESPONSE_TYPE = ['text', 'arraybuffer']; - const DEFAULT_RESPONSE_TYPE = 'text'; - const encode$1 = encodeURIComponent; - function stringifyQuery(url, data) { - let str = url.split('#'); - const hash = str[1] || ''; - str = str[0].split('?'); - let query = str[1] || ''; - url = str[0]; - const search = query.split('&').filter((item) => item); - const params = {}; - search.forEach((item) => { - const part = item.split('='); - params[part[0]] = part[1]; - }); - for (const key in data) { - if (shared.hasOwn(data, key)) { - let v = data[key]; - if (typeof v === 'undefined' || v === null) { - v = ''; - } - else if (shared.isPlainObject(v)) { - v = JSON.stringify(v); - } - params[encode$1(key)] = encode$1(v); - } - } - query = Object.keys(params) - .map((item) => `${item}=${params[item]}`) - .join('&'); - return url + (query ? '?' + query : '') + (hash ? '#' + hash : ''); - } - const RequestProtocol = { - method: String, - data: [Object, String, Array, ArrayBuffer], - url: { - type: String, - required: true, - }, - header: Object, - dataType: String, - responseType: String, - withCredentials: Boolean, - }; - const RequestOptions = { - formatArgs: { - method(value, params) { - params.method = elemInArray((value || '').toUpperCase(), HTTP_METHODS); - }, - data(value, params) { - params.data = value || ''; - }, - url(value, params) { - if (params.method === HTTP_METHODS[0] && - shared.isPlainObject(params.data) && - Object.keys(params.data).length) { - // 将 method,data 校验提前,保证 url 校验时,method,data 已被格式化 - params.url = stringifyQuery(value, params.data); - } - }, - header(value, params) { - const header = (params.header = value || {}); - if (params.method !== HTTP_METHODS[0]) { - if (!Object.keys(header).find((key) => key.toLowerCase() === 'content-type')) { - header['Content-Type'] = 'application/json'; - } - } - }, - dataType(value, params) { - params.dataType = (value || dataType.JSON).toLowerCase(); - }, - responseType(value, params) { - params.responseType = (value || '').toLowerCase(); - if (RESPONSE_TYPE.indexOf(params.responseType) === -1) { - params.responseType = DEFAULT_RESPONSE_TYPE; - } - }, - }, - }; - const API_CONFIG_MTLS = 'configMTLS'; - const ConfigMTLSProtocol = { - certificates: { - type: Array, - required: true, - }, - }; - const ConfigMTLSOptions = { - formatArgs: { - certificates(value) { - if (value.some((item) => shared.toRawType(item.host) !== 'String')) { - return '参数配置错误,请确认后重试'; - } - }, - }, - }; - - const API_DOWNLOAD_FILE = 'downloadFile'; - const DownloadFileOptions = { - formatArgs: { - header(value, params) { - params.header = value || {}; - }, - }, - }; - const DownloadFileProtocol = { - url: { - type: String, - required: true, - }, - header: Object, - timeout: Number, - }; - - const API_UPLOAD_FILE = 'uploadFile'; - const UploadFileOptions = { - formatArgs: { - filePath(filePath, params) { - if (filePath) { - params.filePath = getRealPath(filePath); - } - }, - header(value, params) { - params.header = value || {}; - }, - formData(value, params) { - params.formData = value || {}; - }, - }, - }; - const UploadFileProtocol = { - url: { - type: String, - required: true, - }, - files: Array, - filePath: String, - name: String, - header: Object, - formData: Object, - timeout: Number, - }; - - const API_CONNECT_SOCKET = 'connectSocket'; - const ConnectSocketOptions = { - formatArgs: { - header(value, params) { - params.header = value || {}; - }, - method(value, params) { - params.method = elemInArray((value || '').toUpperCase(), HTTP_METHODS); - }, - protocols(protocols, params) { - if (typeof protocols === 'string') { - params.protocols = [protocols]; - } - }, - }, - }; - const ConnectSocketProtocol = { - url: { - type: String, - required: true, - }, - header: { - type: Object, - }, - method: String, - protocols: [Array, String], - }; - const API_SEND_SOCKET_MESSAGE = 'sendSocketMessage'; - const SendSocketMessageProtocol = { - data: [String, ArrayBuffer], - }; - const API_CLOSE_SOCKET = 'closeSocket'; - const CloseSocketProtocol = { - code: Number, - reason: String, - }; - - function encodeQueryString(url) { - if (typeof url !== 'string') { - return url; - } - const index = url.indexOf('?'); - if (index === -1) { - return url; - } - const query = url - .substr(index + 1) - .trim() - .replace(/^(\?|#|&)/, ''); - if (!query) { - return url; - } - url = url.substr(0, index); - const params = []; - query.split('&').forEach((param) => { - const parts = param.replace(/\+/g, ' ').split('='); - const key = parts.shift(); - const val = parts.length > 0 ? parts.join('=') : ''; - params.push(key + '=' + encodeURIComponent(val)); - }); - return params.length ? url + '?' + params.join('&') : url; - } +const ContextClasss = { + canvas: CanvasContext, + map: MapContext, + video: VideoContext, + editor: EditorContext, +}; +function convertContext(result) { + if (result && result.contextInfo) { + const { id, type, page } = result.contextInfo; + const ContextClass = ContextClasss[type]; + result.context = new ContextClass(id, page); + delete result.contextInfo; + } +} +class NodesRef { + constructor(selectorQuery, component, selector, single) { + this._selectorQuery = selectorQuery; + this._component = component; + this._selector = selector; + this._single = single; + } + boundingClientRect(callback) { + this._selectorQuery._push(this._selector, this._component, this._single, { + id: true, + dataset: true, + rect: true, + size: true, + }, callback); + return this._selectorQuery; + } + fields(fields, callback) { + this._selectorQuery._push(this._selector, this._component, this._single, fields, callback); + return this._selectorQuery; + } + scrollOffset(callback) { + this._selectorQuery._push(this._selector, this._component, this._single, { + id: true, + dataset: true, + scrollOffset: true, + }, callback); + return this._selectorQuery; + } + context(callback) { + this._selectorQuery._push(this._selector, this._component, this._single, { + context: true, + }, callback); + return this._selectorQuery; + } + node(_callback) { + // TODO + return this._selectorQuery; + } +} +class SelectorQuery { + constructor(page) { + this._component = undefined; + this._page = page; + this._queue = []; + this._queueCb = []; + } + exec(callback) { + requestComponentInfo(this._page, this._queue, (res) => { + const queueCbs = this._queueCb; + res.forEach((result, index) => { + if (Array.isArray(result)) { + result.forEach(convertContext); + } + else { + convertContext(result); + } + const queueCb = queueCbs[index]; + if (typeof queueCb === 'function') { + queueCb.call(this, result); + } + }); + // isFn(callback) && + if (typeof callback === 'function') { + callback.call(this, res); + } + }); + // TODO + return this._nodesRef; + } + in(component) { + this._component = resolveComponentInstance(component); + return this; + } + select(selector) { + return (this._nodesRef = new NodesRef(this, this._component, selector, true)); + } + selectAll(selector) { + return (this._nodesRef = new NodesRef(this, this._component, selector, false)); + } + selectViewport() { + return (this._nodesRef = new NodesRef(this, null, '', true)); + } + _push(selector, component, single, fields, callback) { + this._queue.push({ + component, + selector, + single, + fields, + }); + this._queueCb.push(callback); + } +} +const createSelectorQuery = (defineSyncApi('createSelectorQuery', (context) => { + context = resolveComponentInstance(context); + if (context && !getPageIdByVm(context)) { + context = null; + } + return new SelectorQuery(context || getCurrentPageVm()); +})); + +// import { elemInArray } from '../../helpers/protocol' +const API_CREATE_ANIMATION = 'createAnimation'; +// const timingFunctions: API_TYPE_CREATE_ANIMATION_Timing_Function[] = [ +// 'linear', +// 'ease', +// 'ease-in', +// 'ease-in-out', +// 'ease-out', +// 'step-start', +// 'step-end', +// ] +const CreateAnimationOptions = { + // 目前参数校验不支持此api校验 + formatArgs: { + /* duration: 400, + timingFunction(timingFunction, params) { + params.timingFunction = elemInArray(timingFunction, timingFunctions) + }, + delay: 0, + transformOrigin: '50% 50% 0', */ + }, +}; +const CreateAnimationProtocol = { + duration: Number, + timingFunction: String, + delay: Number, + transformOrigin: String, +}; + +const defaultOption = { + duration: 400, + timingFunction: 'linear', + delay: 0, + transformOrigin: '50% 50% 0', +}; +class MPAnimation { + constructor(option) { + this.actions = []; + this.currentTransform = {}; + this.currentStepAnimates = []; + this.option = extend({}, defaultOption, option); + } + _getOption(option) { + const _option = { + transition: extend({}, this.option, option), + transformOrigin: '', + }; + _option.transformOrigin = _option.transition.transformOrigin; + delete _option.transition.transformOrigin; + return _option; + } + _pushAnimates(type, args) { + this.currentStepAnimates.push({ + type: type, + args: args, + }); + } + _converType(type) { + return type.replace(/[A-Z]/g, (text) => { + return `-${text.toLowerCase()}`; + }); + } + _getValue(value) { + return typeof value === 'number' ? `${value}px` : value; + } + export() { + const actions = this.actions; + this.actions = []; + return { + actions, + }; + } + step(option) { + this.currentStepAnimates.forEach((animate) => { + if (animate.type !== 'style') { + this.currentTransform[animate.type] = animate; + } + else { + this.currentTransform[`${animate.type}.${animate.args[0]}`] = animate; + } + }); + this.actions.push({ + animates: Object.values(this.currentTransform), + option: this._getOption(option), + }); + this.currentStepAnimates = []; + return this; + } +} +const initAnimationProperty = /*#__PURE__*/ once(() => { + const animateTypes1 = [ + 'matrix', + 'matrix3d', + 'rotate', + 'rotate3d', + 'rotateX', + 'rotateY', + 'rotateZ', + 'scale', + 'scale3d', + 'scaleX', + 'scaleY', + 'scaleZ', + 'skew', + 'skewX', + 'skewY', + 'translate', + 'translate3d', + 'translateX', + 'translateY', + 'translateZ', + ]; + const animateTypes2 = ['opacity', 'backgroundColor']; + const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']; + animateTypes1.concat(animateTypes2, animateTypes3).forEach((type) => { + MPAnimation.prototype[type] = function (...args) { + if (animateTypes2.concat(animateTypes3).includes(type)) { + this._pushAnimates('style', [ + this._converType(type), + animateTypes3.includes(type) ? this._getValue(args[0]) : args[0], + ]); + } + else { + this._pushAnimates(type, args); + } + return this; + }; + }); +}); +const createAnimation = defineSyncApi(API_CREATE_ANIMATION, (option) => { + initAnimationProperty(); + return new MPAnimation(option); +}, CreateAnimationProtocol, CreateAnimationOptions); + +const API_ON_TAB_BAR_MID_BUTTON_TAP = 'onTabBarMidButtonTap'; +const onTabBarMidButtonTap = defineOnApi(API_ON_TAB_BAR_MID_BUTTON_TAP, () => { + // noop +}); + +const API_ON_WINDOW_RESIZE = 'onWindowResize'; +const API_OFF_WINDOW_RESIZE = 'offWindowResize'; + +/** + * 监听窗口大小变化 + */ +const onWindowResize = defineOnApi(API_ON_WINDOW_RESIZE, () => { + // 生命周期包括onResize,框架直接监听resize + // window.addEventListener('resize', onResize) +}); +/** + * 取消监听窗口大小变化 + */ +const offWindowResize = defineOffApi(API_OFF_WINDOW_RESIZE, () => { + // window.removeEventListener('resize', onResize) +}); + +const API_SET_LOCALE = 'setLocale'; +const API_GET_LOCALE = 'getLocale'; +const API_ON_LOCALE_CHANGE = 'onLocaleChange'; +const getLocale = defineSyncApi(API_GET_LOCALE, () => { + // 优先使用 $locale + const app = getApp({ allowDefault: true }); + if (app && app.$vm) { + return app.$vm.$locale; + } + return useI18n().getLocale(); +}); +const onLocaleChange = defineOnApi(API_ON_LOCALE_CHANGE, () => { }); +const setLocale = defineSyncApi(API_SET_LOCALE, (locale) => { + const app = getApp(); + if (!app) { + return false; + } + const oldLocale = app.$vm.$locale; + if (oldLocale !== locale) { + app.$vm.$locale = locale; + { + const pages = getCurrentPages(); + pages.forEach((page) => { + UniServiceJSBridge.publishHandler(API_SET_LOCALE, locale, page.$page.id); + }); + weex.requireModule('plus').setLanguage(locale); + } + // 执行 uni.onLocaleChange + UniServiceJSBridge.invokeOnCallback(API_ON_LOCALE_CHANGE, { locale }); + return true; + } + return false; +}); + +const API_SET_PAGE_META = 'setPageMeta'; +const setPageMeta = defineAsyncApi(API_SET_PAGE_META, (options, { resolve }) => { + resolve(setCurrentPageMeta(getCurrentPageVm(), options)); +}); + +const API_GET_SELECTED_TEXT_RANGE = 'getSelectedTextRange'; + +const getSelectedTextRange = defineAsyncApi(API_GET_SELECTED_TEXT_RANGE, (_, { resolve, reject }) => { + UniServiceJSBridge.invokeViewMethod('getSelectedTextRange', {}, getCurrentPageId(), (res) => { + if (typeof res.end === 'undefined' && + typeof res.start === 'undefined') { + reject('no focused'); + } + else { + resolve(res); + } + }); +}); + +const appLaunchHooks = []; +function onAppLaunch(hook) { + const app = getApp({ allowDefault: true }); + if (app && app.$vm) { + return injectHook(ON_LAUNCH, hook, app.$vm.$); + } + appLaunchHooks.push(hook); +} +function injectAppLaunchHooks(appInstance) { + appLaunchHooks.forEach((hook) => { + injectHook(ON_LAUNCH, hook, appInstance); + }); +} +const API_GET_ENTER_OPTIONS_SYNC = 'getEnterOptionsSync'; +const getEnterOptionsSync = defineSyncApi(API_GET_ENTER_OPTIONS_SYNC, () => { + return getEnterOptions(); +}); +const API_GET_LAUNCH_OPTIONS_SYNC = 'getLaunchOptionsSync'; +const getLaunchOptionsSync = defineSyncApi(API_GET_LAUNCH_OPTIONS_SYNC, () => { + return getLaunchOptions(); +}); + +let cid = ''; +/** + * @private + * @param args + */ +function invokePushCallback(args) { + if (args.type === 'clientId') { + cid = args.cid; + invokeGetPushCidCallbacks(cid); + } + else if (args.type === 'pushMsg') { + onPushMessageCallbacks.forEach((callback) => { + callback({ data: args.message }); + }); + } +} +const getPushCidCallbacks = []; +function invokeGetPushCidCallbacks(cid) { + getPushCidCallbacks.forEach((callback) => { + callback(cid); + }); + getPushCidCallbacks.length = 0; +} +function getPushCid(args) { + if (!isPlainObject(args)) { + args = {}; + } + const { success, fail, complete } = getApiCallbacks(args); + const hasSuccess = isFunction(success); + const hasFail = isFunction(fail); + const hasComplete = isFunction(complete); + getPushCidCallbacks.push((cid) => { + let res; + if (cid) { + res = { errMsg: 'getPushCid:ok', cid }; + hasSuccess && success(res); + } + else { + res = { errMsg: 'getPushCid:fail' }; + hasFail && fail(res); + } + hasComplete && complete(res); + }); + if (cid) { + Promise.resolve().then(() => invokeGetPushCidCallbacks(cid)); + } +} +const onPushMessageCallbacks = []; +// 不使用 defineOnApi 实现,是因为 defineOnApi 依赖 UniServiceJSBridge ,该对象目前在小程序上未提供,故简单实现 +const onPushMessage = (fn) => { + if (onPushMessageCallbacks.indexOf(fn) === -1) { + onPushMessageCallbacks.push(fn); + } +}; +const offPushMessage = (fn) => { + if (!fn) { + onPushMessageCallbacks.length = 0; + } + else { + const index = onPushMessageCallbacks.indexOf(fn); + if (index > -1) { + onPushMessageCallbacks.splice(index, 1); + } + } +}; + +const API_GET_BACKGROUND_AUDIO_MANAGER = 'getBackgroundAudioManager'; + +const API_MAKE_PHONE_CALL = 'makePhoneCall'; +const MakePhoneCallProtocol = { + phoneNumber: String, +}; + +const API_ADD_PHONE_CONTACT = 'addPhoneContact'; +const AddPhoneContactOptions = { + formatArgs: { + firstName(firstName) { + if (!firstName) + return 'addPhoneContact:fail parameter error: parameter.firstName should not be empty;'; + }, + }, +}; +const AddPhoneContactProtocol = { + firstName: { + type: String, + required: true, + }, + photoFilePath: String, + nickName: String, + lastName: String, + middleName: String, + remark: String, + mobilePhoneNumber: String, + weChatNumber: String, + addressCountry: String, + addressState: String, + addressCity: String, + addressStreet: String, + addressPostalCode: String, + organization: String, + title: String, + workFaxNumber: String, + workPhoneNumber: String, + hostNumber: String, + email: String, + url: String, + workAddressCountry: String, + workAddressState: String, + workAddressCity: String, + workAddressStreet: String, + workAddressPostalCode: String, + homeFaxNumber: String, + homePhoneNumber: String, + homeAddressCountry: String, + homeAddressState: String, + homeAddressCity: String, + homeAddressStreet: String, + homeAddressPostalCode: String, +}; + +const API_GET_CLIPBOARD_DATA = 'getClipboardData'; +const API_SET_CLIPBOARD_DATA = 'setClipboardData'; +const SetClipboardDataOptions = { + formatArgs: { + showToast: true, + }, + beforeInvoke() { + initI18nSetClipboardDataMsgsOnce(); + }, + beforeSuccess(res, params) { + if (!params.showToast) + return; + const { t } = useI18n(); + const title = t('uni.setClipboardData.success'); + if (title) { + uni.showToast({ + title: title, + icon: 'success', + mask: false, + }); + } + }, +}; +const SetClipboardDataProtocol = { + data: { + type: String, + required: true, + }, + showToast: { + type: Boolean, + }, +}; + +const API_ON_ACCELEROMETER = 'onAccelerometer'; +const API_OFF_ACCELEROMETER = 'offAccelerometer'; +const API_START_ACCELEROMETER = 'startAccelerometer'; +const API_STOP_ACCELEROMETER = 'stopAccelerometer'; + +const API_ON_COMPASS = 'onCompass'; +const API_OFF_COMPASS = 'offCompass'; +const API_START_COMPASS = 'startCompass'; +const API_STOP_COMPASS = 'stopCompass'; + +const API_VIBRATE_SHORT = 'vibrateShort'; +const API_VIBRATE_LONG = 'vibrateLong'; + +const API_ON_BLUETOOTH_DEVICE_FOUND = 'onBluetoothDeviceFound'; +const API_ON_BLUETOOTH_ADAPTER_STATE_CHANGE = 'onBluetoothAdapterStateChange'; +const API_ON_BLE_CONNECTION_STATE_CHANGE = 'onBLEConnectionStateChange'; +const API_ON_BLE_CHARACTERISTIC_VALUE_CHANGE = 'onBLECharacteristicValueChange'; +const API_START_BLUETOOTH_DEVICES_DISCOVERY = 'startBluetoothDevicesDiscovery'; +const StartBluetoothDevicesDiscoveryProtocol = { + services: Array, + allowDuplicatesKey: Boolean, + interval: Number, +}; +const API_GET_CONNECTED_BLUETOOTH_DEVICES = 'getConnectedBluetoothDevices'; +const GetConnectedBluetoothDevicesProtocol = { + services: { + type: Array, + required: true, + }, +}; +const API_CREATE_BLE_CONNECTION = 'createBLEConnection'; +const CreateBLEConnectionProtocol = { + deviceId: { + type: String, + required: true, + }, +}; +const API_CLOSE_BLE_CONNECTION = 'closeBLEConnection'; +const CloseBLEConnectionProtocol = { + deviceId: { + type: String, + required: true, + }, +}; +const API_GET_BLE_DEVICE_SERVICES = 'getBLEDeviceServices'; +const GetBLEDeviceServicesProtocol = { + deviceId: { + type: String, + required: true, + }, +}; +const API_GET_BLE_DEVICE_CHARACTERISTICS = 'getBLEDeviceCharacteristics'; +const GetBLEDeviceCharacteristicsProtocol = { + deviceId: { + type: String, + required: true, + }, + serviceId: { + type: String, + required: true, + }, +}; +const API_NOTIFY_BLE_CHARACTERISTIC_VALUE_CHANGE = 'notifyBLECharacteristicValueChange'; +const NotifyBLECharacteristicValueChangeProtocol = { + deviceId: { + type: String, + required: true, + }, + serviceId: { + type: String, + required: true, + }, + characteristicId: { + type: String, + required: true, + }, + state: { + type: Boolean, + required: true, + }, +}; +const API_READ_BLE_CHARACTERISTIC_VALUE = 'readBLECharacteristicValue'; +const ReadBLECharacteristicValueProtocol = { + deviceId: { + type: String, + required: true, + }, + serviceId: { + type: String, + required: true, + }, + characteristicId: { + type: String, + required: true, + }, +}; +const API_WRITE_BLE_CHARACTERISTIC_VALUE = 'writeBLECharacteristicValue'; +const WriteBLECharacteristicValueProtocol = { + deviceId: { + type: String, + required: true, + }, + serviceId: { + type: String, + required: true, + }, + characteristicId: { + type: String, + required: true, + }, + value: { + type: Array, + required: true, + }, +}; +const API_SET_BLE_MTU = 'setBLEMTU'; +const SetBLEMTUProtocol = { + deviceId: { + type: String, + required: true, + }, + mtu: { + type: Number, + required: true, + }, +}; +const API_GET_BLE_DEVICE_RSSI = 'getBLEDeviceRSSI'; +const GetBLEDeviceRSSIProtocol = { + deviceId: { + type: String, + required: true, + }, +}; + +const API_ON_BEACON_UPDATE = 'onBeaconUpdate'; +const API_ON_BEACON_SERVICE_CHANGE = 'onBeaconServiceChange'; +const API_GET_BEACONS = 'getBeacons'; +const API_START_BEACON_DISCOVERY = 'startBeaconDiscovery'; +const StartBeaconDiscoveryProtocol = { + uuids: { + type: Array, + required: true, + }, +}; +const API_STOP_BEACON_DISCOVERY = 'stopBeaconDiscovery'; + +const API_GET_SCREEN_BRIGHTNESS = 'getScreenBrightness'; +const API_SET_SCREEN_BRIGHTNESS = 'setScreenBrightness'; +const API_SET_KEEP_SCREEN_ON = 'setKeepScreenOn'; + +const API_CHECK_IS_SUPPORT_SOTER_AUTHENTICATION = 'soterAuthentication'; +const API_CHECK_IS_SOTER_ENROLLED_IN_DEVICE = 'checkIsSoterEnrolledInDevice'; +const CheckAuthModes = [ + 'fingerPrint', + 'facial', + 'speech', +]; +const CheckIsSoterEnrolledInDeviceOptions = { + formatArgs: { + checkAuthMode(value, params) { + if (!value || !CheckAuthModes.includes(value)) + return 'checkAuthMode 填写错误'; + }, + }, +}; +const CheckIsSoterEnrolledInDeviceProtocols = { + checkAuthMode: String, +}; +const API_START_SOTER_AUTHENTICATION = 'checkIsSoterEnrolledInDevice'; +const StartSoterAuthenticationOptions = { + formatArgs: { + requestAuthModes(value, params) { + if (!value.includes('fingerPrint') && !value.includes('facial')) + return 'requestAuthModes 填写错误'; + }, + }, +}; +const StartSoterAuthenticationProtocols = { + requestAuthModes: { + type: Array, + required: true, + }, + challenge: String, + authContent: String, +}; + +const API_SCAN_CODE = 'scanCode'; +const ScanCodeProtocol = { + onlyFromCamera: Boolean, + scanType: Array, + autoDecodeCharSet: Boolean, +}; + +const API_GET_STORAGE = 'getStorage'; +const GetStorageProtocol = { + key: { + type: String, + required: true, + }, +}; +const API_GET_STORAGE_SYNC = 'getStorageSync'; +const GetStorageSyncProtocol = [ + { + name: 'key', + type: String, + required: true, + }, +]; +const API_SET_STORAGE = 'setStorage'; +const SetStorageProtocol = { + key: { + type: String, + required: true, + }, + data: { + required: true, + }, +}; +const API_SET_STORAGE_SYNC = 'setStorageSync'; +const SetStorageSyncProtocol = [ + { + name: 'key', + type: String, + required: true, + }, + { + name: 'data', + required: true, + }, +]; +const API_REMOVE_STORAGE = 'removeStorage'; +const RemoveStorageProtocol = GetStorageProtocol; +const RemoveStorageSyncProtocol = GetStorageSyncProtocol; + +const API_SAVE_FILE = 'saveFile'; +const SaveFileOptions = { + formatArgs: { + tempFilePath(savedFilePath, params) { + params.tempFilePath = getRealPath(savedFilePath); + }, + }, +}; +const SaveFileProtocol = { + tempFilePath: { + type: String, + required: true, + }, +}; + +const API_GET_FILE_INFO = 'getFileInfo'; +const GetFileInfoOptions = { + formatArgs: { + filePath(filePath, params) { + params.filePath = getRealPath(filePath); + }, + }, +}; +const GetFileInfoProtocol = { + filePath: { + type: String, + required: true, + }, +}; + +const API_OPEN_DOCUMENT = 'openDocument'; +const OpenDocumentOptions = { + formatArgs: { + filePath(filePath, params) { + params.filePath = getRealPath(filePath); + }, + }, +}; +const OpenDocumentProtocol = { + filePath: { + type: String, + required: true, + }, + fileType: String, +}; + +const API_HIDE_KEYBOARD = 'hideKeyboard'; +const API_SHOW_KEYBOARD = 'showKeyboard'; + +const API_CHOOSE_LOCATION = 'chooseLocation'; +const ChooseLocationProtocol = { + keyword: String, + latitude: Number, + longitude: Number, +}; + +const API_GET_LOCATION = 'getLocation'; +const coordTypes = ['wgs84', 'gcj02']; +const GetLocationOptions = { + formatArgs: { + type(value, params) { + value = (value || '').toLowerCase(); + if (coordTypes.indexOf(value) === -1) { + params.type = coordTypes[0]; + } + else { + params.type = value; + } + }, + altitude(value, params) { + params.altitude = value ? value : false; + }, + }, +}; +const GetLocationProtocol = { + type: String, + altitude: Boolean, +}; + +const API_OPEN_LOCATION = 'openLocation'; +const OpenLocationOptions = { + formatArgs: { + scale(value, params) { + value = Math.floor(value); + params.scale = value >= 5 && value <= 18 ? value : 18; + }, + }, +}; +const OpenLocationProtocol = { + latitude: { + type: Number, + required: true, + }, + longitude: { + type: Number, + required: true, + }, + scale: Number, + name: String, + address: String, +}; + +const API_CHOOSE_IMAGE = 'chooseImage'; +const ChooseImageOptions = { + formatArgs: { + count(value, params) { + if (!value || value <= 0) { + params.count = 9; + } + }, + sizeType(sizeType, params) { + params.sizeType = elemsInArray(sizeType, CHOOSE_SIZE_TYPES); + }, + sourceType(sourceType, params) { + params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES); + }, + extension(extension, params) { + if (extension instanceof Array && extension.length === 0) { + return 'param extension should not be empty.'; + } + if (!extension) + params.extension = ['*']; + }, + }, +}; +const ChooseImageProtocol = { + count: Number, + sizeType: [Array, String], + sourceType: Array, + extension: Array, +}; + +const API_CHOOSE_VIDEO = 'chooseVideo'; +const ChooseVideoOptions = { + formatArgs: { + sourceType(sourceType, params) { + params.sourceType = elemsInArray(sourceType, CHOOSE_SOURCE_TYPES); + }, + compressed: true, + maxDuration: 60, + camera: 'back', + extension(extension, params) { + if (extension instanceof Array && extension.length === 0) { + return 'param extension should not be empty.'; + } + if (!extension) + params.extension = ['*']; + }, + }, +}; +const ChooseVideoProtocol = { + sourceType: Array, + compressed: Boolean, + maxDuration: Number, + camera: String, + extension: Array, +}; + +const API_GET_IMAGE_INFO = 'getImageInfo'; +const GetImageInfoOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src); + }, + }, +}; +const GetImageInfoProtocol = { + src: { + type: String, + required: true, + }, +}; + +const API_PREVIEW_IMAGE = 'previewImage'; +const PreviewImageOptions = { + formatArgs: { + urls(urls, params) { + params.urls = urls.map((url) => typeof url === 'string' && url ? getRealPath(url) : ''); + }, + current(current, params) { + if (typeof current === 'number') { + params.current = + current > 0 && current < params.urls.length ? current : 0; + } + else if (typeof current === 'string' && current) { + params.current = getRealPath(current); + } + }, + }, +}; +const PreviewImageProtocol = { + urls: { + type: Array, + required: true, + }, + current: { + type: [Number, String], + }, +}; +const API_CLOSE_PREVIEW_IMAGE = 'closePreviewImage'; + +const API_GET_VIDEO_INFO = 'getVideoInfo'; +const GetVideoInfoOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src); + }, + }, +}; +const GetVideoInfoProtocol = { + src: { + type: String, + required: true, + }, +}; + +const API_SAVE_IMAGE_TO_PHOTOS_ALBUM = 'saveImageToPhotosAlbum'; +const SaveImageToPhotosAlbumOptions = { + formatArgs: { + filePath(filePath, params) { + params.filePath = getRealPath(filePath); + }, + }, +}; +const SaveImageToPhotosAlbumProtocol = { + filePath: { + type: String, + required: true, + }, +}; + +const API_SAVE_VIDEO_TO_PHOTOS_ALBUM = 'saveVideoToPhotosAlbum'; +const SaveVideoToPhotosAlbumOptions = { + formatArgs: { + filePath(filePath, params) { + params.filePath = getRealPath(filePath); + }, + }, +}; +const SaveVideoToPhotosAlbumProtocol = { + filePath: { + type: String, + required: true, + }, +}; + +const API_GET_RECORDER_MANAGER = 'getRecorderManager'; + +const API_COMPRESS_IMAGE = 'compressImage'; +const CompressImageOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src); + }, + }, +}; +const CompressImageProtocol = { + src: { + type: String, + required: true, + }, +}; + +const API_COMPRESS_VIDEO = 'compressVideo'; +const CompressVideoOptions = { + formatArgs: { + src(src, params) { + params.src = getRealPath(src); + }, + }, +}; +const CompressVideoProtocol = { + src: { + type: String, + required: true, + }, + quality: String, + bitrate: Number, + fps: Number, + resolution: Number, +}; + +const API_REQUEST = 'request'; +const dataType = { + JSON: 'json', +}; +const RESPONSE_TYPE = ['text', 'arraybuffer']; +const DEFAULT_RESPONSE_TYPE = 'text'; +const encode$1 = encodeURIComponent; +function stringifyQuery(url, data) { + let str = url.split('#'); + const hash = str[1] || ''; + str = str[0].split('?'); + let query = str[1] || ''; + url = str[0]; + const search = query.split('&').filter((item) => item); + const params = {}; + search.forEach((item) => { + const part = item.split('='); + params[part[0]] = part[1]; + }); + for (const key in data) { + if (hasOwn$1(data, key)) { + let v = data[key]; + if (typeof v === 'undefined' || v === null) { + v = ''; + } + else if (isPlainObject(v)) { + v = JSON.stringify(v); + } + params[encode$1(key)] = encode$1(v); + } + } + query = Object.keys(params) + .map((item) => `${item}=${params[item]}`) + .join('&'); + return url + (query ? '?' + query : '') + (hash ? '#' + hash : ''); +} +const RequestProtocol = { + method: String, + data: [Object, String, Array, ArrayBuffer], + url: { + type: String, + required: true, + }, + header: Object, + dataType: String, + responseType: String, + withCredentials: Boolean, +}; +const RequestOptions = { + formatArgs: { + method(value, params) { + params.method = elemInArray((value || '').toUpperCase(), HTTP_METHODS); + }, + data(value, params) { + params.data = value || ''; + }, + url(value, params) { + if (params.method === HTTP_METHODS[0] && + isPlainObject(params.data) && + Object.keys(params.data).length) { + // 将 method,data 校验提前,保证 url 校验时,method,data 已被格式化 + params.url = stringifyQuery(value, params.data); + } + }, + header(value, params) { + const header = (params.header = value || {}); + if (params.method !== HTTP_METHODS[0]) { + if (!Object.keys(header).find((key) => key.toLowerCase() === 'content-type')) { + header['Content-Type'] = 'application/json'; + } + } + }, + dataType(value, params) { + params.dataType = (value || dataType.JSON).toLowerCase(); + }, + responseType(value, params) { + params.responseType = (value || '').toLowerCase(); + if (RESPONSE_TYPE.indexOf(params.responseType) === -1) { + params.responseType = DEFAULT_RESPONSE_TYPE; + } + }, + }, +}; +const API_CONFIG_MTLS = 'configMTLS'; +const ConfigMTLSProtocol = { + certificates: { + type: Array, + required: true, + }, +}; +const ConfigMTLSOptions = { + formatArgs: { + certificates(value) { + if (value.some((item) => toRawType(item.host) !== 'String')) { + return '参数配置错误,请确认后重试'; + } + }, + }, +}; + +const API_DOWNLOAD_FILE = 'downloadFile'; +const DownloadFileOptions = { + formatArgs: { + header(value, params) { + params.header = value || {}; + }, + }, +}; +const DownloadFileProtocol = { + url: { + type: String, + required: true, + }, + header: Object, + timeout: Number, +}; + +const API_UPLOAD_FILE = 'uploadFile'; +const UploadFileOptions = { + formatArgs: { + filePath(filePath, params) { + if (filePath) { + params.filePath = getRealPath(filePath); + } + }, + header(value, params) { + params.header = value || {}; + }, + formData(value, params) { + params.formData = value || {}; + }, + }, +}; +const UploadFileProtocol = { + url: { + type: String, + required: true, + }, + files: Array, + filePath: String, + name: String, + header: Object, + formData: Object, + timeout: Number, +}; + +const API_CONNECT_SOCKET = 'connectSocket'; +const ConnectSocketOptions = { + formatArgs: { + header(value, params) { + params.header = value || {}; + }, + method(value, params) { + params.method = elemInArray((value || '').toUpperCase(), HTTP_METHODS); + }, + protocols(protocols, params) { + if (typeof protocols === 'string') { + params.protocols = [protocols]; + } + }, + }, +}; +const ConnectSocketProtocol = { + url: { + type: String, + required: true, + }, + header: { + type: Object, + }, + method: String, + protocols: [Array, String], +}; +const API_SEND_SOCKET_MESSAGE = 'sendSocketMessage'; +const SendSocketMessageProtocol = { + data: [String, ArrayBuffer], +}; +const API_CLOSE_SOCKET = 'closeSocket'; +const CloseSocketProtocol = { + code: Number, + reason: String, +}; + +function encodeQueryString(url) { + if (typeof url !== 'string') { + return url; + } + const index = url.indexOf('?'); + if (index === -1) { + return url; + } + const query = url + .substr(index + 1) + .trim() + .replace(/^(\?|#|&)/, ''); + if (!query) { + return url; + } + url = url.substr(0, index); + const params = []; + query.split('&').forEach((param) => { + const parts = param.replace(/\+/g, ' ').split('='); + const key = parts.shift(); + const val = parts.length > 0 ? parts.join('=') : ''; + params.push(key + '=' + encodeURIComponent(val)); + }); + return params.length ? url + '?' + params.join('&') : url; +} - const ANIMATION_IN = [ - 'slide-in-right', - 'slide-in-left', - 'slide-in-top', - 'slide-in-bottom', - 'fade-in', - 'zoom-out', - 'zoom-fade-out', - 'pop-in', - 'none', - ]; - const ANIMATION_OUT = [ - 'slide-out-right', - 'slide-out-left', - 'slide-out-top', - 'slide-out-bottom', - 'fade-out', - 'zoom-in', - 'zoom-fade-in', - 'pop-out', - 'none', - ]; - const BaseRouteProtocol = { - url: { - type: String, - required: true, - }, - }; - const API_NAVIGATE_TO = 'navigateTo'; - const API_REDIRECT_TO = 'redirectTo'; - const API_RE_LAUNCH = 'reLaunch'; - const API_SWITCH_TAB = 'switchTab'; - const API_NAVIGATE_BACK = 'navigateBack'; - const API_PRELOAD_PAGE = 'preloadPage'; - const API_UN_PRELOAD_PAGE = 'unPreloadPage'; - const NavigateToProtocol = - /*#__PURE__*/ shared.extend({}, BaseRouteProtocol, createAnimationProtocol(ANIMATION_IN)); - const NavigateBackProtocol = - /*#__PURE__*/ shared.extend({ - delta: { - type: Number, - }, - }, createAnimationProtocol(ANIMATION_OUT)); - const RedirectToProtocol = BaseRouteProtocol; - const ReLaunchProtocol = BaseRouteProtocol; - const SwitchTabProtocol = BaseRouteProtocol; - const PreloadPageProtocol = BaseRouteProtocol; - const UnPreloadPageProtocol = BaseRouteProtocol; - const NavigateToOptions = - /*#__PURE__*/ createRouteOptions(API_NAVIGATE_TO); - const RedirectToOptions = - /*#__PURE__*/ createRouteOptions(API_REDIRECT_TO); - const ReLaunchOptions = - /*#__PURE__*/ createRouteOptions(API_RE_LAUNCH); - const SwitchTabOptions = - /*#__PURE__*/ createRouteOptions(API_SWITCH_TAB); - const NavigateBackOptions = { - formatArgs: { - delta(value, params) { - value = parseInt(value + '') || 1; - params.delta = Math.min(getCurrentPages().length - 1, value); - }, - }, - }; - function createAnimationProtocol(animationTypes) { - return { - animationType: { - type: String, - validator(type) { - if (type && animationTypes.indexOf(type) === -1) { - return ('`' + - type + - '` is not supported for `animationType` (supported values are: `' + - animationTypes.join('`|`') + - '`)'); - } - }, - }, - animationDuration: { - type: Number, - }, - }; - } - let navigatorLock; - function beforeRoute() { - navigatorLock = ''; - } - function createRouteOptions(type) { - return { - formatArgs: { - url: createNormalizeUrl(type), - }, - beforeAll: beforeRoute, - }; - } - function createNormalizeUrl(type) { - return function normalizeUrl(url, params) { - if (!url) { - return `Missing required args: "url"`; - } - // 格式化为绝对路径路由 - url = normalizeRoute(url); - const pagePath = url.split('?')[0]; - // 匹配路由是否存在 - const routeOptions = getRouteOptions(pagePath, true); - if (!routeOptions) { - return 'page `' + url + '` is not found'; - } - // 检测不同类型跳转 - if (type === API_NAVIGATE_TO || type === API_REDIRECT_TO) { - if (routeOptions.meta.isTabBar) { - return `can not ${type} a tabbar page`; - } - } - else if (type === API_SWITCH_TAB) { - if (!routeOptions.meta.isTabBar) { - return 'can not switch to no-tabBar page'; - } - } - // switchTab不允许传递参数,reLaunch到一个tabBar页面是可以的 - if ((type === API_SWITCH_TAB || type === API_PRELOAD_PAGE) && - routeOptions.meta.isTabBar && - params.openType !== 'appLaunch') { - url = pagePath; - } - // 首页自动格式化为`/` - if (routeOptions.meta.isEntry) { - url = url.replace(routeOptions.alias, '/'); - } - // 参数格式化 - params.url = encodeQueryString(url); - if (type === API_UN_PRELOAD_PAGE) { - return; - } - else if (type === API_PRELOAD_PAGE) { - { - if (!routeOptions.meta.isNVue) { - return 'can not preload vue page'; - } - } - if (routeOptions.meta.isTabBar) { - const pages = getCurrentPages(); - const tabBarPagePath = routeOptions.path.substr(1); - if (pages.find((page) => page.route === tabBarPagePath)) { - return 'tabBar page `' + tabBarPagePath + '` already exists'; - } - } - return; - } - // 主要拦截目标为用户快速点击时触发的多次跳转,该情况,通常前后 url 是一样的 - if (navigatorLock === url && params.openType !== 'appLaunch') { - return `${navigatorLock} locked`; - } - // 至少 onLaunch 之后,再启用lock逻辑(onLaunch之前可能开发者手动调用路由API,来提前跳转) - // enableNavigatorLock 临时开关(不对外开放),避免该功能上线后,有部分情况异常,可以让开发者临时关闭 lock 功能 - if (__uniConfig.ready) { - navigatorLock = url; - } - }; - } +const ANIMATION_IN = [ + 'slide-in-right', + 'slide-in-left', + 'slide-in-top', + 'slide-in-bottom', + 'fade-in', + 'zoom-out', + 'zoom-fade-out', + 'pop-in', + 'none', +]; +const ANIMATION_OUT = [ + 'slide-out-right', + 'slide-out-left', + 'slide-out-top', + 'slide-out-bottom', + 'fade-out', + 'zoom-in', + 'zoom-fade-in', + 'pop-out', + 'none', +]; +const BaseRouteProtocol = { + url: { + type: String, + required: true, + }, +}; +const API_NAVIGATE_TO = 'navigateTo'; +const API_REDIRECT_TO = 'redirectTo'; +const API_RE_LAUNCH = 'reLaunch'; +const API_SWITCH_TAB = 'switchTab'; +const API_NAVIGATE_BACK = 'navigateBack'; +const API_PRELOAD_PAGE = 'preloadPage'; +const API_UN_PRELOAD_PAGE = 'unPreloadPage'; +const NavigateToProtocol = +/*#__PURE__*/ extend({}, BaseRouteProtocol, createAnimationProtocol(ANIMATION_IN)); +const NavigateBackProtocol = +/*#__PURE__*/ extend({ + delta: { + type: Number, + }, +}, createAnimationProtocol(ANIMATION_OUT)); +const RedirectToProtocol = BaseRouteProtocol; +const ReLaunchProtocol = BaseRouteProtocol; +const SwitchTabProtocol = BaseRouteProtocol; +const PreloadPageProtocol = BaseRouteProtocol; +const UnPreloadPageProtocol = BaseRouteProtocol; +const NavigateToOptions = +/*#__PURE__*/ createRouteOptions(API_NAVIGATE_TO); +const RedirectToOptions = +/*#__PURE__*/ createRouteOptions(API_REDIRECT_TO); +const ReLaunchOptions = +/*#__PURE__*/ createRouteOptions(API_RE_LAUNCH); +const SwitchTabOptions = +/*#__PURE__*/ createRouteOptions(API_SWITCH_TAB); +const NavigateBackOptions = { + formatArgs: { + delta(value, params) { + value = parseInt(value + '') || 1; + params.delta = Math.min(getCurrentPages().length - 1, value); + }, + }, +}; +function createAnimationProtocol(animationTypes) { + return { + animationType: { + type: String, + validator(type) { + if (type && animationTypes.indexOf(type) === -1) { + return ('`' + + type + + '` is not supported for `animationType` (supported values are: `' + + animationTypes.join('`|`') + + '`)'); + } + }, + }, + animationDuration: { + type: Number, + }, + }; +} +let navigatorLock; +function beforeRoute() { + navigatorLock = ''; +} +function createRouteOptions(type) { + return { + formatArgs: { + url: createNormalizeUrl(type), + }, + beforeAll: beforeRoute, + }; +} +function createNormalizeUrl(type) { + return function normalizeUrl(url, params) { + if (!url) { + return `Missing required args: "url"`; + } + // 格式化为绝对路径路由 + url = normalizeRoute(url); + const pagePath = url.split('?')[0]; + // 匹配路由是否存在 + const routeOptions = getRouteOptions(pagePath, true); + if (!routeOptions) { + return 'page `' + url + '` is not found'; + } + // 检测不同类型跳转 + if (type === API_NAVIGATE_TO || type === API_REDIRECT_TO) { + if (routeOptions.meta.isTabBar) { + return `can not ${type} a tabbar page`; + } + } + else if (type === API_SWITCH_TAB) { + if (!routeOptions.meta.isTabBar) { + return 'can not switch to no-tabBar page'; + } + } + // switchTab不允许传递参数,reLaunch到一个tabBar页面是可以的 + if ((type === API_SWITCH_TAB || type === API_PRELOAD_PAGE) && + routeOptions.meta.isTabBar && + params.openType !== 'appLaunch') { + url = pagePath; + } + // 首页自动格式化为`/` + if (routeOptions.meta.isEntry) { + url = url.replace(routeOptions.alias, '/'); + } + // 参数格式化 + params.url = encodeQueryString(url); + if (type === API_UN_PRELOAD_PAGE) { + return; + } + else if (type === API_PRELOAD_PAGE) { + { + if (!routeOptions.meta.isNVue) { + return 'can not preload vue page'; + } + } + if (routeOptions.meta.isTabBar) { + const pages = getCurrentPages(); + const tabBarPagePath = routeOptions.path.substr(1); + if (pages.find((page) => page.route === tabBarPagePath)) { + return 'tabBar page `' + tabBarPagePath + '` already exists'; + } + } + return; + } + // 主要拦截目标为用户快速点击时触发的多次跳转,该情况,通常前后 url 是一样的 + if (navigatorLock === url && params.openType !== 'appLaunch') { + return `${navigatorLock} locked`; + } + // 至少 onLaunch 之后,再启用lock逻辑(onLaunch之前可能开发者手动调用路由API,来提前跳转) + // enableNavigatorLock 临时开关(不对外开放),避免该功能上线后,有部分情况异常,可以让开发者临时关闭 lock 功能 + if (__uniConfig.ready) { + navigatorLock = url; + } + }; +} - const API_HIDE_LOADING = 'hideLoading'; - - const API_HIDE_TOAST = 'hideToast'; - - const API_LOAD_FONT_FACE = 'loadFontFace'; - const LoadFontFaceProtocol = { - family: { - type: String, - required: true, - }, - source: { - type: String, - required: true, - }, - desc: Object, - }; - - const FRONT_COLORS = ['#ffffff', '#000000']; - const API_SET_NAVIGATION_BAR_COLOR = 'setNavigationBarColor'; - const SetNavigationBarColorOptions = { - formatArgs: { - animation(animation, params) { - if (!animation) { - animation = { duration: 0, timingFunc: 'linear' }; - } - params.animation = { - duration: animation.duration || 0, - timingFunc: animation.timingFunc || 'linear', - }; - }, - }, - }; - const SetNavigationBarColorProtocol = { - frontColor: { - type: String, - required: true, - validator(frontColor) { - if (FRONT_COLORS.indexOf(frontColor) === -1) { - return `invalid frontColor "${frontColor}"`; - } - }, - }, - backgroundColor: { - type: String, - required: true, - }, - animation: Object, - }; - const API_SET_NAVIGATION_BAR_TITLE = 'setNavigationBarTitle'; - const SetNavigationBarTitleProtocol = { - title: { - type: String, - required: true, - }, - }; - const API_SHOW_NAVIGATION_BAR_LOADING = 'showNavigationBarLoading'; - const API_HIDE_NAVIGATION_BAR_LOADING = 'hideNavigationBarLoading'; - - const API_PAGE_SCROLL_TO = 'pageScrollTo'; - const PageScrollToProtocol = { - scrollTop: Number, - selector: String, - duration: Number, - }; - const DEFAULT_DURATION = 300; - const PageScrollToOptions = { - formatArgs: { - duration(value, params) { - params.duration = Math.max(0, parseInt(value + '') || DEFAULT_DURATION); - }, - }, - }; - - const API_SHOW_ACTION_SHEET = 'showActionSheet'; - const ShowActionSheetProtocol = { - itemList: { - type: Array, - required: true, - }, - title: String, - alertText: String, - itemColor: String, - popover: Object, - }; - const ShowActionSheetOptions = { - formatArgs: { - itemColor: '#000', - }, - }; - - const API_SHOW_LOADING = 'showLoading'; - const ShowLoadingProtocol = { - title: String, - mask: Boolean, - }; - const ShowLoadingOptions = { - formatArgs: { - title: '', - mask: false, - }, - }; - - const API_SHOW_MODAL = 'showModal'; - const ShowModalProtocol = { - title: String, - content: String, - showCancel: Boolean, - cancelText: String, - cancelColor: String, - confirmText: String, - confirmColor: String, - }; - const ShowModalOptions = { - beforeInvoke() { - // dynamic init (tree shaking) - initI18nShowModalMsgsOnce(); - }, - formatArgs: { - title: '', - content: '', - showCancel: true, - cancelText(_value, params) { - if (!shared.hasOwn(params, 'cancelText')) { - const { t } = useI18n(); - params.cancelText = t('uni.showModal.cancel'); - } - }, - cancelColor: '#000', - confirmText(_value, params) { - if (!shared.hasOwn(params, 'confirmText')) { - const { t } = useI18n(); - params.confirmText = t('uni.showModal.confirm'); - } - }, - confirmColor: PRIMARY_COLOR, - }, - }; - - const API_SHOW_TOAST = 'showToast'; - const SHOW_TOAST_ICON = [ - 'success', - 'loading', - 'none', - 'error', - ]; - const ShowToastProtocol = { - title: String, - icon: String, - image: String, - duration: Number, - mask: Boolean, - }; - const ShowToastOptions = { - formatArgs: { - title: '', - icon(type, params) { - params.icon = elemInArray(type, SHOW_TOAST_ICON); - }, - image(value, params) { - if (value) { - params.image = getRealPath(value); - } - else { - params.image = ''; - } - }, - duration: 1500, - mask: false, - }, - }; - - const API_START_PULL_DOWN_REFRESH = 'startPullDownRefresh'; - - const API_STOP_PULL_DOWN_REFRESH = 'stopPullDownRefresh'; - - const IndexProtocol = { - index: { - type: Number, - required: true, - }, - }; - const IndexOptions = { - beforeInvoke() { - const pageMeta = getCurrentPageMeta(); - if (pageMeta && !pageMeta.isTabBar) { - return 'not TabBar page'; - } - }, - formatArgs: { - index(value) { - if (!__uniConfig.tabBar.list[value]) { - return 'tabbar item not found'; - } - }, - }, - }; - const API_SET_TAB_BAR_ITEM = 'setTabBarItem'; - const SetTabBarItemProtocol = - /*#__PURE__*/ shared.extend({ - text: String, - iconPath: String, - selectedIconPath: String, - pagePath: String, - }, IndexProtocol); - const SetTabBarItemOptions = { - beforeInvoke: IndexOptions.beforeInvoke, - formatArgs: /*#__PURE__*/ shared.extend({ - pagePath(value, params) { - if (value) { - params.pagePath = removeLeadingSlash(value); - } - }, - }, IndexOptions.formatArgs), - }; - const API_SET_TAB_BAR_STYLE = 'setTabBarStyle'; - const SetTabBarStyleProtocol = { - color: String, - selectedColor: String, - backgroundColor: String, - backgroundImage: String, - backgroundRepeat: String, - borderStyle: String, - }; - const GRADIENT_RE = /^(linear|radial)-gradient\(.+?\);?$/; - const SetTabBarStyleOptions = { - beforeInvoke: IndexOptions.beforeInvoke, - formatArgs: { - backgroundImage(value, params) { - if (value && !GRADIENT_RE.test(value)) { - params.backgroundImage = getRealPath(value); - } - }, - borderStyle(value, params) { - if (value) { - params.borderStyle = value === 'white' ? 'white' : 'black'; - } - }, - }, - }; - const API_HIDE_TAB_BAR = 'hideTabBar'; - const HideTabBarProtocol = { - animation: Boolean, - }; - const API_SHOW_TAB_BAR = 'showTabBar'; - const ShowTabBarProtocol = HideTabBarProtocol; - const API_HIDE_TAB_BAR_RED_DOT = 'hideTabBarRedDot'; - const HideTabBarRedDotProtocol = IndexProtocol; - const HideTabBarRedDotOptions = IndexOptions; - const API_SHOW_TAB_BAR_RED_DOT = 'showTabBarRedDot'; - const ShowTabBarRedDotProtocol = IndexProtocol; - const ShowTabBarRedDotOptions = IndexOptions; - const API_REMOVE_TAB_BAR_BADGE = 'removeTabBarBadge'; - const RemoveTabBarBadgeProtocol = IndexProtocol; - const RemoveTabBarBadgeOptions = IndexOptions; - const API_SET_TAB_BAR_BADGE = 'setTabBarBadge'; - const SetTabBarBadgeProtocol = - /*#__PURE__*/ shared.extend({ - text: { - type: String, - required: true, - }, - }, IndexProtocol); - const SetTabBarBadgeOptions = { - beforeInvoke: IndexOptions.beforeInvoke, - formatArgs: /*#__PURE__*/ shared.extend({ - text(value, params) { - if (getLen(value) >= 4) { - params.text = '...'; - } - }, - }, IndexOptions.formatArgs), - }; - - const API_GET_PROVIDER = 'getProvider'; - const GetProviderProtocol = { - service: { - type: String, - required: true, - }, - }; - - const API_LOGIN = 'login'; - const LoginProtocol = { - provider: String, - scopes: [String, Array], - timeout: Number, - univerifyStyle: Object, - onlyAuthorize: Boolean, - }; - const API_GET_USER_INFO = 'getUserInfo'; - const GetUserInfoProtocol = { - provider: String, - withCredentials: Boolean, - timeout: Number, - lang: String, - }; - const API_GET_USER_PROFILE = 'ggetUserProfilegetUserProfile'; - const GgetUserProfileProtocol = { - provider: String, - withCredentials: Boolean, - timeout: Number, - lang: String, - }; - const API_PRE_LOGIN = 'preLogin'; - const provider = { - UNIVERIFY: 'univerify', - }; - const PreLoginOptions = { - formatArgs: { - provider(value, parmas) { - if (Object.values(provider).indexOf(String(value)) < 0) { - return 'provider error'; - } - }, - }, - }; - const PreLoginProtocol = { - provider: { - type: String, - required: true, - }, - }; - const API_CLOSE_AUTH_VIEW = 'closeAuthView'; - const API_GET_CHECK_BOX_STATE = 'getCheckBoxState'; - const API_GET_UNIVERIFY_MANAGER = 'getUniverifyManager'; - - const API_SHREA = 'share'; - const SCENE = [ - 'WXSceneSession', - 'WXSceneTimeline', - 'WXSceneFavorite', - ]; - const SahreOptions = { - formatArgs: { - scene(value, params) { - if (params.provider === 'weixin' && (!value || !SCENE.includes(value))) { - return `分享到微信时,scene必须为以下其中一个:${SCENE.join('、')}`; - } - }, - summary(value, params) { - if (params.type === 1 && !value) { - return '分享纯文本时,summary必填'; - } - }, - href(value, params) { - if (params.type === 0 && !value) { - return '分享图文时,href必填'; - } - }, - imageUrl(value, params) { - if ([0, 2, 5].includes(Number(params.type)) && !value) { - return '分享图文、纯图片、小程序时,imageUrl必填,推荐使用小于20Kb的图片'; - } - }, - mediaUrl(value, params) { - if ([3, 4].includes(Number(params.type)) && !value) { - return '分享音乐、视频时,mediaUrl必填'; - } - }, - miniProgram(value, params) { - if (params.type === 5 && !value) { - return '分享小程序时,miniProgram必填'; - } - }, - }, - }; - const ShareProtocols = { - provider: { - type: String, - required: true, - }, - type: Number, - title: String, - scene: String, - summary: String, - href: String, - imageUrl: String, - mediaUrl: String, - miniProgram: Object, - }; - const API_SHARE_WITH_SYSTEM = 'shareWithSystem'; - const TYPE = [ - 'text', - 'image', - ]; - const ShareWithSystemOptions = { - formatArgs: { - type(value, params) { - if (value && !TYPE.includes(value)) - return '分享参数 type 不正确。只支持text、image'; - params.type = elemInArray(value, TYPE); - }, - }, - }; - const ShareWithSystemProtocols = { - type: String, - summary: String, - href: String, - imageUrl: String, - }; - - const API_REQUEST_PAYMENT = 'requestPayment'; - const RequestPaymentProtocol = { - provider: { - type: String, - required: true, - }, - orderInfo: { - type: [String, Object], - required: true, - }, - timeStamp: String, - nonceStr: String, - package: String, - signType: String, - paySign: String, - }; - - const API_CREATE_REWARDED_VIDEO_AD = 'createRewardedVideoAd'; - const CreateRewardedVideoAdOptions = { - formatArgs: { - adpid: '', - adUnitId: '', - }, - }; - const CreateRewardedVideoAdProtocol = { - adpid: String, - adUnitId: String, - }; - - const API_CREATE_FULL_SCREEN_VIDEO_AD = 'createFullScreenVideoAd'; - const CreateFullScreenVideoAdOptions = { - formatArgs: { - adpid: '', - }, - }; - const CreateFullScreenVideoAdProtocol = { - adpid: String, - }; - - const API_CREATE_INTERSTITIAL_AD = 'createInterstitialAd'; - const CreateInterstitialAdOptions = { - formatArgs: { - adpid: '', - adUnitId: '', - }, - }; - const CreateInterstitialAdProtocol = { - adpid: String, - adUnitId: String, - }; - - const API_CREATE_INTERACTIVE_AD = 'createInteractiveAd'; - const CreateInteractiveAdOptions = { - formatArgs: { - adpid(value, params) { - if (!value) { - return 'adpid should not be empty.'; - } - if (value) - params.adpid = value; - }, - provider(value, params) { - if (!value) { - return 'provider should not be empty.'; - } - if (value) - params.provider = value; - }, - }, - }; - const CreateInteractiveAdProtocol = { - adpid: { - type: String, - required: true, - }, - provider: { - type: String, - required: true, - }, - }; - - function warpPlusSuccessCallback(resolve, after) { - return function successCallback(data) { - delete data.code; - delete data.message; - if (typeof after === 'function') { - data = after(data); - } - resolve(data); - }; - } - function warpPlusErrorCallback(reject, errMsg) { - return function errorCallback(error) { - error = error || {}; - // 一键登录errorCallback新增 appid、metadata、uid 参数返回 - errMsg = error.message || errMsg || ''; - delete error.message; - reject(errMsg, shared.extend({ code: 0 }, error)); - }; - } - function warpPlusEvent(plusObject, event) { - return function () { - const object = plusObject(); - object(function (data) { - if (data) { - delete data.code; - delete data.message; - } - UniServiceJSBridge.invokeOnCallback(event, data); - }); - }; - } - function warpPlusMethod(plusObject, before, after) { - return function (options, { resolve, reject }) { - const object = plusObject(); - object(shared.extend({}, typeof before === 'function' ? before(options) : options, { - success: warpPlusSuccessCallback(resolve, after), - fail: warpPlusErrorCallback(reject), - })); - }; - } - function isTabBarPage$1(path = '') { - if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) { - return false; - } - try { - if (!path) { - const pages = getCurrentPages(); - if (!pages.length) { - return false; - } - const page = pages[pages.length - 1]; - if (!page) { - return false; - } - return page.$page.meta.isTabBar; - } - if (!/^\//.test(path)) { - path = addLeadingSlash(path); - } - const route = getRouteOptions(path); - return route && route.meta.isTabBar; - } - catch (e) { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('isTabBarPage', e)); - } - } - return false; - } +const API_HIDE_LOADING = 'hideLoading'; + +const API_HIDE_TOAST = 'hideToast'; + +const API_LOAD_FONT_FACE = 'loadFontFace'; +const LoadFontFaceProtocol = { + family: { + type: String, + required: true, + }, + source: { + type: String, + required: true, + }, + desc: Object, +}; + +const FRONT_COLORS = ['#ffffff', '#000000']; +const API_SET_NAVIGATION_BAR_COLOR = 'setNavigationBarColor'; +const SetNavigationBarColorOptions = { + formatArgs: { + animation(animation, params) { + if (!animation) { + animation = { duration: 0, timingFunc: 'linear' }; + } + params.animation = { + duration: animation.duration || 0, + timingFunc: animation.timingFunc || 'linear', + }; + }, + }, +}; +const SetNavigationBarColorProtocol = { + frontColor: { + type: String, + required: true, + validator(frontColor) { + if (FRONT_COLORS.indexOf(frontColor) === -1) { + return `invalid frontColor "${frontColor}"`; + } + }, + }, + backgroundColor: { + type: String, + required: true, + }, + animation: Object, +}; +const API_SET_NAVIGATION_BAR_TITLE = 'setNavigationBarTitle'; +const SetNavigationBarTitleProtocol = { + title: { + type: String, + required: true, + }, +}; +const API_SHOW_NAVIGATION_BAR_LOADING = 'showNavigationBarLoading'; +const API_HIDE_NAVIGATION_BAR_LOADING = 'hideNavigationBarLoading'; + +const API_PAGE_SCROLL_TO = 'pageScrollTo'; +const PageScrollToProtocol = { + scrollTop: Number, + selector: String, + duration: Number, +}; +const DEFAULT_DURATION = 300; +const PageScrollToOptions = { + formatArgs: { + duration(value, params) { + params.duration = Math.max(0, parseInt(value + '') || DEFAULT_DURATION); + }, + }, +}; + +const API_SHOW_ACTION_SHEET = 'showActionSheet'; +const ShowActionSheetProtocol = { + itemList: { + type: Array, + required: true, + }, + title: String, + alertText: String, + itemColor: String, + popover: Object, +}; +const ShowActionSheetOptions = { + formatArgs: { + itemColor: '#000', + }, +}; + +const API_SHOW_LOADING = 'showLoading'; +const ShowLoadingProtocol = { + title: String, + mask: Boolean, +}; +const ShowLoadingOptions = { + formatArgs: { + title: '', + mask: false, + }, +}; + +const API_SHOW_MODAL = 'showModal'; +const ShowModalProtocol = { + title: String, + content: String, + showCancel: Boolean, + cancelText: String, + cancelColor: String, + confirmText: String, + confirmColor: String, +}; +const ShowModalOptions = { + beforeInvoke() { + // dynamic init (tree shaking) + initI18nShowModalMsgsOnce(); + }, + formatArgs: { + title: '', + content: '', + showCancel: true, + cancelText(_value, params) { + if (!hasOwn$1(params, 'cancelText')) { + const { t } = useI18n(); + params.cancelText = t('uni.showModal.cancel'); + } + }, + cancelColor: '#000', + confirmText(_value, params) { + if (!hasOwn$1(params, 'confirmText')) { + const { t } = useI18n(); + params.confirmText = t('uni.showModal.confirm'); + } + }, + confirmColor: PRIMARY_COLOR, + }, +}; + +const API_SHOW_TOAST = 'showToast'; +const SHOW_TOAST_ICON = [ + 'success', + 'loading', + 'none', + 'error', +]; +const ShowToastProtocol = { + title: String, + icon: String, + image: String, + duration: Number, + mask: Boolean, +}; +const ShowToastOptions = { + formatArgs: { + title: '', + icon(type, params) { + params.icon = elemInArray(type, SHOW_TOAST_ICON); + }, + image(value, params) { + if (value) { + params.image = getRealPath(value); + } + else { + params.image = ''; + } + }, + duration: 1500, + mask: false, + }, +}; + +const API_START_PULL_DOWN_REFRESH = 'startPullDownRefresh'; + +const API_STOP_PULL_DOWN_REFRESH = 'stopPullDownRefresh'; + +const IndexProtocol = { + index: { + type: Number, + required: true, + }, +}; +const IndexOptions = { + beforeInvoke() { + const pageMeta = getCurrentPageMeta(); + if (pageMeta && !pageMeta.isTabBar) { + return 'not TabBar page'; + } + }, + formatArgs: { + index(value) { + if (!__uniConfig.tabBar.list[value]) { + return 'tabbar item not found'; + } + }, + }, +}; +const API_SET_TAB_BAR_ITEM = 'setTabBarItem'; +const SetTabBarItemProtocol = +/*#__PURE__*/ extend({ + text: String, + iconPath: String, + selectedIconPath: String, + pagePath: String, +}, IndexProtocol); +const SetTabBarItemOptions = { + beforeInvoke: IndexOptions.beforeInvoke, + formatArgs: /*#__PURE__*/ extend({ + pagePath(value, params) { + if (value) { + params.pagePath = removeLeadingSlash(value); + } + }, + }, IndexOptions.formatArgs), +}; +const API_SET_TAB_BAR_STYLE = 'setTabBarStyle'; +const SetTabBarStyleProtocol = { + color: String, + selectedColor: String, + backgroundColor: String, + backgroundImage: String, + backgroundRepeat: String, + borderStyle: String, +}; +const GRADIENT_RE = /^(linear|radial)-gradient\(.+?\);?$/; +const SetTabBarStyleOptions = { + beforeInvoke: IndexOptions.beforeInvoke, + formatArgs: { + backgroundImage(value, params) { + if (value && !GRADIENT_RE.test(value)) { + params.backgroundImage = getRealPath(value); + } + }, + borderStyle(value, params) { + if (value) { + params.borderStyle = value === 'white' ? 'white' : 'black'; + } + }, + }, +}; +const API_HIDE_TAB_BAR = 'hideTabBar'; +const HideTabBarProtocol = { + animation: Boolean, +}; +const API_SHOW_TAB_BAR = 'showTabBar'; +const ShowTabBarProtocol = HideTabBarProtocol; +const API_HIDE_TAB_BAR_RED_DOT = 'hideTabBarRedDot'; +const HideTabBarRedDotProtocol = IndexProtocol; +const HideTabBarRedDotOptions = IndexOptions; +const API_SHOW_TAB_BAR_RED_DOT = 'showTabBarRedDot'; +const ShowTabBarRedDotProtocol = IndexProtocol; +const ShowTabBarRedDotOptions = IndexOptions; +const API_REMOVE_TAB_BAR_BADGE = 'removeTabBarBadge'; +const RemoveTabBarBadgeProtocol = IndexProtocol; +const RemoveTabBarBadgeOptions = IndexOptions; +const API_SET_TAB_BAR_BADGE = 'setTabBarBadge'; +const SetTabBarBadgeProtocol = +/*#__PURE__*/ extend({ + text: { + type: String, + required: true, + }, +}, IndexProtocol); +const SetTabBarBadgeOptions = { + beforeInvoke: IndexOptions.beforeInvoke, + formatArgs: /*#__PURE__*/ extend({ + text(value, params) { + if (getLen(value) >= 4) { + params.text = '...'; + } + }, + }, IndexOptions.formatArgs), +}; + +const API_GET_PROVIDER = 'getProvider'; +const GetProviderProtocol = { + service: { + type: String, + required: true, + }, +}; + +const API_LOGIN = 'login'; +const LoginProtocol = { + provider: String, + scopes: [String, Array], + timeout: Number, + univerifyStyle: Object, + onlyAuthorize: Boolean, +}; +const API_GET_USER_INFO = 'getUserInfo'; +const GetUserInfoProtocol = { + provider: String, + withCredentials: Boolean, + timeout: Number, + lang: String, +}; +const API_GET_USER_PROFILE = 'ggetUserProfilegetUserProfile'; +const GgetUserProfileProtocol = { + provider: String, + withCredentials: Boolean, + timeout: Number, + lang: String, +}; +const API_PRE_LOGIN = 'preLogin'; +const provider = { + UNIVERIFY: 'univerify', +}; +const PreLoginOptions = { + formatArgs: { + provider(value, parmas) { + if (Object.values(provider).indexOf(String(value)) < 0) { + return 'provider error'; + } + }, + }, +}; +const PreLoginProtocol = { + provider: { + type: String, + required: true, + }, +}; +const API_CLOSE_AUTH_VIEW = 'closeAuthView'; +const API_GET_CHECK_BOX_STATE = 'getCheckBoxState'; +const API_GET_UNIVERIFY_MANAGER = 'getUniverifyManager'; + +const API_SHREA = 'share'; +const SCENE = [ + 'WXSceneSession', + 'WXSceneTimeline', + 'WXSceneFavorite', +]; +const SahreOptions = { + formatArgs: { + scene(value, params) { + if (params.provider === 'weixin' && (!value || !SCENE.includes(value))) { + return `分享到微信时,scene必须为以下其中一个:${SCENE.join('、')}`; + } + }, + summary(value, params) { + if (params.type === 1 && !value) { + return '分享纯文本时,summary必填'; + } + }, + href(value, params) { + if (params.type === 0 && !value) { + return '分享图文时,href必填'; + } + }, + imageUrl(value, params) { + if ([0, 2, 5].includes(Number(params.type)) && !value) { + return '分享图文、纯图片、小程序时,imageUrl必填,推荐使用小于20Kb的图片'; + } + }, + mediaUrl(value, params) { + if ([3, 4].includes(Number(params.type)) && !value) { + return '分享音乐、视频时,mediaUrl必填'; + } + }, + miniProgram(value, params) { + if (params.type === 5 && !value) { + return '分享小程序时,miniProgram必填'; + } + }, + }, +}; +const ShareProtocols = { + provider: { + type: String, + required: true, + }, + type: Number, + title: String, + scene: String, + summary: String, + href: String, + imageUrl: String, + mediaUrl: String, + miniProgram: Object, +}; +const API_SHARE_WITH_SYSTEM = 'shareWithSystem'; +const TYPE = [ + 'text', + 'image', +]; +const ShareWithSystemOptions = { + formatArgs: { + type(value, params) { + if (value && !TYPE.includes(value)) + return '分享参数 type 不正确。只支持text、image'; + params.type = elemInArray(value, TYPE); + }, + }, +}; +const ShareWithSystemProtocols = { + type: String, + summary: String, + href: String, + imageUrl: String, +}; + +const API_REQUEST_PAYMENT = 'requestPayment'; +const RequestPaymentProtocol = { + provider: { + type: String, + required: true, + }, + orderInfo: { + type: [String, Object], + required: true, + }, + timeStamp: String, + nonceStr: String, + package: String, + signType: String, + paySign: String, +}; + +const API_CREATE_REWARDED_VIDEO_AD = 'createRewardedVideoAd'; +const CreateRewardedVideoAdOptions = { + formatArgs: { + adpid: '', + adUnitId: '', + }, +}; +const CreateRewardedVideoAdProtocol = { + adpid: String, + adUnitId: String, +}; + +const API_CREATE_FULL_SCREEN_VIDEO_AD = 'createFullScreenVideoAd'; +const CreateFullScreenVideoAdOptions = { + formatArgs: { + adpid: '', + }, +}; +const CreateFullScreenVideoAdProtocol = { + adpid: String, +}; + +const API_CREATE_INTERSTITIAL_AD = 'createInterstitialAd'; +const CreateInterstitialAdOptions = { + formatArgs: { + adpid: '', + adUnitId: '', + }, +}; +const CreateInterstitialAdProtocol = { + adpid: String, + adUnitId: String, +}; + +const API_CREATE_INTERACTIVE_AD = 'createInteractiveAd'; +const CreateInteractiveAdOptions = { + formatArgs: { + adpid(value, params) { + if (!value) { + return 'adpid should not be empty.'; + } + if (value) + params.adpid = value; + }, + provider(value, params) { + if (!value) { + return 'provider should not be empty.'; + } + if (value) + params.provider = value; + }, + }, +}; +const CreateInteractiveAdProtocol = { + adpid: { + type: String, + required: true, + }, + provider: { + type: String, + required: true, + }, +}; + +function warpPlusSuccessCallback(resolve, after) { + return function successCallback(data) { + delete data.code; + delete data.message; + if (typeof after === 'function') { + data = after(data); + } + resolve(data); + }; +} +function warpPlusErrorCallback(reject, errMsg) { + return function errorCallback(error) { + error = error || {}; + // 一键登录errorCallback新增 appid、metadata、uid 参数返回 + errMsg = error.message || errMsg || ''; + delete error.message; + reject(errMsg, extend({ code: 0 }, error)); + }; +} +function warpPlusEvent(plusObject, event) { + return function () { + const object = plusObject(); + object(function (data) { + if (data) { + delete data.code; + delete data.message; + } + UniServiceJSBridge.invokeOnCallback(event, data); + }); + }; +} +function warpPlusMethod(plusObject, before, after) { + return function (options, { resolve, reject }) { + const object = plusObject(); + object(extend({}, typeof before === 'function' ? before(options) : options, { + success: warpPlusSuccessCallback(resolve, after), + fail: warpPlusErrorCallback(reject), + })); + }; +} +function isTabBarPage$1(path = '') { + if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) { + return false; + } + try { + if (!path) { + const pages = getCurrentPages(); + if (!pages.length) { + return false; + } + const page = pages[pages.length - 1]; + if (!page) { + return false; + } + return page.$page.meta.isTabBar; + } + if (!/^\//.test(path)) { + path = addLeadingSlash(path); + } + const route = getRouteOptions(path); + return route && route.meta.isTabBar; + } + catch (e) { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('isTabBarPage', e)); + } + } + return false; +} - const STORAGE_DATA_TYPE = '__TYPE'; - const STORAGE_KEYS = 'uni-storage-keys'; - function parseValue(value) { - const types = ['object', 'string', 'number', 'boolean', 'undefined']; - try { - const object = typeof value === 'string' ? JSON.parse(value) : value; - const type = object.type; - if (types.indexOf(type) >= 0) { - const keys = Object.keys(object); - if (keys.length === 2 && 'data' in object) { - // eslint-disable-next-line valid-typeof - if (typeof object.data === type) { - return object.data; - } - // eslint-disable-next-line no-useless-escape - if (type === 'object' && - /^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z$/.test(object.data)) { - // ISO 8601 格式返回 Date - return new Date(object.data); - } - } - else if (keys.length === 1) { - return ''; - } - } - } - catch (error) { } - } - const setStorageSync = defineSyncApi(API_SET_STORAGE_SYNC, (key, data) => { - const type = typeof data; - const value = type === 'string' - ? data - : JSON.stringify({ - type, - data: data, - }); - try { - if (type === 'string' && parseValue(value) !== undefined) { - plus.storage.setItem(key + STORAGE_DATA_TYPE, type); - } - else { - plus.storage.removeItem(key + STORAGE_DATA_TYPE); - } - plus.storage.setItem(key, value); - } - catch (error) { } - }, SetStorageSyncProtocol); - const setStorage = defineAsyncApi(API_SET_STORAGE, ({ key, data }, { resolve, reject }) => { - const type = typeof data; - const value = type === 'string' - ? data - : JSON.stringify({ - type, - data: data, - }); - try { - const storage = plus.storage; - if (type === 'string' && parseValue(value) !== undefined) { - storage.setItemAsync(key + STORAGE_DATA_TYPE, type); - } - else { - storage.removeItemAsync(key + STORAGE_DATA_TYPE); - } - storage.setItemAsync(key, value, resolve, warpPlusErrorCallback(reject)); - } - catch (error) { - reject(error.message); - } - }, SetStorageProtocol); - function parseGetStorage(type, value) { - let data = value; - if (type !== 'string' || - (type === 'string' && value === '{"type":"undefined"}')) { - try { - // 兼容H5和V3初期历史格式 - let object = JSON.parse(value); - const result = parseValue(object); - if (result !== undefined) { - data = result; - } - else if (type) { - // 兼容App端历史格式 - data = object; - if (typeof object === 'string') { - object = JSON.parse(object); - const objectType = typeof object; - if (objectType === 'number' && type === 'date') { - data = new Date(object); - } - else if (objectType === - (['null', 'array'].indexOf(type) < 0 ? type : 'object')) { - data = object; - } - } - } - } - catch (error) { } - } - return data; - } - const getStorageSync = defineSyncApi(API_GET_STORAGE_SYNC, (key, t) => { - const value = plus.storage.getItem(key); - const typeOrigin = plus.storage.getItem(key + STORAGE_DATA_TYPE) || ''; - const type = typeOrigin.toLowerCase(); - if (typeof value !== 'string') { - return ''; - } - return parseGetStorage(type, value); - }, GetStorageSyncProtocol); - const getStorage = defineAsyncApi(API_GET_STORAGE, ({ key }, { resolve, reject }) => { - const storage = plus.storage; - storage.getItemAsync(key, function (res) { - storage.getItemAsync(key + STORAGE_DATA_TYPE, function (typeRes) { - const typeOrigin = typeRes.data || ''; - const type = typeOrigin.toLowerCase(); - resolve({ - data: parseGetStorage(type, res.data), - }); - }, function () { - const type = ''; - resolve({ - data: parseGetStorage(type, res.data), - }); - }); - }, warpPlusErrorCallback(reject)); - }, GetStorageProtocol); - const removeStorageSync = defineSyncApi(API_REMOVE_STORAGE, (key) => { - plus.storage.removeItem(key + STORAGE_DATA_TYPE); - plus.storage.removeItem(key); - }, RemoveStorageSyncProtocol); - const removeStorage = defineAsyncApi(API_REMOVE_STORAGE, ({ key }, { resolve, reject }) => { - // 兼容App端历史格式 - plus.storage.removeItemAsync(key + STORAGE_DATA_TYPE); - plus.storage.removeItemAsync(key, resolve, warpPlusErrorCallback(reject)); - }, RemoveStorageProtocol); - const clearStorageSync = (defineSyncApi('clearStorageSync', () => { - plus.storage.clear(); - })); - const clearStorage = (defineAsyncApi('clearStorage', (_, { resolve, reject }) => { - plus.storage.clearAsync(resolve, warpPlusErrorCallback(reject)); - })); - const getStorageInfoSync = (defineSyncApi('getStorageInfoSync', () => { - const length = plus.storage.getLength() || 0; - const keys = []; - let currentSize = 0; - for (let index = 0; index < length; index++) { - const key = plus.storage.key(index); - if (key !== STORAGE_KEYS && - (key.indexOf(STORAGE_DATA_TYPE) < 0 || - key.indexOf(STORAGE_DATA_TYPE) + STORAGE_DATA_TYPE.length !== - key.length)) { - const value = plus.storage.getItem(key); - currentSize += key.length + value.length; - keys.push(key); - } - } - return { - keys, - currentSize: Math.ceil((currentSize * 2) / 1024), - limitSize: Number.MAX_VALUE, - }; - })); - const getStorageInfo = (defineAsyncApi('getStorageInfo', (_, { resolve }) => { - resolve(getStorageInfoSync()); - })); - - const getFileInfo$1 = defineAsyncApi(API_GET_FILE_INFO, (options, { resolve, reject }) => { - plus.io.getFileInfo(shared.extend(options, { - success: warpPlusSuccessCallback(resolve), - fail: warpPlusErrorCallback(reject), - })); - }, GetFileInfoProtocol, GetFileInfoOptions); - - const openDocument = defineAsyncApi(API_OPEN_DOCUMENT, ({ filePath, fileType }, { resolve, reject }) => { - const errorCallback = warpPlusErrorCallback(reject); - plus.runtime.openDocument(getRealPath(filePath), undefined, resolve, errorCallback); - }, OpenDocumentProtocol, OpenDocumentOptions); - - function getFileName(path) { - const array = path.split('/'); - return array[array.length - 1]; - } - function getExtName(path) { - const array = path.split('.'); - return array.length > 1 ? '.' + array[array.length - 1] : ''; - } +const STORAGE_DATA_TYPE = '__TYPE'; +const STORAGE_KEYS = 'uni-storage-keys'; +function parseValue(value) { + const types = ['object', 'string', 'number', 'boolean', 'undefined']; + try { + const object = typeof value === 'string' ? JSON.parse(value) : value; + const type = object.type; + if (types.indexOf(type) >= 0) { + const keys = Object.keys(object); + if (keys.length === 2 && 'data' in object) { + // eslint-disable-next-line valid-typeof + if (typeof object.data === type) { + return object.data; + } + // eslint-disable-next-line no-useless-escape + if (type === 'object' && + /^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}Z$/.test(object.data)) { + // ISO 8601 格式返回 Date + return new Date(object.data); + } + } + else if (keys.length === 1) { + return ''; + } + } + } + catch (error) { } +} +const setStorageSync = defineSyncApi(API_SET_STORAGE_SYNC, (key, data) => { + const type = typeof data; + const value = type === 'string' + ? data + : JSON.stringify({ + type, + data: data, + }); + try { + if (type === 'string' && parseValue(value) !== undefined) { + plus.storage.setItem(key + STORAGE_DATA_TYPE, type); + } + else { + plus.storage.removeItem(key + STORAGE_DATA_TYPE); + } + plus.storage.setItem(key, value); + } + catch (error) { } +}, SetStorageSyncProtocol); +const setStorage = defineAsyncApi(API_SET_STORAGE, ({ key, data }, { resolve, reject }) => { + const type = typeof data; + const value = type === 'string' + ? data + : JSON.stringify({ + type, + data: data, + }); + try { + const storage = plus.storage; + if (type === 'string' && parseValue(value) !== undefined) { + storage.setItemAsync(key + STORAGE_DATA_TYPE, type); + } + else { + storage.removeItemAsync(key + STORAGE_DATA_TYPE); + } + storage.setItemAsync(key, value, resolve, warpPlusErrorCallback(reject)); + } + catch (error) { + reject(error.message); + } +}, SetStorageProtocol); +function parseGetStorage(type, value) { + let data = value; + if (type !== 'string' || + (type === 'string' && value === '{"type":"undefined"}')) { + try { + // 兼容H5和V3初期历史格式 + let object = JSON.parse(value); + const result = parseValue(object); + if (result !== undefined) { + data = result; + } + else if (type) { + // 兼容App端历史格式 + data = object; + if (typeof object === 'string') { + object = JSON.parse(object); + const objectType = typeof object; + if (objectType === 'number' && type === 'date') { + data = new Date(object); + } + else if (objectType === + (['null', 'array'].indexOf(type) < 0 ? type : 'object')) { + data = object; + } + } + } + } + catch (error) { } + } + return data; +} +const getStorageSync = defineSyncApi(API_GET_STORAGE_SYNC, (key, t) => { + const value = plus.storage.getItem(key); + const typeOrigin = plus.storage.getItem(key + STORAGE_DATA_TYPE) || ''; + const type = typeOrigin.toLowerCase(); + if (typeof value !== 'string') { + return ''; + } + return parseGetStorage(type, value); +}, GetStorageSyncProtocol); +const getStorage = defineAsyncApi(API_GET_STORAGE, ({ key }, { resolve, reject }) => { + const storage = plus.storage; + storage.getItemAsync(key, function (res) { + storage.getItemAsync(key + STORAGE_DATA_TYPE, function (typeRes) { + const typeOrigin = typeRes.data || ''; + const type = typeOrigin.toLowerCase(); + resolve({ + data: parseGetStorage(type, res.data), + }); + }, function () { + const type = ''; + resolve({ + data: parseGetStorage(type, res.data), + }); + }); + }, warpPlusErrorCallback(reject)); +}, GetStorageProtocol); +const removeStorageSync = defineSyncApi(API_REMOVE_STORAGE, (key) => { + plus.storage.removeItem(key + STORAGE_DATA_TYPE); + plus.storage.removeItem(key); +}, RemoveStorageSyncProtocol); +const removeStorage = defineAsyncApi(API_REMOVE_STORAGE, ({ key }, { resolve, reject }) => { + // 兼容App端历史格式 + plus.storage.removeItemAsync(key + STORAGE_DATA_TYPE); + plus.storage.removeItemAsync(key, resolve, warpPlusErrorCallback(reject)); +}, RemoveStorageProtocol); +const clearStorageSync = (defineSyncApi('clearStorageSync', () => { + plus.storage.clear(); +})); +const clearStorage = (defineAsyncApi('clearStorage', (_, { resolve, reject }) => { + plus.storage.clearAsync(resolve, warpPlusErrorCallback(reject)); +})); +const getStorageInfoSync = (defineSyncApi('getStorageInfoSync', () => { + const length = plus.storage.getLength() || 0; + const keys = []; + let currentSize = 0; + for (let index = 0; index < length; index++) { + const key = plus.storage.key(index); + if (key !== STORAGE_KEYS && + (key.indexOf(STORAGE_DATA_TYPE) < 0 || + key.indexOf(STORAGE_DATA_TYPE) + STORAGE_DATA_TYPE.length !== + key.length)) { + const value = plus.storage.getItem(key); + currentSize += key.length + value.length; + keys.push(key); + } + } + return { + keys, + currentSize: Math.ceil((currentSize * 2) / 1024), + limitSize: Number.MAX_VALUE, + }; +})); +const getStorageInfo = (defineAsyncApi('getStorageInfo', (_, { resolve }) => { + resolve(getStorageInfoSync()); +})); + +const getFileInfo$1 = defineAsyncApi(API_GET_FILE_INFO, (options, { resolve, reject }) => { + plus.io.getFileInfo(extend(options, { + success: warpPlusSuccessCallback(resolve), + fail: warpPlusErrorCallback(reject), + })); +}, GetFileInfoProtocol, GetFileInfoOptions); + +const openDocument = defineAsyncApi(API_OPEN_DOCUMENT, ({ filePath, fileType }, { resolve, reject }) => { + const errorCallback = warpPlusErrorCallback(reject); + plus.runtime.openDocument(getRealPath(filePath), undefined, resolve, errorCallback); +}, OpenDocumentProtocol, OpenDocumentOptions); + +function getFileName(path) { + const array = path.split('/'); + return array[array.length - 1]; +} +function getExtName(path) { + const array = path.split('.'); + return array.length > 1 ? '.' + array[array.length - 1] : ''; +} - let index$2 = 0; - const SAVED_DIR = 'uniapp_save'; - const SAVE_PATH = `_doc/${SAVED_DIR}`; - function getSavedFileDir(success, fail) { - fail = fail || function () { }; - plus.io.requestFileSystem(plus.io.PRIVATE_DOC, (fs) => { - // 请求_doc fs - fs.root.getDirectory(SAVED_DIR, { - // 获取文件保存目录对象 - create: true, - }, success, fail); - }, fail); - } - const saveFile = defineAsyncApi(API_SAVE_FILE, ({ tempFilePath }, { resolve, reject }) => { - const errorCallback = warpPlusErrorCallback(reject); - const fileName = `${Date.now()}${index$2++}${getExtName(tempFilePath)}`; - plus.io.resolveLocalFileSystemURL(tempFilePath, (entry) => { - // 读取临时文件 FileEntry - getSavedFileDir((dir) => { - entry.copyTo(dir, fileName, () => { - // 复制临时文件 FileEntry,为了避免把相册里的文件删除,使用 copy,微信中是要删除临时文件的 - const savedFilePath = SAVE_PATH + '/' + fileName; - resolve({ - savedFilePath, - }); - }, errorCallback); - }, errorCallback); - }, errorCallback); - }, SaveFileProtocol, SaveFileOptions); - - const isIOS = plus.os.name === 'iOS'; - let config; - /** - * tabbar显示状态 - */ - let visible = true; - let tabBar; - /** - * 设置角标 - * @param {string} type - * @param {number} index - * @param {string} text - */ - function setTabBarBadge$1(type, index, text) { - if (!tabBar) { - return; - } - if (type === 'none') { - tabBar.hideTabBarRedDot({ - index, - }); - tabBar.removeTabBarBadge({ - index, - }); - } - else if (type === 'text') { - tabBar.setTabBarBadge({ - index, - text, - }); - } - else if (type === 'redDot') { - tabBar.showTabBarRedDot({ - index, - }); - } - } - /** - * 动态设置 tabBar 某一项的内容 - */ - function setTabBarItem$1(index, text, iconPath, selectedIconPath, visible) { - const item = { - index, - }; - if (text !== undefined) { - item.text = text; - } - if (iconPath) { - item.iconPath = getRealPath(iconPath); - } - if (selectedIconPath) { - item.selectedIconPath = getRealPath(selectedIconPath); - } - if (visible !== undefined) { - item.visible = config.list[index].visible = visible; - delete item.index; - const tabbarItems = config.list.map((item) => ({ - visible: item.visible, - })); - tabbarItems[index] = item; - tabBar && tabBar.setTabBarItems({ list: tabbarItems }); - } - else { - tabBar && tabBar.setTabBarItem(item); - } - } - /** - * 动态设置 tabBar 的整体样式 - * @param {Object} style 样式 - */ - function setTabBarStyle$1(style) { - tabBar && tabBar.setTabBarStyle(style); - } - /** - * 隐藏 tabBar - * @param {boolean} animation 是否需要动画效果 - */ - function hideTabBar$1(animation) { - visible = false; - tabBar && - tabBar.hideTabBar({ - animation, - }); - } - /** - * 显示 tabBar - * @param {boolean} animation 是否需要动画效果 - */ - function showTabBar$1(animation) { - visible = true; - tabBar && - tabBar.showTabBar({ - animation, - }); - } - const maskClickCallback = []; - var tabBar$1 = { - id: '0', - init(options, clickCallback) { - if (options && options.list.length) { - config = options; - } - try { - tabBar = weex.requireModule('uni-tabview'); - } - catch (error) { - console.log(`uni.requireNativePlugin("uni-tabview") error ${error}`); - } - tabBar.onMaskClick(() => { - maskClickCallback.forEach((callback) => { - callback(); - }); - }); - tabBar && - tabBar.onClick(({ index }) => { - clickCallback(config.list[index], index); - }); - tabBar && - tabBar.onMidButtonClick(() => { - return UniServiceJSBridge.invokeOnCallback(API_ON_TAB_BAR_MID_BUTTON_TAP); - }); - }, - indexOf(page) { - const itemLength = config && config.list && config.list.length; - if (itemLength) { - for (let i = 0; i < itemLength; i++) { - if (config.list[i].pagePath === page || - config.list[i].pagePath === `${page}.html`) { - return i; - } - } - } - return -1; - }, - switchTab(page) { - const index = this.indexOf(page); - if (index >= 0) { - tabBar && - tabBar.switchSelect({ - index, - }); - return true; - } - return false; - }, - setTabBarBadge: setTabBarBadge$1, - setTabBarItem: setTabBarItem$1, - setTabBarStyle: setTabBarStyle$1, - hideTabBar: hideTabBar$1, - showTabBar: showTabBar$1, - append(webview) { - tabBar && - tabBar.append({ - id: webview.id, - }, ({ code }) => { - if (code !== 0) { - setTimeout(() => { - this.append(webview); - }, 20); - } - }); - }, - get visible() { - return visible; - }, - get height() { - return ((config && config.height ? parseFloat(config.height) : TABBAR_HEIGHT) + - plus.navigator.getSafeAreaInsets().deviceBottom); - }, - // tabBar是否遮挡内容区域 - get cover() { - const array = ['extralight', 'light', 'dark']; - return isIOS && array.indexOf(config.blurEffect) >= 0; - }, - setStyle({ mask }) { - tabBar.setMask({ - color: mask, - }); - }, - addEventListener(_name, callback) { - maskClickCallback.push(callback); - }, - removeEventListener(_name, callback) { - const callbackIndex = maskClickCallback.indexOf(callback); - maskClickCallback.splice(callbackIndex, 1); - }, - }; - - function getCurrentWebview() { - const page = getCurrentPage(); - if (page) { - return page.$getAppWebview(); - } - return null; - } - function getWebview(page) { - if (page) { - return page.$getAppWebview(); - } - return getCurrentWebview(); - } - let pullDownRefreshWebview = null; - function getPullDownRefreshWebview() { - return pullDownRefreshWebview; - } - function setPullDownRefreshWebview(webview) { - pullDownRefreshWebview = webview; - } - function isTabBarPage(path = '') { - if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) { - return false; - } - try { - if (!path) { - const pages = getCurrentPages(); - if (!pages.length) { - return false; - } - const page = pages[pages.length - 1]; - if (!page) { - return false; - } - return page.$page.meta.isTabBar; - } - if (!/^\//.test(path)) { - path = addLeadingSlash(path); - } - const route = __uniRoutes.find((route) => route.path === path); - return route && route.meta.isTabBar; - } - catch (e) { - if (process.env.NODE_ENV !== 'production') { - console.log('getCurrentPages is not ready'); - } - } - return false; - } +let index$2 = 0; +const SAVED_DIR = 'uniapp_save'; +const SAVE_PATH = `_doc/${SAVED_DIR}`; +function getSavedFileDir(success, fail) { + fail = fail || function () { }; + plus.io.requestFileSystem(plus.io.PRIVATE_DOC, (fs) => { + // 请求_doc fs + fs.root.getDirectory(SAVED_DIR, { + // 获取文件保存目录对象 + create: true, + }, success, fail); + }, fail); +} +const saveFile = defineAsyncApi(API_SAVE_FILE, ({ tempFilePath }, { resolve, reject }) => { + const errorCallback = warpPlusErrorCallback(reject); + const fileName = `${Date.now()}${index$2++}${getExtName(tempFilePath)}`; + plus.io.resolveLocalFileSystemURL(tempFilePath, (entry) => { + // 读取临时文件 FileEntry + getSavedFileDir((dir) => { + entry.copyTo(dir, fileName, () => { + // 复制临时文件 FileEntry,为了避免把相册里的文件删除,使用 copy,微信中是要删除临时文件的 + const savedFilePath = SAVE_PATH + '/' + fileName; + resolve({ + savedFilePath, + }); + }, errorCallback); + }, errorCallback); + }, errorCallback); +}, SaveFileProtocol, SaveFileOptions); + +const isIOS = plus.os.name === 'iOS'; +let config; +/** + * tabbar显示状态 + */ +let visible = true; +let tabBar; +/** + * 设置角标 + * @param {string} type + * @param {number} index + * @param {string} text + */ +function setTabBarBadge$1(type, index, text) { + if (!tabBar) { + return; + } + if (type === 'none') { + tabBar.hideTabBarRedDot({ + index, + }); + tabBar.removeTabBarBadge({ + index, + }); + } + else if (type === 'text') { + tabBar.setTabBarBadge({ + index, + text, + }); + } + else if (type === 'redDot') { + tabBar.showTabBarRedDot({ + index, + }); + } +} +/** + * 动态设置 tabBar 某一项的内容 + */ +function setTabBarItem$1(index, text, iconPath, selectedIconPath, visible) { + const item = { + index, + }; + if (text !== undefined) { + item.text = text; + } + if (iconPath) { + item.iconPath = getRealPath(iconPath); + } + if (selectedIconPath) { + item.selectedIconPath = getRealPath(selectedIconPath); + } + if (visible !== undefined) { + item.visible = config.list[index].visible = visible; + delete item.index; + const tabbarItems = config.list.map((item) => ({ + visible: item.visible, + })); + tabbarItems[index] = item; + tabBar && tabBar.setTabBarItems({ list: tabbarItems }); + } + else { + tabBar && tabBar.setTabBarItem(item); + } +} +/** + * 动态设置 tabBar 的整体样式 + * @param {Object} style 样式 + */ +function setTabBarStyle$1(style) { + tabBar && tabBar.setTabBarStyle(style); +} +/** + * 隐藏 tabBar + * @param {boolean} animation 是否需要动画效果 + */ +function hideTabBar$1(animation) { + visible = false; + tabBar && + tabBar.hideTabBar({ + animation, + }); +} +/** + * 显示 tabBar + * @param {boolean} animation 是否需要动画效果 + */ +function showTabBar$1(animation) { + visible = true; + tabBar && + tabBar.showTabBar({ + animation, + }); +} +const maskClickCallback = []; +var tabBar$1 = { + id: '0', + init(options, clickCallback) { + if (options && options.list.length) { + config = options; + } + try { + tabBar = weex.requireModule('uni-tabview'); + } + catch (error) { + console.log(`uni.requireNativePlugin("uni-tabview") error ${error}`); + } + tabBar.onMaskClick(() => { + maskClickCallback.forEach((callback) => { + callback(); + }); + }); + tabBar && + tabBar.onClick(({ index }) => { + clickCallback(config.list[index], index); + }); + tabBar && + tabBar.onMidButtonClick(() => { + return UniServiceJSBridge.invokeOnCallback(API_ON_TAB_BAR_MID_BUTTON_TAP); + }); + }, + indexOf(page) { + const itemLength = config && config.list && config.list.length; + if (itemLength) { + for (let i = 0; i < itemLength; i++) { + if (config.list[i].pagePath === page || + config.list[i].pagePath === `${page}.html`) { + return i; + } + } + } + return -1; + }, + switchTab(page) { + const index = this.indexOf(page); + if (index >= 0) { + tabBar && + tabBar.switchSelect({ + index, + }); + return true; + } + return false; + }, + setTabBarBadge: setTabBarBadge$1, + setTabBarItem: setTabBarItem$1, + setTabBarStyle: setTabBarStyle$1, + hideTabBar: hideTabBar$1, + showTabBar: showTabBar$1, + append(webview) { + tabBar && + tabBar.append({ + id: webview.id, + }, ({ code }) => { + if (code !== 0) { + setTimeout(() => { + this.append(webview); + }, 20); + } + }); + }, + get visible() { + return visible; + }, + get height() { + return ((config && config.height ? parseFloat(config.height) : TABBAR_HEIGHT) + + plus.navigator.getSafeAreaInsets().deviceBottom); + }, + // tabBar是否遮挡内容区域 + get cover() { + const array = ['extralight', 'light', 'dark']; + return isIOS && array.indexOf(config.blurEffect) >= 0; + }, + setStyle({ mask }) { + tabBar.setMask({ + color: mask, + }); + }, + addEventListener(_name, callback) { + maskClickCallback.push(callback); + }, + removeEventListener(_name, callback) { + const callbackIndex = maskClickCallback.indexOf(callback); + maskClickCallback.splice(callbackIndex, 1); + }, +}; + +function getCurrentWebview() { + const page = getCurrentPage(); + if (page) { + return page.$getAppWebview(); + } + return null; +} +function getWebview(page) { + if (page) { + return page.$getAppWebview(); + } + return getCurrentWebview(); +} +let pullDownRefreshWebview = null; +function getPullDownRefreshWebview() { + return pullDownRefreshWebview; +} +function setPullDownRefreshWebview(webview) { + pullDownRefreshWebview = webview; +} +function isTabBarPage(path = '') { + if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) { + return false; + } + try { + if (!path) { + const pages = getCurrentPages(); + if (!pages.length) { + return false; + } + const page = pages[pages.length - 1]; + if (!page) { + return false; + } + return page.$page.meta.isTabBar; + } + if (!/^\//.test(path)) { + path = addLeadingSlash(path); + } + const route = __uniRoutes.find((route) => route.path === path); + return route && route.meta.isTabBar; + } + catch (e) { + if (process.env.NODE_ENV !== 'production') { + console.log('getCurrentPages is not ready'); + } + } + return false; +} - function getStatusbarHeight() { - // 横屏时 iOS 获取的状态栏高度错误,进行纠正 - return plus.navigator.isImmersedStatusbar() - ? Math.round(plus.os.name === 'iOS' - ? plus.navigator.getSafeAreaInsets().top - : plus.navigator.getStatusbarHeight()) - : 0; - } - function getStatusBarStyle() { - let style = plus.navigator.getStatusBarStyle(); - if (style === 'UIStatusBarStyleBlackTranslucent' || - style === 'UIStatusBarStyleBlackOpaque' || - style === 'null') { - style = 'light'; - } - else if (style === 'UIStatusBarStyleDefault') { - style = 'dark'; - } - return style; - } +function getStatusbarHeight() { + // 横屏时 iOS 获取的状态栏高度错误,进行纠正 + return plus.navigator.isImmersedStatusbar() + ? Math.round(plus.os.name === 'iOS' + ? plus.navigator.getSafeAreaInsets().top + : plus.navigator.getStatusbarHeight()) + : 0; +} +function getStatusBarStyle() { + let style = plus.navigator.getStatusBarStyle(); + if (style === 'UIStatusBarStyleBlackTranslucent' || + style === 'UIStatusBarStyleBlackOpaque' || + style === 'null') { + style = 'light'; + } + else if (style === 'UIStatusBarStyleDefault') { + style = 'dark'; + } + return style; +} - let deviceId; - function deviceId$1 () { - deviceId = deviceId || plus.device.uuid; - return deviceId; - } +let deviceId; +function deviceId$1 () { + deviceId = deviceId || plus.device.uuid; + return deviceId; +} - function getScreenInfo() { - const { resolutionWidth, resolutionHeight } = plus.screen.getCurrentSize(); - return { - screenWidth: Math.round(resolutionWidth), - screenHeight: Math.round(resolutionHeight), - }; - } - const getSystemInfoSync = defineSyncApi('getSystemInfoSync', () => { - const platform = plus.os.name.toLowerCase(); - const ios = platform === 'ios'; - const isAndroid = platform === 'android'; - const { screenWidth, screenHeight } = getScreenInfo(); - const statusBarHeight = getStatusbarHeight(); - let safeAreaInsets; - const titleNView = { - height: 0, - cover: false, - }; - const webview = getCurrentWebview(); - if (webview) { - const webStyle = webview.getStyle(); - const style = webStyle && webStyle.titleNView; - if (style && style.type && style.type !== 'none') { - titleNView.height = - style.type === 'transparent' ? 0 : statusBarHeight + NAVBAR_HEIGHT; - titleNView.cover = - style.type === 'transparent' || style.type === 'float'; - } - safeAreaInsets = webview.getSafeAreaInsets(); - } - else { - safeAreaInsets = plus.navigator.getSafeAreaInsets(); - } - const tabBarView = { - height: 0, - cover: false, - }; - if (isTabBarPage$1()) { - tabBarView.height = tabBar$1.visible ? tabBar$1.height : 0; - tabBarView.cover = tabBar$1.cover; - } - const windowTop = titleNView.cover ? titleNView.height : 0; - const windowBottom = tabBarView.cover ? tabBarView.height : 0; - let windowHeight = screenHeight - titleNView.height - tabBarView.height; - let windowHeightReal = screenHeight - - (titleNView.cover ? 0 : titleNView.height) - - (tabBarView.cover ? 0 : tabBarView.height); - const windowWidth = screenWidth; - if ((!tabBarView.height || tabBarView.cover) && - !safeAreaInsets.bottom && - safeAreaInsets.deviceBottom) { - windowHeight -= safeAreaInsets.deviceBottom; - windowHeightReal -= safeAreaInsets.deviceBottom; - } - safeAreaInsets = ios - ? safeAreaInsets - : { - left: 0, - right: 0, - top: titleNView.height && !titleNView.cover ? 0 : statusBarHeight, - bottom: 0, - }; - const safeArea = { - left: safeAreaInsets.left, - right: windowWidth - safeAreaInsets.right, - top: safeAreaInsets.top, - bottom: windowHeightReal - safeAreaInsets.bottom, - width: windowWidth - safeAreaInsets.left - safeAreaInsets.right, - height: windowHeightReal - safeAreaInsets.top - safeAreaInsets.bottom, - }; - return { - brand: plus.device.vendor, - model: plus.device.model, - pixelRatio: plus.screen.scale, - screenWidth, - screenHeight, - windowWidth, - windowHeight, - statusBarHeight, - language: plus.os.language, - system: `${ios ? 'iOS' : isAndroid ? 'Android' : ''} ${plus.os.version}`, - version: plus.runtime.innerVersion, - platform, - SDKVersion: '', - windowTop, - windowBottom, - safeArea, - safeAreaInsets: { - top: safeAreaInsets.top, - right: safeAreaInsets.right, - bottom: safeAreaInsets.bottom, - left: safeAreaInsets.left, - }, - deviceId: deviceId$1(), - }; - }); - const getSystemInfo = defineAsyncApi('getSystemInfo', (_, { resolve }) => { - return resolve(getSystemInfoSync()); - }); - - let listener$1 = null; - const onCompassChange = (defineOnApi(API_ON_COMPASS, () => { - startCompass(); - })); - const offCompassChange = (defineOffApi(API_OFF_COMPASS, () => { - stopCompass(); - })); - const startCompass = (defineAsyncApi(API_START_COMPASS, (_, { resolve, reject }) => { - if (!listener$1) { - listener$1 = plus.orientation.watchOrientation((res) => { - UniServiceJSBridge.invokeOnCallback(API_ON_COMPASS, { - direction: res.magneticHeading, - }); - }, (err) => { - reject(err.message); - listener$1 = null; - }, { - frequency: DEVICE_FREQUENCY, - }); - } - setTimeout(resolve, DEVICE_FREQUENCY); - })); - const stopCompass = (defineAsyncApi(API_STOP_COMPASS, (_, { resolve }) => { - if (listener$1) { - plus.orientation.clearWatch(listener$1); - listener$1 = null; - } - resolve(); - })); - - const vibrateShort = defineAsyncApi(API_VIBRATE_SHORT, (_, { resolve }) => { - plus.device.vibrate(15); - resolve(); - }); - const vibrateLong = defineAsyncApi(API_VIBRATE_LONG, (_, { resolve }) => { - plus.device.vibrate(400); - resolve(); - }); - - let listener = null; - const onAccelerometerChange = (defineOnApi(API_ON_ACCELEROMETER, () => { - startAccelerometer(); - })); - const offAccelerometerChange = (defineOffApi(API_OFF_ACCELEROMETER, () => { - stopAccelerometer(); - })); - const startAccelerometer = (defineAsyncApi(API_START_ACCELEROMETER, (_, { resolve, reject }) => { - if (!listener) { - listener = plus.accelerometer.watchAcceleration((res) => { - UniServiceJSBridge.invokeOnCallback(API_ON_ACCELEROMETER, { - x: (res && res.xAxis) || 0, - y: (res && res.yAxis) || 0, - z: (res && res.zAxis) || 0, - }); - }, (err) => { - listener = null; - reject(`startAccelerometer:fail ${err.message}`); - }, { - frequency: DEVICE_FREQUENCY, - }); - } - setTimeout(resolve, DEVICE_FREQUENCY); - })); - const stopAccelerometer = (defineAsyncApi(API_STOP_ACCELEROMETER, (_, { resolve }) => { - if (listener) { - plus.accelerometer.clearWatch(listener); - listener = null; - } - resolve(); - })); - - const onBluetoothDeviceFound = defineOnApi(API_ON_BLUETOOTH_DEVICE_FOUND, warpPlusEvent(() => plus.bluetooth.onBluetoothDeviceFound.bind(plus.bluetooth), API_ON_BLUETOOTH_DEVICE_FOUND)); - const onBluetoothAdapterStateChange = defineOnApi(API_ON_BLUETOOTH_ADAPTER_STATE_CHANGE, warpPlusEvent(() => plus.bluetooth.onBluetoothAdapterStateChange.bind(plus.bluetooth), API_ON_BLUETOOTH_ADAPTER_STATE_CHANGE)); - const onBLEConnectionStateChange = defineOnApi(API_ON_BLE_CONNECTION_STATE_CHANGE, warpPlusEvent(() => plus.bluetooth.onBLEConnectionStateChange.bind(plus.bluetooth), API_ON_BLE_CONNECTION_STATE_CHANGE)); - const onBLECharacteristicValueChange = defineOnApi(API_ON_BLE_CHARACTERISTIC_VALUE_CHANGE, warpPlusEvent(() => plus.bluetooth.onBLECharacteristicValueChange.bind(plus.bluetooth), API_ON_BLE_CHARACTERISTIC_VALUE_CHANGE)); - const openBluetoothAdapter = defineAsyncApi('openBluetoothAdapter', warpPlusMethod(() => plus.bluetooth.openBluetoothAdapter.bind(plus.bluetooth))); - const closeBluetoothAdapter = defineAsyncApi('closeBluetoothAdapter', warpPlusMethod(() => plus.bluetooth.closeBluetoothAdapter.bind(plus.bluetooth))); - const getBluetoothAdapterState = defineAsyncApi('getBluetoothAdapterState', warpPlusMethod(() => plus.bluetooth.getBluetoothAdapterState)); - const startBluetoothDevicesDiscovery = defineAsyncApi(API_START_BLUETOOTH_DEVICES_DISCOVERY, warpPlusMethod(() => plus.bluetooth.startBluetoothDevicesDiscovery.bind(plus.bluetooth)), StartBluetoothDevicesDiscoveryProtocol); - const stopBluetoothDevicesDiscovery = defineAsyncApi('stopBluetoothDevicesDiscovery', warpPlusMethod(() => plus.bluetooth.stopBluetoothDevicesDiscovery.bind(plus.bluetooth))); - const getBluetoothDevices = defineAsyncApi('getBluetoothDevices', warpPlusMethod(() => plus.bluetooth.getBluetoothDevices.bind(plus.bluetooth))); - const getConnectedBluetoothDevices = defineAsyncApi(API_GET_CONNECTED_BLUETOOTH_DEVICES, warpPlusMethod(() => plus.bluetooth.getConnectedBluetoothDevices), GetConnectedBluetoothDevicesProtocol); - const createBLEConnection = defineAsyncApi(API_CREATE_BLE_CONNECTION, warpPlusMethod(() => plus.bluetooth.createBLEConnection.bind(plus.bluetooth)), CreateBLEConnectionProtocol); - const closeBLEConnection = defineAsyncApi(API_CLOSE_BLE_CONNECTION, warpPlusMethod(() => plus.bluetooth.closeBLEConnection.bind(plus.bluetooth)), CloseBLEConnectionProtocol); - const getBLEDeviceServices = defineAsyncApi(API_GET_BLE_DEVICE_SERVICES, warpPlusMethod(() => plus.bluetooth.getBLEDeviceServices.bind(plus.bluetooth)), GetBLEDeviceServicesProtocol); - const getBLEDeviceCharacteristics = defineAsyncApi(API_GET_BLE_DEVICE_CHARACTERISTICS, warpPlusMethod(() => plus.bluetooth.getBLEDeviceCharacteristics.bind(plus.bluetooth)), GetBLEDeviceCharacteristicsProtocol); - const notifyBLECharacteristicValueChange = defineAsyncApi(API_NOTIFY_BLE_CHARACTERISTIC_VALUE_CHANGE, warpPlusMethod(() => plus.bluetooth.notifyBLECharacteristicValueChange.bind(plus.bluetooth)), NotifyBLECharacteristicValueChangeProtocol); - const readBLECharacteristicValue = defineAsyncApi(API_READ_BLE_CHARACTERISTIC_VALUE, warpPlusMethod(() => plus.bluetooth.readBLECharacteristicValue.bind(plus.bluetooth)), ReadBLECharacteristicValueProtocol); - const writeBLECharacteristicValue = defineAsyncApi(API_WRITE_BLE_CHARACTERISTIC_VALUE, warpPlusMethod(() => plus.bluetooth.writeBLECharacteristicValue.bind(plus.bluetooth)), WriteBLECharacteristicValueProtocol); - const setBLEMTU = defineAsyncApi(API_SET_BLE_MTU, warpPlusMethod(() => plus.bluetooth.setBLEMTU.bind(plus.bluetooth)), SetBLEMTUProtocol); - const getBLEDeviceRSSI = defineAsyncApi(API_GET_BLE_DEVICE_RSSI, warpPlusMethod(() => plus.bluetooth.getBLEDeviceRSSI.bind(plus.bluetooth)), GetBLEDeviceRSSIProtocol); - - const onBeaconUpdate = defineOnApi(API_ON_BEACON_UPDATE, warpPlusEvent(() => plus.ibeacon.onBeaconUpdate.bind(plus.ibeacon), API_ON_BEACON_UPDATE)); - const onBeaconServiceChange = defineOnApi(API_ON_BEACON_SERVICE_CHANGE, warpPlusEvent(() => plus.ibeacon.onBeaconServiceChange.bind(plus.ibeacon), API_ON_BEACON_SERVICE_CHANGE)); - const getBeacons = defineAsyncApi(API_GET_BEACONS, warpPlusMethod(() => plus.ibeacon.getBeacons.bind(plus.ibeacon))); - const startBeaconDiscovery = defineAsyncApi(API_START_BEACON_DISCOVERY, warpPlusMethod(() => plus.ibeacon.startBeaconDiscovery.bind(plus.ibeacon)), StartBeaconDiscoveryProtocol); - const stopBeaconDiscovery = defineAsyncApi(API_STOP_BEACON_DISCOVERY, warpPlusMethod(() => plus.ibeacon.stopBeaconDiscovery.bind(plus.ibeacon))); - - const makePhoneCall = defineAsyncApi(API_MAKE_PHONE_CALL, ({ phoneNumber }, { resolve }) => { - plus.device.dial(phoneNumber); - return resolve(); - }, MakePhoneCallProtocol); - - const schema = { - name: { - givenName: 'firstName', - middleName: 'middleName', - familyName: 'lastName', - }, - nickname: 'nickName', - photos: { - type: 'url', - value: 'photoFilePath', - }, - note: 'remark', - phoneNumbers: [ - { - type: 'mobile', - value: 'mobilePhoneNumber', - }, - { - type: 'work', - value: 'workPhoneNumber', - }, - { - type: 'company', - value: 'hostNumber', - }, - { - type: 'home fax', - value: 'homeFaxNumber', - }, - { - type: 'work fax', - value: 'workFaxNumber', - }, - ], - emails: [ - { - type: 'home', - value: 'email', - }, - ], - urls: [ - { - type: 'other', - value: 'url', - }, - ], - organizations: [ - { - type: 'company', - name: 'organization', - title: 'title', - }, - ], - ims: [ - { - type: 'other', - value: 'weChatNumber', - }, - ], - addresses: [ - { - type: 'other', - preferred: true, - country: 'addressCountry', - region: 'addressState', - locality: 'addressCity', - streetAddress: 'addressStreet', - postalCode: 'addressPostalCode', - }, - { - type: 'home', - country: 'homeAddressCountry', - region: 'homeAddressState', - locality: 'homeAddressCity', - streetAddress: 'homeAddressStreet', - postalCode: 'homeAddressPostalCode', - }, - { - type: 'company', - country: 'workAddressCountry', - region: 'workAddressState', - locality: 'workAddressCity', - streetAddress: 'workAddressStreet', - postalCode: 'workAddressPostalCode', - }, - ], - }; - const keepFields = ['type', 'preferred']; - function buildContact(contact, data, schema) { - let hasValue = 0; - Object.keys(schema).forEach((contactKey) => { - const dataKey = schema[contactKey]; - const typed = typeof dataKey; - if (typed !== 'object') { - if (keepFields.indexOf(contactKey) !== -1) { - contact[contactKey] = schema[contactKey]; - } - else { - if (typeof data[dataKey] !== 'undefined') { - hasValue++; - contact[contactKey] = data[dataKey]; - } - else { - delete contact[contactKey]; - } - } - } - else { - if (dataKey instanceof Array) { - contact[contactKey] = []; - dataKey.forEach((item) => { - const obj = {}; - if (buildContact(obj, data, item)) { - contact[contactKey].push(obj); - } - }); - if (!contact[contactKey].length) { - delete contact[contactKey]; - } - else { - hasValue++; - } - } - else { - contact[contactKey] = {}; - if (buildContact(contact[contactKey], data, dataKey)) { - hasValue++; - } - else { - delete contact[contactKey]; - } - } - } - }); - return hasValue; - } - const addPhoneContact = defineAsyncApi(API_ADD_PHONE_CONTACT, (data, { resolve, reject }) => { - !data.photoFilePath && (data.photoFilePath = ''); - plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, (addressbook) => { - const contact = addressbook.create(); - buildContact(contact, data, schema); - contact.save(() => resolve(), (e) => reject()); - }, (e) => reject()); - }, AddPhoneContactProtocol, AddPhoneContactOptions); - - function requireNativePlugin(pluginName) { - if (typeof weex !== 'undefined') { - return weex.requireModule(pluginName); - } - return __requireNativePlugin__(pluginName); - } - function sendNativeEvent(event, data, callback) { - // 实时获取weex module(weex可能会变化,比如首页nvue加速显示时) - return requireNativePlugin('plus').sendNativeEvent(event, data, callback); - } +function getScreenInfo() { + const { resolutionWidth, resolutionHeight } = plus.screen.getCurrentSize(); + return { + screenWidth: Math.round(resolutionWidth), + screenHeight: Math.round(resolutionHeight), + }; +} +const getSystemInfoSync = defineSyncApi('getSystemInfoSync', () => { + const platform = plus.os.name.toLowerCase(); + const ios = platform === 'ios'; + const isAndroid = platform === 'android'; + const { screenWidth, screenHeight } = getScreenInfo(); + const statusBarHeight = getStatusbarHeight(); + let safeAreaInsets; + const titleNView = { + height: 0, + cover: false, + }; + const webview = getCurrentWebview(); + if (webview) { + const webStyle = webview.getStyle(); + const style = webStyle && webStyle.titleNView; + if (style && style.type && style.type !== 'none') { + titleNView.height = + style.type === 'transparent' ? 0 : statusBarHeight + NAVBAR_HEIGHT; + titleNView.cover = + style.type === 'transparent' || style.type === 'float'; + } + safeAreaInsets = webview.getSafeAreaInsets(); + } + else { + safeAreaInsets = plus.navigator.getSafeAreaInsets(); + } + const tabBarView = { + height: 0, + cover: false, + }; + if (isTabBarPage$1()) { + tabBarView.height = tabBar$1.visible ? tabBar$1.height : 0; + tabBarView.cover = tabBar$1.cover; + } + const windowTop = titleNView.cover ? titleNView.height : 0; + const windowBottom = tabBarView.cover ? tabBarView.height : 0; + let windowHeight = screenHeight - titleNView.height - tabBarView.height; + let windowHeightReal = screenHeight - + (titleNView.cover ? 0 : titleNView.height) - + (tabBarView.cover ? 0 : tabBarView.height); + const windowWidth = screenWidth; + if ((!tabBarView.height || tabBarView.cover) && + !safeAreaInsets.bottom && + safeAreaInsets.deviceBottom) { + windowHeight -= safeAreaInsets.deviceBottom; + windowHeightReal -= safeAreaInsets.deviceBottom; + } + safeAreaInsets = ios + ? safeAreaInsets + : { + left: 0, + right: 0, + top: titleNView.height && !titleNView.cover ? 0 : statusBarHeight, + bottom: 0, + }; + const safeArea = { + left: safeAreaInsets.left, + right: windowWidth - safeAreaInsets.right, + top: safeAreaInsets.top, + bottom: windowHeightReal - safeAreaInsets.bottom, + width: windowWidth - safeAreaInsets.left - safeAreaInsets.right, + height: windowHeightReal - safeAreaInsets.top - safeAreaInsets.bottom, + }; + return { + brand: plus.device.vendor, + model: plus.device.model, + pixelRatio: plus.screen.scale, + screenWidth, + screenHeight, + windowWidth, + windowHeight, + statusBarHeight, + language: plus.os.language, + system: `${ios ? 'iOS' : isAndroid ? 'Android' : ''} ${plus.os.version}`, + version: plus.runtime.innerVersion, + platform, + SDKVersion: '', + windowTop, + windowBottom, + safeArea, + safeAreaInsets: { + top: safeAreaInsets.top, + right: safeAreaInsets.right, + bottom: safeAreaInsets.bottom, + left: safeAreaInsets.left, + }, + deviceId: deviceId$1(), + }; +}); +const getSystemInfo = defineAsyncApi('getSystemInfo', (_, { resolve }) => { + return resolve(getSystemInfoSync()); +}); + +let listener$1 = null; +const onCompassChange = (defineOnApi(API_ON_COMPASS, () => { + startCompass(); +})); +const offCompassChange = (defineOffApi(API_OFF_COMPASS, () => { + stopCompass(); +})); +const startCompass = (defineAsyncApi(API_START_COMPASS, (_, { resolve, reject }) => { + if (!listener$1) { + listener$1 = plus.orientation.watchOrientation((res) => { + UniServiceJSBridge.invokeOnCallback(API_ON_COMPASS, { + direction: res.magneticHeading, + }); + }, (err) => { + reject(err.message); + listener$1 = null; + }, { + frequency: DEVICE_FREQUENCY, + }); + } + setTimeout(resolve, DEVICE_FREQUENCY); +})); +const stopCompass = (defineAsyncApi(API_STOP_COMPASS, (_, { resolve }) => { + if (listener$1) { + plus.orientation.clearWatch(listener$1); + listener$1 = null; + } + resolve(); +})); + +const vibrateShort = defineAsyncApi(API_VIBRATE_SHORT, (_, { resolve }) => { + plus.device.vibrate(15); + resolve(); +}); +const vibrateLong = defineAsyncApi(API_VIBRATE_LONG, (_, { resolve }) => { + plus.device.vibrate(400); + resolve(); +}); + +let listener = null; +const onAccelerometerChange = (defineOnApi(API_ON_ACCELEROMETER, () => { + startAccelerometer(); +})); +const offAccelerometerChange = (defineOffApi(API_OFF_ACCELEROMETER, () => { + stopAccelerometer(); +})); +const startAccelerometer = (defineAsyncApi(API_START_ACCELEROMETER, (_, { resolve, reject }) => { + if (!listener) { + listener = plus.accelerometer.watchAcceleration((res) => { + UniServiceJSBridge.invokeOnCallback(API_ON_ACCELEROMETER, { + x: (res && res.xAxis) || 0, + y: (res && res.yAxis) || 0, + z: (res && res.zAxis) || 0, + }); + }, (err) => { + listener = null; + reject(`startAccelerometer:fail ${err.message}`); + }, { + frequency: DEVICE_FREQUENCY, + }); + } + setTimeout(resolve, DEVICE_FREQUENCY); +})); +const stopAccelerometer = (defineAsyncApi(API_STOP_ACCELEROMETER, (_, { resolve }) => { + if (listener) { + plus.accelerometer.clearWatch(listener); + listener = null; + } + resolve(); +})); + +const onBluetoothDeviceFound = defineOnApi(API_ON_BLUETOOTH_DEVICE_FOUND, warpPlusEvent(() => plus.bluetooth.onBluetoothDeviceFound.bind(plus.bluetooth), API_ON_BLUETOOTH_DEVICE_FOUND)); +const onBluetoothAdapterStateChange = defineOnApi(API_ON_BLUETOOTH_ADAPTER_STATE_CHANGE, warpPlusEvent(() => plus.bluetooth.onBluetoothAdapterStateChange.bind(plus.bluetooth), API_ON_BLUETOOTH_ADAPTER_STATE_CHANGE)); +const onBLEConnectionStateChange = defineOnApi(API_ON_BLE_CONNECTION_STATE_CHANGE, warpPlusEvent(() => plus.bluetooth.onBLEConnectionStateChange.bind(plus.bluetooth), API_ON_BLE_CONNECTION_STATE_CHANGE)); +const onBLECharacteristicValueChange = defineOnApi(API_ON_BLE_CHARACTERISTIC_VALUE_CHANGE, warpPlusEvent(() => plus.bluetooth.onBLECharacteristicValueChange.bind(plus.bluetooth), API_ON_BLE_CHARACTERISTIC_VALUE_CHANGE)); +const openBluetoothAdapter = defineAsyncApi('openBluetoothAdapter', warpPlusMethod(() => plus.bluetooth.openBluetoothAdapter.bind(plus.bluetooth))); +const closeBluetoothAdapter = defineAsyncApi('closeBluetoothAdapter', warpPlusMethod(() => plus.bluetooth.closeBluetoothAdapter.bind(plus.bluetooth))); +const getBluetoothAdapterState = defineAsyncApi('getBluetoothAdapterState', warpPlusMethod(() => plus.bluetooth.getBluetoothAdapterState)); +const startBluetoothDevicesDiscovery = defineAsyncApi(API_START_BLUETOOTH_DEVICES_DISCOVERY, warpPlusMethod(() => plus.bluetooth.startBluetoothDevicesDiscovery.bind(plus.bluetooth)), StartBluetoothDevicesDiscoveryProtocol); +const stopBluetoothDevicesDiscovery = defineAsyncApi('stopBluetoothDevicesDiscovery', warpPlusMethod(() => plus.bluetooth.stopBluetoothDevicesDiscovery.bind(plus.bluetooth))); +const getBluetoothDevices = defineAsyncApi('getBluetoothDevices', warpPlusMethod(() => plus.bluetooth.getBluetoothDevices.bind(plus.bluetooth))); +const getConnectedBluetoothDevices = defineAsyncApi(API_GET_CONNECTED_BLUETOOTH_DEVICES, warpPlusMethod(() => plus.bluetooth.getConnectedBluetoothDevices), GetConnectedBluetoothDevicesProtocol); +const createBLEConnection = defineAsyncApi(API_CREATE_BLE_CONNECTION, warpPlusMethod(() => plus.bluetooth.createBLEConnection.bind(plus.bluetooth)), CreateBLEConnectionProtocol); +const closeBLEConnection = defineAsyncApi(API_CLOSE_BLE_CONNECTION, warpPlusMethod(() => plus.bluetooth.closeBLEConnection.bind(plus.bluetooth)), CloseBLEConnectionProtocol); +const getBLEDeviceServices = defineAsyncApi(API_GET_BLE_DEVICE_SERVICES, warpPlusMethod(() => plus.bluetooth.getBLEDeviceServices.bind(plus.bluetooth)), GetBLEDeviceServicesProtocol); +const getBLEDeviceCharacteristics = defineAsyncApi(API_GET_BLE_DEVICE_CHARACTERISTICS, warpPlusMethod(() => plus.bluetooth.getBLEDeviceCharacteristics.bind(plus.bluetooth)), GetBLEDeviceCharacteristicsProtocol); +const notifyBLECharacteristicValueChange = defineAsyncApi(API_NOTIFY_BLE_CHARACTERISTIC_VALUE_CHANGE, warpPlusMethod(() => plus.bluetooth.notifyBLECharacteristicValueChange.bind(plus.bluetooth)), NotifyBLECharacteristicValueChangeProtocol); +const readBLECharacteristicValue = defineAsyncApi(API_READ_BLE_CHARACTERISTIC_VALUE, warpPlusMethod(() => plus.bluetooth.readBLECharacteristicValue.bind(plus.bluetooth)), ReadBLECharacteristicValueProtocol); +const writeBLECharacteristicValue = defineAsyncApi(API_WRITE_BLE_CHARACTERISTIC_VALUE, warpPlusMethod(() => plus.bluetooth.writeBLECharacteristicValue.bind(plus.bluetooth)), WriteBLECharacteristicValueProtocol); +const setBLEMTU = defineAsyncApi(API_SET_BLE_MTU, warpPlusMethod(() => plus.bluetooth.setBLEMTU.bind(plus.bluetooth)), SetBLEMTUProtocol); +const getBLEDeviceRSSI = defineAsyncApi(API_GET_BLE_DEVICE_RSSI, warpPlusMethod(() => plus.bluetooth.getBLEDeviceRSSI.bind(plus.bluetooth)), GetBLEDeviceRSSIProtocol); + +const onBeaconUpdate = defineOnApi(API_ON_BEACON_UPDATE, warpPlusEvent(() => plus.ibeacon.onBeaconUpdate.bind(plus.ibeacon), API_ON_BEACON_UPDATE)); +const onBeaconServiceChange = defineOnApi(API_ON_BEACON_SERVICE_CHANGE, warpPlusEvent(() => plus.ibeacon.onBeaconServiceChange.bind(plus.ibeacon), API_ON_BEACON_SERVICE_CHANGE)); +const getBeacons = defineAsyncApi(API_GET_BEACONS, warpPlusMethod(() => plus.ibeacon.getBeacons.bind(plus.ibeacon))); +const startBeaconDiscovery = defineAsyncApi(API_START_BEACON_DISCOVERY, warpPlusMethod(() => plus.ibeacon.startBeaconDiscovery.bind(plus.ibeacon)), StartBeaconDiscoveryProtocol); +const stopBeaconDiscovery = defineAsyncApi(API_STOP_BEACON_DISCOVERY, warpPlusMethod(() => plus.ibeacon.stopBeaconDiscovery.bind(plus.ibeacon))); + +const makePhoneCall = defineAsyncApi(API_MAKE_PHONE_CALL, ({ phoneNumber }, { resolve }) => { + plus.device.dial(phoneNumber); + return resolve(); +}, MakePhoneCallProtocol); + +const schema = { + name: { + givenName: 'firstName', + middleName: 'middleName', + familyName: 'lastName', + }, + nickname: 'nickName', + photos: { + type: 'url', + value: 'photoFilePath', + }, + note: 'remark', + phoneNumbers: [ + { + type: 'mobile', + value: 'mobilePhoneNumber', + }, + { + type: 'work', + value: 'workPhoneNumber', + }, + { + type: 'company', + value: 'hostNumber', + }, + { + type: 'home fax', + value: 'homeFaxNumber', + }, + { + type: 'work fax', + value: 'workFaxNumber', + }, + ], + emails: [ + { + type: 'home', + value: 'email', + }, + ], + urls: [ + { + type: 'other', + value: 'url', + }, + ], + organizations: [ + { + type: 'company', + name: 'organization', + title: 'title', + }, + ], + ims: [ + { + type: 'other', + value: 'weChatNumber', + }, + ], + addresses: [ + { + type: 'other', + preferred: true, + country: 'addressCountry', + region: 'addressState', + locality: 'addressCity', + streetAddress: 'addressStreet', + postalCode: 'addressPostalCode', + }, + { + type: 'home', + country: 'homeAddressCountry', + region: 'homeAddressState', + locality: 'homeAddressCity', + streetAddress: 'homeAddressStreet', + postalCode: 'homeAddressPostalCode', + }, + { + type: 'company', + country: 'workAddressCountry', + region: 'workAddressState', + locality: 'workAddressCity', + streetAddress: 'workAddressStreet', + postalCode: 'workAddressPostalCode', + }, + ], +}; +const keepFields = ['type', 'preferred']; +function buildContact(contact, data, schema) { + let hasValue = 0; + Object.keys(schema).forEach((contactKey) => { + const dataKey = schema[contactKey]; + const typed = typeof dataKey; + if (typed !== 'object') { + if (keepFields.indexOf(contactKey) !== -1) { + contact[contactKey] = schema[contactKey]; + } + else { + if (typeof data[dataKey] !== 'undefined') { + hasValue++; + contact[contactKey] = data[dataKey]; + } + else { + delete contact[contactKey]; + } + } + } + else { + if (dataKey instanceof Array) { + contact[contactKey] = []; + dataKey.forEach((item) => { + const obj = {}; + if (buildContact(obj, data, item)) { + contact[contactKey].push(obj); + } + }); + if (!contact[contactKey].length) { + delete contact[contactKey]; + } + else { + hasValue++; + } + } + else { + contact[contactKey] = {}; + if (buildContact(contact[contactKey], data, dataKey)) { + hasValue++; + } + else { + delete contact[contactKey]; + } + } + } + }); + return hasValue; +} +const addPhoneContact = defineAsyncApi(API_ADD_PHONE_CONTACT, (data, { resolve, reject }) => { + !data.photoFilePath && (data.photoFilePath = ''); + plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, (addressbook) => { + const contact = addressbook.create(); + buildContact(contact, data, schema); + contact.save(() => resolve(), (e) => reject()); + }, (e) => reject()); +}, AddPhoneContactProtocol, AddPhoneContactOptions); + +function requireNativePlugin(pluginName) { + if (typeof weex !== 'undefined') { + return weex.requireModule(pluginName); + } + return __requireNativePlugin__(pluginName); +} +function sendNativeEvent(event, data, callback) { + // 实时获取weex module(weex可能会变化,比如首页nvue加速显示时) + return requireNativePlugin('plus').sendNativeEvent(event, data, callback); +} - const getClipboardData = defineAsyncApi(API_GET_CLIPBOARD_DATA, (_, { resolve, reject }) => { - const clipboard = requireNativePlugin('clipboard'); - clipboard.getString((ret) => { - if (ret.result === 'success') { - resolve({ - data: ret.data, - }); - } - else { - reject('getClipboardData:fail'); - } - }); - }); - const setClipboardData = defineAsyncApi(API_SET_CLIPBOARD_DATA, (options, { resolve }) => { - const clipboard = requireNativePlugin('clipboard'); - clipboard.setString(options.data); - resolve(); - }, SetClipboardDataProtocol, SetClipboardDataOptions); - - const API_ON_NETWORK_STATUS_CHANGE = 'onNetworkStatusChange'; - function networkListener() { - getNetworkType().then(({ networkType }) => { - UniServiceJSBridge.invokeOnCallback(API_ON_NETWORK_STATUS_CHANGE, { - isConnected: networkType !== 'none', - networkType, - }); - }); - } - // 注意:框架对on类的API已做了统一的前置处理(仅首次调用on方法时,会调用具体的平台on实现,后续调用,框架不会再调用,实现时,直接监听平台事件即可) - const onNetworkStatusChange = defineOnApi(API_ON_NETWORK_STATUS_CHANGE, () => { - plus.globalEvent.addEventListener('netchange', networkListener); - }); - // 注意:框架对off类的API已做了统一的前置处理(仅当框架内不存在对应的on监听时,会调用具体的平台off实现,若还存在事件,框架不会再调用,具体实现时,直接移除平台事件即可) - const offNetworkStatusChange = defineOffApi('offNetworkStatusChange', () => { - plus.globalEvent.removeEventListener('netchange', networkListener); - }); - const getNetworkType = defineAsyncApi('getNetworkType', (_args, { resolve }) => { - let networkType = NETWORK_TYPES[plus.networkinfo.getCurrentType()] || 'unknown'; - return resolve({ networkType }); - }); - - function checkIsSupportFaceID() { - const platform = plus.os.name.toLowerCase(); - if (platform !== 'ios') { - return false; - } - const faceID = requireNativePlugin('faceID'); - return !!(faceID && faceID.isSupport()); - } - function checkIsSupportFingerPrint() { - return !!(plus.fingerprint && plus.fingerprint.isSupport()); - } - const baseCheckIsSupportSoterAuthentication = (resolve) => { - const supportMode = []; - if (checkIsSupportFingerPrint()) { - supportMode.push('fingerPrint'); - } - if (checkIsSupportFaceID()) { - supportMode.push('facial'); - } - resolve && - resolve({ - supportMode, - }); - return { - supportMode, - errMsg: 'checkIsSupportSoterAuthentication:ok', - }; - }; - const checkIsSupportSoterAuthentication = defineAsyncApi(API_CHECK_IS_SUPPORT_SOTER_AUTHENTICATION, (_, { resolve, reject }) => { - baseCheckIsSupportSoterAuthentication(resolve); - }); - const basecheckIsSoterEnrolledInDevice = ({ checkAuthMode, resolve, reject, }) => { - const wrapReject = (errMsg, errRes) => reject && reject(errMsg, errRes); - const wrapResolve = (res) => resolve && resolve(res); - if (checkAuthMode === 'fingerPrint') { - if (checkIsSupportFingerPrint()) { - const isEnrolled = plus.fingerprint.isKeyguardSecure() && - plus.fingerprint.isEnrolledFingerprints(); - wrapResolve({ isEnrolled }); - return { - isEnrolled, - errMsg: 'checkIsSoterEnrolledInDevice:ok', - }; - } - wrapReject('not support', { isEnrolled: false }); - return { - isEnrolled: false, - errMsg: 'checkIsSoterEnrolledInDevice:fail not support', - }; - } - else if (checkAuthMode === 'facial') { - if (checkIsSupportFaceID()) { - const faceID = requireNativePlugin('faceID'); - const isEnrolled = faceID && faceID.isKeyguardSecure() && faceID.isEnrolledFaceID(); - wrapResolve({ isEnrolled }); - return { - isEnrolled, - errMsg: 'checkIsSoterEnrolledInDevice:ok', - }; - } - wrapReject('not support', { isEnrolled: false }); - return { - isEnrolled: false, - errMsg: 'checkIsSoterEnrolledInDevice:fail not support', - }; - } - wrapReject('not support', { isEnrolled: false }); - return { - isEnrolled: false, - errMsg: 'checkIsSoterEnrolledInDevice:fail not support', - }; - }; - const checkIsSoterEnrolledInDevice = defineAsyncApi(API_CHECK_IS_SOTER_ENROLLED_IN_DEVICE, ({ checkAuthMode }, { resolve, reject }) => { - basecheckIsSoterEnrolledInDevice({ checkAuthMode, resolve, reject }); - }, CheckIsSoterEnrolledInDeviceProtocols, CheckIsSoterEnrolledInDeviceOptions); - const startSoterAuthentication = defineAsyncApi(API_START_SOTER_AUTHENTICATION, ({ requestAuthModes, challenge = false, authContent }, { resolve, reject }) => { - /* - 以手机不支持facial未录入fingerPrint为例 - requestAuthModes:['facial','fingerPrint']时,微信小程序返回值里的authMode为"fingerPrint" - requestAuthModes:['fingerPrint','facial']时,微信小程序返回值里的authMode为"fingerPrint" - 即先过滤不支持的方式之后再判断是否录入 - 微信小程序errCode(从企业号开发者中心查到如下文档): - 0:识别成功 'startSoterAuthentication:ok' - 90001:本设备不支持SOTER 'startSoterAuthentication:fail not support soter' - 90002:用户未授权微信使用该生物认证接口 注:APP端暂不支持 - 90003:请求使用的生物认证方式不支持 'startSoterAuthentication:fail no corresponding mode' - 90004:未传入challenge或challenge长度过长(最长512字符)注:APP端暂不支持 - 90005:auth_content长度超过限制(最长42个字符)注:微信小程序auth_content指纹识别时无效果,faceID暂未测试 - 90007:内部错误 'startSoterAuthentication:fail auth key update error' - 90008:用户取消授权 'startSoterAuthentication:fail cancel' - 90009:识别失败 'startSoterAuthentication:fail' - 90010:重试次数过多被冻结 'startSoterAuthentication:fail authenticate freeze. please try again later' - 90011:用户未录入所选识别方式 'startSoterAuthentication:fail no fingerprint enrolled' - */ - initI18nStartSoterAuthenticationMsgsOnce(); - const { t } = useI18n(); - const supportMode = baseCheckIsSupportSoterAuthentication().supportMode; - if (supportMode.length === 0) { - return { - authMode: 'fingerPrint', - errCode: 90001, - errMsg: 'startSoterAuthentication:fail', - }; - } - const supportRequestAuthMode = []; - requestAuthModes.map((item, index) => { - if (supportMode.indexOf(item) > -1) { - supportRequestAuthMode.push(item); - } - }); - if (supportRequestAuthMode.length === 0) { - return { - authMode: 'fingerPrint', - errCode: 90003, - errMsg: 'startSoterAuthentication:fail no corresponding mode', - }; - } - const enrolledRequestAuthMode = []; - supportRequestAuthMode.map((item, index) => { - const checked = basecheckIsSoterEnrolledInDevice({ - checkAuthMode: item, - }).isEnrolled; - if (checked) { - enrolledRequestAuthMode.push(item); - } - }); - if (enrolledRequestAuthMode.length === 0) { - return { - authMode: supportRequestAuthMode[0], - errCode: 90011, - errMsg: `startSoterAuthentication:fail no ${supportRequestAuthMode[0]} enrolled`, - }; - } - const realAuthMode = enrolledRequestAuthMode[0]; - if (realAuthMode === 'fingerPrint') { - if (plus.os.name.toLowerCase() === 'android') { - plus.nativeUI.showWaiting(authContent || t('uni.startSoterAuthentication.authContent')).onclose = function () { - plus.fingerprint.cancel(); - }; - } - plus.fingerprint.authenticate(() => { - plus.nativeUI.closeWaiting(); - resolve({ - authMode: realAuthMode, - errCode: 0, - }); - }, (e) => { - const res = { - authMode: realAuthMode, - }; - switch (e.code) { - case e.AUTHENTICATE_MISMATCH: - // 微信小程序没有这个回调,如果要实现此处回调需要多次触发需要用事件publish实现 - // invoke(callbackId, { - // authMode: realAuthMode, - // errCode: 90009, - // errMsg: 'startSoterAuthentication:fail' - // }) - break; - case e.AUTHENTICATE_OVERLIMIT: - // 微信小程序在第一次重试次数超限时安卓IOS返回不一致,安卓端会返回次数超过限制(errCode: 90010),IOS端会返回认证失败(errCode: 90009)。APP-IOS实际运行时不会次数超限,超过指定次数之后会弹出输入密码的界面 - plus.nativeUI.closeWaiting(); - reject('authenticate freeze. please try again later', shared.extend(res, { - errCode: 90010, - })); - break; - case e.CANCEL: - plus.nativeUI.closeWaiting(); - reject('cancel', shared.extend(res, { - errCode: 90008, - })); - break; - default: - plus.nativeUI.closeWaiting(); - reject('', shared.extend(res, { - errCode: 90007, - })); - break; - } - }, { - message: authContent, - }); - } - else if (realAuthMode === 'facial') { - const faceID = requireNativePlugin('faceID'); - faceID.authenticate({ - message: authContent, - }, (e) => { - const res = { - authMode: realAuthMode, - }; - if (e.type === 'success' && e.code === 0) { - resolve({ - authMode: realAuthMode, - errCode: 0, - }); - } - else { - switch (e.code) { - case 4: - reject('', shared.extend(res, { - errCode: 90009, - })); - break; - case 5: - reject('authenticate freeze. please try again later', shared.extend(res, { - errCode: 90010, - })); - break; - case 6: - reject('', shared.extend(res, { - errCode: 90008, - })); - break; - default: - reject('', shared.extend(res, { - errCode: 90007, - })); - break; - } - } - }); - } - }, StartSoterAuthenticationProtocols, StartSoterAuthenticationOptions); - - let plus_; - let weex_; - let BroadcastChannel_; - function getRuntime() { - return typeof window === 'object' && - typeof navigator === 'object' && - typeof document === 'object' - ? 'webview' - : 'v8'; - } - function getPageId() { - return plus_.webview.currentWebview().id; - } - let channel; - let globalEvent$1; - const callbacks$2 = {}; - function onPlusMessage$1(res) { - const message = res.data && res.data.__message; - if (!message || !message.__page) { - return; - } - const pageId = message.__page; - const callback = callbacks$2[pageId]; - callback && callback(message); - if (!message.keep) { - delete callbacks$2[pageId]; - } - } - function addEventListener(pageId, callback) { - if (getRuntime() === 'v8') { - if (BroadcastChannel_) { - channel && channel.close(); - channel = new BroadcastChannel_(getPageId()); - channel.onmessage = onPlusMessage$1; - } - else if (!globalEvent$1) { - globalEvent$1 = weex_.requireModule('globalEvent'); - globalEvent$1.addEventListener('plusMessage', onPlusMessage$1); - } - } - else { - // @ts-ignore - window.__plusMessage = onPlusMessage$1; - } - callbacks$2[pageId] = callback; - } - class Page { - constructor(webview) { - this.webview = webview; - } - sendMessage(data) { - const message = JSON.parse(JSON.stringify({ - __message: { - data, - }, - })); - const id = this.webview.id; - if (BroadcastChannel_) { - const channel = new BroadcastChannel_(id); - channel.postMessage(message); - } - else { - plus_.webview.postMessageToUniNView && - plus_.webview.postMessageToUniNView(message, id); - } - } - close() { - this.webview.close(); - } - } - function showPage({ context = {}, url, data = {}, style = {}, onMessage, onClose, }) { - // eslint-disable-next-line - plus_ = context.plus || plus; - // eslint-disable-next-line - weex_ = context.weex || (typeof weex === 'object' ? weex : null); - // eslint-disable-next-line - BroadcastChannel_ = - context.BroadcastChannel || - (typeof BroadcastChannel === 'object' ? BroadcastChannel : null); - const titleNView = { - autoBackButton: true, - titleSize: '17px', - }; - const pageId = `page${Date.now()}`; - style = shared.extend({}, style); - if (style.titleNView !== false && style.titleNView !== 'none') { - style.titleNView = shared.extend(titleNView, style.titleNView); - } - const defaultStyle = { - top: 0, - bottom: 0, - usingComponents: {}, - popGesture: 'close', - scrollIndicator: 'none', - animationType: 'pop-in', - animationDuration: 200, - uniNView: { - path: `${(typeof process === 'object' && +const getClipboardData = defineAsyncApi(API_GET_CLIPBOARD_DATA, (_, { resolve, reject }) => { + const clipboard = requireNativePlugin('clipboard'); + clipboard.getString((ret) => { + if (ret.result === 'success') { + resolve({ + data: ret.data, + }); + } + else { + reject('getClipboardData:fail'); + } + }); +}); +const setClipboardData = defineAsyncApi(API_SET_CLIPBOARD_DATA, (options, { resolve }) => { + const clipboard = requireNativePlugin('clipboard'); + clipboard.setString(options.data); + resolve(); +}, SetClipboardDataProtocol, SetClipboardDataOptions); + +const API_ON_NETWORK_STATUS_CHANGE = 'onNetworkStatusChange'; +function networkListener() { + getNetworkType().then(({ networkType }) => { + UniServiceJSBridge.invokeOnCallback(API_ON_NETWORK_STATUS_CHANGE, { + isConnected: networkType !== 'none', + networkType, + }); + }); +} +// 注意:框架对on类的API已做了统一的前置处理(仅首次调用on方法时,会调用具体的平台on实现,后续调用,框架不会再调用,实现时,直接监听平台事件即可) +const onNetworkStatusChange = defineOnApi(API_ON_NETWORK_STATUS_CHANGE, () => { + plus.globalEvent.addEventListener('netchange', networkListener); +}); +// 注意:框架对off类的API已做了统一的前置处理(仅当框架内不存在对应的on监听时,会调用具体的平台off实现,若还存在事件,框架不会再调用,具体实现时,直接移除平台事件即可) +const offNetworkStatusChange = defineOffApi('offNetworkStatusChange', () => { + plus.globalEvent.removeEventListener('netchange', networkListener); +}); +const getNetworkType = defineAsyncApi('getNetworkType', (_args, { resolve }) => { + let networkType = NETWORK_TYPES[plus.networkinfo.getCurrentType()] || 'unknown'; + return resolve({ networkType }); +}); + +function checkIsSupportFaceID() { + const platform = plus.os.name.toLowerCase(); + if (platform !== 'ios') { + return false; + } + const faceID = requireNativePlugin('faceID'); + return !!(faceID && faceID.isSupport()); +} +function checkIsSupportFingerPrint() { + return !!(plus.fingerprint && plus.fingerprint.isSupport()); +} +const baseCheckIsSupportSoterAuthentication = (resolve) => { + const supportMode = []; + if (checkIsSupportFingerPrint()) { + supportMode.push('fingerPrint'); + } + if (checkIsSupportFaceID()) { + supportMode.push('facial'); + } + resolve && + resolve({ + supportMode, + }); + return { + supportMode, + errMsg: 'checkIsSupportSoterAuthentication:ok', + }; +}; +const checkIsSupportSoterAuthentication = defineAsyncApi(API_CHECK_IS_SUPPORT_SOTER_AUTHENTICATION, (_, { resolve, reject }) => { + baseCheckIsSupportSoterAuthentication(resolve); +}); +const basecheckIsSoterEnrolledInDevice = ({ checkAuthMode, resolve, reject, }) => { + const wrapReject = (errMsg, errRes) => reject && reject(errMsg, errRes); + const wrapResolve = (res) => resolve && resolve(res); + if (checkAuthMode === 'fingerPrint') { + if (checkIsSupportFingerPrint()) { + const isEnrolled = plus.fingerprint.isKeyguardSecure() && + plus.fingerprint.isEnrolledFingerprints(); + wrapResolve({ isEnrolled }); + return { + isEnrolled, + errMsg: 'checkIsSoterEnrolledInDevice:ok', + }; + } + wrapReject('not support', { isEnrolled: false }); + return { + isEnrolled: false, + errMsg: 'checkIsSoterEnrolledInDevice:fail not support', + }; + } + else if (checkAuthMode === 'facial') { + if (checkIsSupportFaceID()) { + const faceID = requireNativePlugin('faceID'); + const isEnrolled = faceID && faceID.isKeyguardSecure() && faceID.isEnrolledFaceID(); + wrapResolve({ isEnrolled }); + return { + isEnrolled, + errMsg: 'checkIsSoterEnrolledInDevice:ok', + }; + } + wrapReject('not support', { isEnrolled: false }); + return { + isEnrolled: false, + errMsg: 'checkIsSoterEnrolledInDevice:fail not support', + }; + } + wrapReject('not support', { isEnrolled: false }); + return { + isEnrolled: false, + errMsg: 'checkIsSoterEnrolledInDevice:fail not support', + }; +}; +const checkIsSoterEnrolledInDevice = defineAsyncApi(API_CHECK_IS_SOTER_ENROLLED_IN_DEVICE, ({ checkAuthMode }, { resolve, reject }) => { + basecheckIsSoterEnrolledInDevice({ checkAuthMode, resolve, reject }); +}, CheckIsSoterEnrolledInDeviceProtocols, CheckIsSoterEnrolledInDeviceOptions); +const startSoterAuthentication = defineAsyncApi(API_START_SOTER_AUTHENTICATION, ({ requestAuthModes, challenge = false, authContent }, { resolve, reject }) => { + /* + 以手机不支持facial未录入fingerPrint为例 + requestAuthModes:['facial','fingerPrint']时,微信小程序返回值里的authMode为"fingerPrint" + requestAuthModes:['fingerPrint','facial']时,微信小程序返回值里的authMode为"fingerPrint" + 即先过滤不支持的方式之后再判断是否录入 + 微信小程序errCode(从企业号开发者中心查到如下文档): + 0:识别成功 'startSoterAuthentication:ok' + 90001:本设备不支持SOTER 'startSoterAuthentication:fail not support soter' + 90002:用户未授权微信使用该生物认证接口 注:APP端暂不支持 + 90003:请求使用的生物认证方式不支持 'startSoterAuthentication:fail no corresponding mode' + 90004:未传入challenge或challenge长度过长(最长512字符)注:APP端暂不支持 + 90005:auth_content长度超过限制(最长42个字符)注:微信小程序auth_content指纹识别时无效果,faceID暂未测试 + 90007:内部错误 'startSoterAuthentication:fail auth key update error' + 90008:用户取消授权 'startSoterAuthentication:fail cancel' + 90009:识别失败 'startSoterAuthentication:fail' + 90010:重试次数过多被冻结 'startSoterAuthentication:fail authenticate freeze. please try again later' + 90011:用户未录入所选识别方式 'startSoterAuthentication:fail no fingerprint enrolled' + */ + initI18nStartSoterAuthenticationMsgsOnce(); + const { t } = useI18n(); + const supportMode = baseCheckIsSupportSoterAuthentication().supportMode; + if (supportMode.length === 0) { + return { + authMode: 'fingerPrint', + errCode: 90001, + errMsg: 'startSoterAuthentication:fail', + }; + } + const supportRequestAuthMode = []; + requestAuthModes.map((item, index) => { + if (supportMode.indexOf(item) > -1) { + supportRequestAuthMode.push(item); + } + }); + if (supportRequestAuthMode.length === 0) { + return { + authMode: 'fingerPrint', + errCode: 90003, + errMsg: 'startSoterAuthentication:fail no corresponding mode', + }; + } + const enrolledRequestAuthMode = []; + supportRequestAuthMode.map((item, index) => { + const checked = basecheckIsSoterEnrolledInDevice({ + checkAuthMode: item, + }).isEnrolled; + if (checked) { + enrolledRequestAuthMode.push(item); + } + }); + if (enrolledRequestAuthMode.length === 0) { + return { + authMode: supportRequestAuthMode[0], + errCode: 90011, + errMsg: `startSoterAuthentication:fail no ${supportRequestAuthMode[0]} enrolled`, + }; + } + const realAuthMode = enrolledRequestAuthMode[0]; + if (realAuthMode === 'fingerPrint') { + if (plus.os.name.toLowerCase() === 'android') { + plus.nativeUI.showWaiting(authContent || t('uni.startSoterAuthentication.authContent')).onclose = function () { + plus.fingerprint.cancel(); + }; + } + plus.fingerprint.authenticate(() => { + plus.nativeUI.closeWaiting(); + resolve({ + authMode: realAuthMode, + errCode: 0, + }); + }, (e) => { + const res = { + authMode: realAuthMode, + }; + switch (e.code) { + case e.AUTHENTICATE_MISMATCH: + // 微信小程序没有这个回调,如果要实现此处回调需要多次触发需要用事件publish实现 + // invoke(callbackId, { + // authMode: realAuthMode, + // errCode: 90009, + // errMsg: 'startSoterAuthentication:fail' + // }) + break; + case e.AUTHENTICATE_OVERLIMIT: + // 微信小程序在第一次重试次数超限时安卓IOS返回不一致,安卓端会返回次数超过限制(errCode: 90010),IOS端会返回认证失败(errCode: 90009)。APP-IOS实际运行时不会次数超限,超过指定次数之后会弹出输入密码的界面 + plus.nativeUI.closeWaiting(); + reject('authenticate freeze. please try again later', extend(res, { + errCode: 90010, + })); + break; + case e.CANCEL: + plus.nativeUI.closeWaiting(); + reject('cancel', extend(res, { + errCode: 90008, + })); + break; + default: + plus.nativeUI.closeWaiting(); + reject('', extend(res, { + errCode: 90007, + })); + break; + } + }, { + message: authContent, + }); + } + else if (realAuthMode === 'facial') { + const faceID = requireNativePlugin('faceID'); + faceID.authenticate({ + message: authContent, + }, (e) => { + const res = { + authMode: realAuthMode, + }; + if (e.type === 'success' && e.code === 0) { + resolve({ + authMode: realAuthMode, + errCode: 0, + }); + } + else { + switch (e.code) { + case 4: + reject('', extend(res, { + errCode: 90009, + })); + break; + case 5: + reject('authenticate freeze. please try again later', extend(res, { + errCode: 90010, + })); + break; + case 6: + reject('', extend(res, { + errCode: 90008, + })); + break; + default: + reject('', extend(res, { + errCode: 90007, + })); + break; + } + } + }); + } +}, StartSoterAuthenticationProtocols, StartSoterAuthenticationOptions); + +let plus_; +let weex_; +let BroadcastChannel_; +function getRuntime() { + return typeof window === 'object' && + typeof navigator === 'object' && + typeof document === 'object' + ? 'webview' + : 'v8'; +} +function getPageId() { + return plus_.webview.currentWebview().id; +} +let channel; +let globalEvent$1; +const callbacks$2 = {}; +function onPlusMessage$1(res) { + const message = res.data && res.data.__message; + if (!message || !message.__page) { + return; + } + const pageId = message.__page; + const callback = callbacks$2[pageId]; + callback && callback(message); + if (!message.keep) { + delete callbacks$2[pageId]; + } +} +function addEventListener(pageId, callback) { + if (getRuntime() === 'v8') { + if (BroadcastChannel_) { + channel && channel.close(); + channel = new BroadcastChannel_(getPageId()); + channel.onmessage = onPlusMessage$1; + } + else if (!globalEvent$1) { + globalEvent$1 = weex_.requireModule('globalEvent'); + globalEvent$1.addEventListener('plusMessage', onPlusMessage$1); + } + } + else { + // @ts-ignore + window.__plusMessage = onPlusMessage$1; + } + callbacks$2[pageId] = callback; +} +class Page { + constructor(webview) { + this.webview = webview; + } + sendMessage(data) { + const message = JSON.parse(JSON.stringify({ + __message: { + data, + }, + })); + const id = this.webview.id; + if (BroadcastChannel_) { + const channel = new BroadcastChannel_(id); + channel.postMessage(message); + } + else { + plus_.webview.postMessageToUniNView && + plus_.webview.postMessageToUniNView(message, id); + } + } + close() { + this.webview.close(); + } +} +function showPage({ context = {}, url, data = {}, style = {}, onMessage, onClose, }) { + // eslint-disable-next-line + plus_ = context.plus || plus; + // eslint-disable-next-line + weex_ = context.weex || (typeof weex === 'object' ? weex : null); + // eslint-disable-next-line + BroadcastChannel_ = + context.BroadcastChannel || + (typeof BroadcastChannel === 'object' ? BroadcastChannel : null); + const titleNView = { + autoBackButton: true, + titleSize: '17px', + }; + const pageId = `page${Date.now()}`; + style = extend({}, style); + if (style.titleNView !== false && style.titleNView !== 'none') { + style.titleNView = extend(titleNView, style.titleNView); + } + const defaultStyle = { + top: 0, + bottom: 0, + usingComponents: {}, + popGesture: 'close', + scrollIndicator: 'none', + animationType: 'pop-in', + animationDuration: 200, + uniNView: { + path: `${(typeof process === 'object' && process.env && process.env.VUE_APP_TEMPLATE_PATH) || ''}/${url}.js`, - defaultFontSize: 16, - viewport: plus_.screen.resolutionWidth, - }, - }; - style = shared.extend(defaultStyle, style); - const page = plus_.webview.create('', pageId, style, { - extras: { - from: getPageId(), - runtime: getRuntime(), - data, - useGlobalEvent: !BroadcastChannel_, - }, - }); - page.addEventListener('close', onClose); - addEventListener(pageId, (message) => { - if (typeof onMessage === 'function') { - onMessage(message.data); - } - if (!message.keep) { - page.close('auto'); - } - }); - page.show(style.animationType, style.animationDuration); - return new Page(page); - } - - const scanCode = defineAsyncApi(API_SCAN_CODE, (options, { resolve, reject }) => { - initI18nScanCodeMsgsOnce(); - const { t } = useI18n(); - const statusBarStyle = getStatusBarStyle(); - const isDark = statusBarStyle !== 'light'; - let result; - let success = false; - const page = showPage({ - url: '__uniappscan', - data: Object.assign({}, options, { - messages: { - fail: t('uni.scanCode.fail'), - 'flash.on': t('uni.scanCode.flash.on'), - 'flash.off': t('uni.scanCode.flash.off'), - }, - }), - style: { - // @ts-expect-error - animationType: options.animationType || 'pop-in', - titleNView: { - autoBackButton: true, - type: 'float', - // @ts-expect-error - titleText: options.titleText || t('uni.scanCode.title'), - titleColor: '#ffffff', - backgroundColor: 'rgba(0,0,0,0)', - buttons: !options.onlyFromCamera - ? [ - { - // @ts-expect-error - text: options.albumText || t('uni.scanCode.album'), - fontSize: '17px', - width: '60px', - onclick: () => { - page.sendMessage({ - type: 'gallery', - }); - }, - }, - ] - : [], - }, - popGesture: 'close', - background: '#000000', - backButtonAutoControl: 'close', - }, - onMessage({ event, detail, }) { - result = detail; - success = event === 'marked'; - }, - onClose() { - if (isDark) { - plus.navigator.setStatusBarStyle('dark'); - } - result - ? success - ? (delete result.message, resolve(result)) - : reject(result.message) - : reject('cancel'); - }, - }); - if (isDark) { - plus.navigator.setStatusBarStyle('light'); - page.webview.addEventListener('popGesture', ({ type, result }) => { - if (type === 'start') { - plus.navigator.setStatusBarStyle('dark'); - } - else if (type === 'end' && !result) { - plus.navigator.setStatusBarStyle('light'); - } - }); - } - }, ScanCodeProtocol); - - const onThemeChange = defineOnApi(ON_THEME_CHANGE, () => { - UniServiceJSBridge.on(ON_THEME_CHANGE, (res) => { - UniServiceJSBridge.invokeOnCallback(ON_THEME_CHANGE, res); - }); - }); - - const getScreenBrightness = defineAsyncApi(API_GET_SCREEN_BRIGHTNESS, (_, { resolve }) => { - const value = plus.screen.getBrightness(false); - resolve({ value }); - }); - const setScreenBrightness = defineAsyncApi(API_SET_SCREEN_BRIGHTNESS, (options, { resolve }) => { - plus.screen.setBrightness(options.value, false); - resolve(); - }); - const setKeepScreenOn = defineAsyncApi(API_SET_KEEP_SCREEN_ON, (options, { resolve }) => { - plus.device.setWakelock(!!options.keepScreenOn); - resolve(); - }); - - const getImageInfo = defineAsyncApi(API_GET_IMAGE_INFO, (options, { resolve, reject }) => { - const path = TEMP_PATH + '/download/'; - plus.io.getImageInfo(shared.extend(options, { - savePath: path, - filename: path, - success: warpPlusSuccessCallback(resolve), - fail: warpPlusErrorCallback(reject), - })); - }, GetImageInfoProtocol, GetImageInfoOptions); - - const getVideoInfo = defineAsyncApi(API_GET_VIDEO_INFO, (options, { resolve, reject }) => { - plus.io.getVideoInfo({ - filePath: options.src, - success: (data) => { - return { - orientation: data.orientation, - type: data.type, - duration: data.duration, - size: data.size, - height: data.height, - width: data.width, - fps: data.fps || 30, - bitrate: data.bitrate, - }; - }, - fail: warpPlusErrorCallback(reject), - }); - }, GetVideoInfoProtocol, GetVideoInfoOptions); - - const previewImage = defineAsyncApi(API_PREVIEW_IMAGE, ({ current = 0, indicator = 'number', loop = false, urls, longPressActions }, { resolve, reject }) => { - initI18nPreviewImageMsgsOnce(); - const { t } = useI18n(); - urls = urls.map((url) => getRealPath(url)); - const index = Number(current); - if (isNaN(index)) { - current = urls.indexOf(getRealPath(current)); - current = current < 0 ? 0 : current; - } - else { - current = index; - } - plus.nativeUI.previewImage(urls, { - current, - indicator, - loop, - onLongPress: function (res) { - let itemList = []; - let itemColor = ''; - const hasLongPressActions = longPressActions && shared.isPlainObject(longPressActions); - if (!hasLongPressActions) { - itemList = [t('uni.previewImage.button.save')]; - itemColor = '#000000'; - } - else { - itemList = longPressActions.itemList - ? longPressActions.itemList - : []; - itemColor = longPressActions.itemColor - ? longPressActions.itemColor - : '#000000'; - } - const options = { - buttons: itemList.map((item) => ({ - title: item, - color: itemColor, - })), - cancel: t('uni.previewImage.cancel'), - }; - plus.nativeUI.actionSheet(options, (e) => { - if (e.index > 0) { - if (hasLongPressActions) { - typeof longPressActions.success === 'function' && - longPressActions.success({ - tapIndex: e.index - 1, - index: res.index, - }); - return; - } - plus.gallery.save(res.url, () => { - plus.nativeUI.toast(t('uni.previewImage.save.success')); - }, function () { - plus.nativeUI.toast(t('uni.previewImage.save.fail')); - }); - } - else if (hasLongPressActions) { - typeof longPressActions.fail === 'function' && - longPressActions.fail({ - errMsg: 'showActionSheet:fail cancel', - }); - } - }); - }, - }); - resolve(); - }, PreviewImageProtocol, PreviewImageOptions); - const closePreviewImage = defineAsyncApi(API_CLOSE_PREVIEW_IMAGE, (_, { resolve, reject }) => { - try { - // @ts-expect-error - plus.nativeUI.closePreviewImage(); - resolve(); - } - catch (error) { - reject(); - } - }); - - let recorder; - let recording = false; - let recordTimeout; - const publishRecorderStateChange = (state, res = {}) => { - onRecorderStateChange(shared.extend({ - state, - }, res)); - }; - const Recorder = { - start({ duration = 60000, sampleRate, numberOfChannels, encodeBitRate, format = 'mp3', frameSize, - // audioSource = 'auto', - }) { - if (recording) { - return publishRecorderStateChange('start'); - } - recorder = plus.audio.getRecorder(); - recorder.record({ - format, - samplerate: sampleRate ? String(sampleRate) : '', - filename: TEMP_PATH + '/recorder/', - }, (res) => publishRecorderStateChange('stop', { - tempFilePath: res, - }), (err) => publishRecorderStateChange('error', { - errMsg: err.message, - })); - recordTimeout = setTimeout(() => { - Recorder.stop(); - }, duration); - publishRecorderStateChange('start'); - recording = true; - }, - stop() { - if (recording) { - recorder.stop(); - recording = false; - recordTimeout && clearTimeout(recordTimeout); - } - }, - pause() { - if (recording) { - publishRecorderStateChange('error', { - errMsg: 'Unsupported operation: pause', - }); - } - }, - resume() { - if (recording) { - publishRecorderStateChange('error', { - errMsg: 'Unsupported operation: resume', - }); - } - }, - }; - const callbacks$1 = { - pause: null, - resume: null, - start: null, - stop: null, - error: null, - }; - function onRecorderStateChange(res) { - const state = res.state; - delete res.state; - delete res.errMsg; - if (state && typeof callbacks$1[state] === 'function') { - callbacks$1[state](res); - } - } - class RecorderManager { - constructor() { } - onError(callback) { - callbacks$1.error = callback; - } - onFrameRecorded(callback) { } - onInterruptionBegin(callback) { } - onInterruptionEnd(callback) { } - onPause(callback) { - callbacks$1.pause = callback; - } - onResume(callback) { - callbacks$1.resume = callback; - } - onStart(callback) { - callbacks$1.start = callback; - } - onStop(callback) { - callbacks$1.stop = callback; - } - pause() { - Recorder.pause(); - } - resume() { - Recorder.resume(); - } - start(options) { - Recorder.start(options); - } - stop() { - Recorder.stop(); - } - } - let recorderManager; - const getRecorderManager = defineSyncApi(API_GET_RECORDER_MANAGER, () => recorderManager || (recorderManager = new RecorderManager())); - - const saveVideoToPhotosAlbum = defineAsyncApi(API_SAVE_VIDEO_TO_PHOTOS_ALBUM, (options, { resolve, reject }) => { - plus.gallery.save(options.filePath, warpPlusSuccessCallback(resolve), warpPlusErrorCallback(reject)); - }, SaveVideoToPhotosAlbumProtocol, SaveVideoToPhotosAlbumOptions); - - const saveImageToPhotosAlbum = defineAsyncApi(API_SAVE_IMAGE_TO_PHOTOS_ALBUM, (options, { resolve, reject }) => { - plus.gallery.save(options.filePath, warpPlusSuccessCallback(resolve), warpPlusErrorCallback(reject)); - }, SaveImageToPhotosAlbumProtocol, SaveImageToPhotosAlbumOptions); - - const compressImage = defineAsyncApi(API_COMPRESS_IMAGE, (options, { resolve, reject }) => { - const dst = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(options.src)}`; - plus.zip.compressImage(shared.extend({}, options, { - dst, - }), () => { - resolve({ - tempFilePath: dst, - }); - }, reject); - }, CompressImageProtocol, CompressImageOptions); - - const compressVideo = defineAsyncApi(API_COMPRESS_VIDEO, (options, { resolve, reject }) => { - const filename = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(options.src)}`; - plus.zip.compressVideo(shared.extend({}, options, { - filename, - }), () => { - resolve({ - tempFilePath: filename, - }); - }, reject); - }, CompressVideoProtocol, CompressVideoOptions); - - /** - * 获取文件信息 - * @param {string} filePath 文件路径 - * @returns {Promise} 文件信息Promise - */ - function getFileInfo(filePath) { - return new Promise((resolve, reject) => { - plus.io.resolveLocalFileSystemURL(filePath, function (entry) { - entry.getMetadata(resolve, reject, false); - }, reject); - }); - } - const chooseImage = defineAsyncApi(API_CHOOSE_IMAGE, ({ count, sizeType, sourceType, crop } = {}, { resolve, reject }) => { - initI18nChooseImageMsgsOnce(); - const { t } = useI18n(); - const errorCallback = warpPlusErrorCallback(reject); - function successCallback(paths) { - const tempFiles = []; - const tempFilePaths = []; - Promise.all(paths.map((path) => getFileInfo(path))) - .then((filesInfo) => { - filesInfo.forEach((file, index) => { - const path = paths[index]; - tempFilePaths.push(path); - tempFiles.push({ path, size: file.size }); - }); - resolve({ - tempFilePaths, - tempFiles, - }); - }) - .catch(errorCallback); - } - function openCamera() { - const camera = plus.camera.getCamera(); - camera.captureImage((path) => successCallback([path]), errorCallback, { - filename: TEMP_PATH + '/camera/', - resolution: 'high', - crop, - // @ts-expect-error - sizeType, - }); - } - function openAlbum() { - // @ts-ignore 5+此API分单选和多选,多选返回files:string[] - plus.gallery.pick(({ files }) => successCallback(files), errorCallback, { - maximum: count, - multiple: true, - system: false, - filename: TEMP_PATH + '/gallery/', - permissionAlert: true, - crop, - // @ts-expect-error - sizeType, - }); - } - if (sourceType.length === 1) { - if (sourceType.includes('album')) { - openAlbum(); - return; - } - else if (sourceType.includes('camera')) { - openCamera(); - return; - } - } - plus.nativeUI.actionSheet({ - cancel: t('uni.chooseImage.cancel'), - buttons: [ - { - title: t('uni.chooseImage.sourceType.camera'), - }, - { - title: t('uni.chooseImage.sourceType.album'), - }, - ], - }, (e) => { - switch (e.index) { - case 1: - openCamera(); - break; - case 2: - openAlbum(); - break; - default: - errorCallback(); - break; - } - }); - }, ChooseImageProtocol, ChooseImageOptions); - - const chooseVideo = defineAsyncApi(API_CHOOSE_VIDEO, ({ sourceType, compressed, maxDuration, camera }, { resolve, reject }) => { - initI18nChooseVideoMsgsOnce(); - const { t } = useI18n(); - const errorCallback = warpPlusErrorCallback(reject); - function successCallback(tempFilePath) { - plus.io.getVideoInfo({ - filePath: tempFilePath, - success(videoInfo) { - const result = { - errMsg: 'chooseVideo:ok', - tempFilePath: tempFilePath, - size: videoInfo.size, - duration: videoInfo.duration, - width: videoInfo.width, - height: videoInfo.height, - }; - // @ts-expect-error tempFile、name 仅H5支持 - resolve(result); - }, - fail: errorCallback, - }); - } - function openAlbum() { - plus.gallery.pick( - // @ts-ignore 5+此API分单选和多选,多选返回files:string[] - ({ files }) => successCallback(files[0]), errorCallback, { - filter: 'video', - system: false, - // 不启用 multiple 时 system 无效 - multiple: true, - maximum: 1, - filename: TEMP_PATH + '/gallery/', - permissionAlert: true, - // @ts-expect-error 新增参数,用于视频压缩 - videoCompress: compressed, - }); - } - function openCamera() { - const plusCamera = plus.camera.getCamera(); - plusCamera.startVideoCapture(successCallback, errorCallback, { - index: camera === 'front' ? '2' : '1', - videoMaximumDuration: maxDuration, - filename: TEMP_PATH + '/camera/', - // @ts-expect-error 新增参数,用于视频压缩 - videoCompress: compressed, - }); - } - if (sourceType.length === 1) { - if (sourceType.includes('album')) { - openAlbum(); - return; - } - else if (sourceType.includes('camera')) { - openCamera(); - return; - } - } - plus.nativeUI.actionSheet({ - cancel: t('uni.chooseVideo.cancel'), - buttons: [ - { - title: t('uni.chooseVideo.sourceType.camera'), - }, - { - title: t('uni.chooseVideo.sourceType.album'), - }, - ], - }, (e) => { - switch (e.index) { - case 1: - openCamera(); - break; - case 2: - openAlbum(); - break; - default: - errorCallback(); - break; - } - }); - }, ChooseVideoProtocol, ChooseVideoOptions); - - const showKeyboard = defineAsyncApi(API_SHOW_KEYBOARD, (_, { resolve }) => { - plus.key.showSoftKeybord(); - resolve(); - }); - const hideKeyboard = defineAsyncApi(API_HIDE_KEYBOARD, (_, { resolve }) => { - plus.key.hideSoftKeybord(); - resolve(); - }); - function onKeyboardHeightChangeCallback(res) { - UniServiceJSBridge.invokeOnCallback(ON_KEYBOARD_HEIGHT_CHANGE, res); - } - const onKeyboardHeightChange = defineOnApi(ON_KEYBOARD_HEIGHT_CHANGE, () => { - UniServiceJSBridge.on(ON_KEYBOARD_HEIGHT_CHANGE, onKeyboardHeightChangeCallback); - }); - const offKeyboardHeightChange = defineOffApi(ON_KEYBOARD_HEIGHT_CHANGE, () => { - UniServiceJSBridge.off(ON_KEYBOARD_HEIGHT_CHANGE, onKeyboardHeightChangeCallback); - }); - - class DownloadTask { - constructor(downloader) { - this._callbacks = []; - this._downloader = downloader; - downloader.addEventListener('statechanged', (download, status) => { - if (download.downloadedSize && download.totalSize) { - this._callbacks.forEach((callback) => { - callback({ - progress: Math.round((download.downloadedSize / download.totalSize) * 100), - totalBytesWritten: download.downloadedSize, - totalBytesExpectedToWrite: download.totalSize, - }); - }); - } - }); - } - abort() { - this._downloader.abort(); - } - onProgressUpdate(callback) { - if (typeof callback !== 'function') { - return; - } - this._callbacks.push(callback); - } - offProgressUpdate(callback) { - const index = this._callbacks.indexOf(callback); - if (index >= 0) { - this._callbacks.splice(index, 1); - } - } - onHeadersReceived(callback) { - throw new Error('Method not implemented.'); - } - offHeadersReceived(callback) { - throw new Error('Method not implemented.'); - } - } - const downloadFile = defineTaskApi(API_DOWNLOAD_FILE, ({ url, header, timeout }, { resolve, reject }) => { - timeout = - (timeout || - (__uniConfig.networkTimeout && __uniConfig.networkTimeout.request) || - 60 * 1000) / 1000; - const downloader = plus.downloader.createDownload(url, { - timeout, - filename: TEMP_PATH + '/download/', - // 需要与其它平台上的表现保持一致,不走重试的逻辑。 - retry: 0, - retryInterval: 0, - }, (download, statusCode) => { - if (statusCode) { - resolve({ - tempFilePath: download.filename, - statusCode, - }); - } - else { - reject(`statusCode: ${statusCode}`); - } - }); - const downloadTask = new DownloadTask(downloader); - for (const name in header) { - if (shared.hasOwn(header, name)) { - downloader.setRequestHeader(name, header[name]); - } - } - downloader.start(); - return downloadTask; - }, DownloadFileProtocol, DownloadFileOptions); - - const cookiesParse = (header) => { - let cookiesStr = header['Set-Cookie'] || header['set-cookie']; - let cookiesArr = []; - if (!cookiesStr) { - return []; - } - if (cookiesStr[0] === '[' && cookiesStr[cookiesStr.length - 1] === ']') { - cookiesStr = cookiesStr.slice(1, -1); - } - const handleCookiesArr = cookiesStr.split(';'); - for (let i = 0; i < handleCookiesArr.length; i++) { - if (handleCookiesArr[i].indexOf('Expires=') !== -1 || - handleCookiesArr[i].indexOf('expires=') !== -1) { - cookiesArr.push(handleCookiesArr[i].replace(',', '')); - } - else { - cookiesArr.push(handleCookiesArr[i]); - } - } - cookiesArr = cookiesArr.join(';').split(','); - return cookiesArr; - }; - function formatResponse(res, args) { - if (typeof res.data === 'string' && res.data.charCodeAt(0) === 65279) { - res.data = res.data.substr(1); - } - res.statusCode = parseInt(String(res.statusCode), 10); - if (shared.isPlainObject(res.header)) { - res.header = Object.keys(res.header).reduce(function (ret, key) { - const value = res.header[key]; - if (Array.isArray(value)) { - ret[key] = value.join(','); - } - else if (typeof value === 'string') { - ret[key] = value; - } - return ret; - }, {}); - } - if (args.dataType && args.dataType.toLowerCase() === 'json') { - try { - res.data = JSON.parse(res.data); - } - catch (e) { } - } - return res; - } - /** - * 请求任务类 - */ - class RequestTask { - constructor(requestTask) { - this._requestTask = requestTask; - } - abort() { - this._requestTask.abort(); - } - offHeadersReceived() { } - onHeadersReceived() { } - } - const request = defineTaskApi(API_REQUEST, (args, { resolve, reject }) => { - let { header, method, data, timeout, url, responseType, sslVerify, firstIpv4, - // @ts-ignore tls 缺少 types 类型 - tls, } = args; - let contentType; - for (const name in header) { - if (name.toLowerCase() === 'content-type') { - contentType = header[name]; - break; - } - } - if (method !== 'GET' && - contentType.indexOf('application/json') === 0 && - shared.isPlainObject(data)) { - data = JSON.stringify(data); - } - const stream = requireNativePlugin('stream'); - const headers = {}; - let abortTimeout; - let aborted; - let hasContentType = false; - for (const name in header) { - if (!hasContentType && name.toLowerCase() === 'content-type') { - hasContentType = true; - headers['Content-Type'] = header[name]; - // TODO 需要重构 - if (method !== 'GET' && - header[name].indexOf('application/x-www-form-urlencoded') === 0 && - typeof data !== 'string' && - !(data instanceof ArrayBuffer)) { - const bodyArray = []; - for (const key in data) { - if (shared.hasOwn(data, key)) { - bodyArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])); - } - } - data = bodyArray.join('&'); - } - } - else { - headers[name] = header[name]; - } - } - if (!hasContentType && method === 'POST') { - headers['Content-Type'] = - 'application/x-www-form-urlencoded; charset=UTF-8'; - } - if (timeout) { - abortTimeout = setTimeout(() => { - aborted = true; - reject('timeout'); - }, timeout + 200); // TODO +200 发消息到原生层有时间开销,以后考虑由原生层回调超时 - } - const options = { - method, - url: url.trim(), - headers, - type: responseType === 'arraybuffer' ? 'base64' : 'text', - timeout: timeout || 6e5, - // 配置和weex模块内相反 - sslVerify: !sslVerify, - firstIpv4: firstIpv4, - tls, - }; - let withArrayBuffer = false; - if (method !== 'GET') { - if (toString.call(data) === '[object ArrayBuffer]') { - withArrayBuffer = true; - } - else { - options.body = typeof data === 'string' ? data : JSON.stringify(data); - } - } - const callback = ({ ok, status, data, headers, errorMsg, }) => { - if (aborted) { - return; - } - if (abortTimeout) { - clearTimeout(abortTimeout); - } - const statusCode = status; - if (statusCode > 0) { - resolve(formatResponse({ - data: ok && responseType === 'arraybuffer' - ? base64ToArrayBuffer(data) - : data, - statusCode, - header: headers, - cookies: cookiesParse(headers), - }, args)); - } - else { - let errMsg = 'abort statusCode:' + statusCode; - if (errorMsg) { - errMsg = errMsg + ' ' + errorMsg; - } - reject(errMsg); - } - }; - if (withArrayBuffer) { - stream.fetchWithArrayBuffer({ - '@type': 'binary', - base64: arrayBufferToBase64(data), - }, options, callback); - } - else { - stream.fetch(options, callback); - } - return new RequestTask({ - abort() { - aborted = true; - if (abortTimeout) { - clearTimeout(abortTimeout); - } - reject('abort'); - }, - }); - }, RequestProtocol, RequestOptions); - const configMTLS = defineAsyncApi(API_CONFIG_MTLS, ({ certificates }, { resolve, reject }) => { - const stream = requireNativePlugin('stream'); - stream.configMTLS(certificates, ({ type, code, message }) => { - switch (type) { - case 'success': - resolve({ code }); - break; - case 'fail': - reject(message, { code }); - break; - } - }); - }, ConfigMTLSProtocol, ConfigMTLSOptions); - - const socketTasks = []; - const socketsMap = {}; - const globalEvent = { - open: '', - close: '', - error: '', - message: '', - }; - let socket; - function createSocketTask(args) { - const socketId = String(Date.now()); - let errMsg; - try { - if (!socket) { - socket = requireNativePlugin('uni-webSocket'); - bindSocketCallBack(socket); - } - socket.WebSocket({ - id: socketId, - url: args.url, - protocol: Array.isArray(args.protocols) - ? args.protocols.join(',') - : args.protocols, - header: args.header, - }); - } - catch (error) { - errMsg = error; - } - return { socket, socketId, errMsg }; - } - function bindSocketCallBack(socket) { - socket.onopen((e) => { - const curSocket = socketsMap[e.id]; - if (!curSocket) - return; - curSocket._socketOnOpen(); - }); - socket.onmessage((e) => { - const curSocket = socketsMap[e.id]; - if (!curSocket) - return; - curSocket._socketOnMessage(e); - }); - socket.onerror((e) => { - const curSocket = socketsMap[e.id]; - if (!curSocket) - return; - curSocket._socketOnError(); - }); - socket.onclose((e) => { - const curSocket = socketsMap[e.id]; - if (!curSocket) - return; - curSocket._socketOnClose(); - }); - } - class SocketTask { - constructor(socket, socketId) { - this.id = socketId; - this._socket = socket; - this._callbacks = { - open: [], - close: [], - error: [], - message: [], - }; - this.CLOSED = 3; - this.CLOSING = 2; - this.CONNECTING = 0; - this.OPEN = 1; - this.readyState = this.CLOSED; - if (!this._socket) - return; - } - _socketOnOpen() { - this.readyState = this.OPEN; - this.socketStateChange('open'); - } - _socketOnMessage(e) { - this.socketStateChange('message', { - data: typeof e.data === 'object' - ? base64ToArrayBuffer(e.data.base64) - : e.data, - }); - } - _socketOnError() { - this.socketStateChange('error'); - this.onErrorOrClose(); - } - _socketOnClose() { - this.socketStateChange('close'); - this.onErrorOrClose(); - } - onErrorOrClose() { - this.readyState = this.CLOSED; - delete socketsMap[this.id]; - const index = socketTasks.indexOf(this); - if (index >= 0) { - socketTasks.splice(index, 1); - } - } - socketStateChange(name, res = {}) { - const data = name === 'message' ? res : {}; - if (this === socketTasks[0] && globalEvent[name]) { - UniServiceJSBridge.invokeOnCallback(globalEvent[name], data); - } - // WYQ fix: App平台修复websocket onOpen时发送数据报错的Bug - this._callbacks[name].forEach((callback) => { - if (typeof callback === 'function') { - callback(data); - } - }); - } - send(args, callopt = true) { - if (this.readyState !== this.OPEN) { - callOptions(args, 'sendSocketMessage:fail WebSocket is not connected'); - } - try { - this._socket.send({ - id: this.id, - data: typeof args.data === 'object' - ? { - '@type': 'binary', - base64: arrayBufferToBase64(args.data), - } - : args.data, - }); - callopt && callOptions(args, 'sendSocketMessage:ok'); - } - catch (error) { - callopt && callOptions(args, `sendSocketMessage:fail ${error}`); - } - } - close(args, callopt = true) { - this.readyState = this.CLOSING; - try { - this._socket.close(shared.extend({ - id: this.id, - args, - })); - callopt && callOptions(args, 'closeSocket:ok'); - } - catch (error) { - callopt && callOptions(args, `closeSocket:fail ${error}`); - } - } - onOpen(callback) { - this._callbacks.open.push(callback); - } - onClose(callback) { - this._callbacks.close.push(callback); - } - onError(callback) { - this._callbacks.error.push(callback); - } - onMessage(callback) { - this._callbacks.message.push(callback); - } - } - const connectSocket = defineTaskApi(API_CONNECT_SOCKET, ({ url, protocols, header, method }, { resolve, reject }) => { - const { socket, socketId, errMsg } = createSocketTask({ - url, - protocols, - header, - method, - }); - const socketTask = new SocketTask(socket, socketId); - if (errMsg) { - setTimeout(() => { - reject(errMsg); - }, 0); - } - else { - socketTasks.push(socketTask); - socketsMap[socketId] = socketTask; - } - setTimeout(() => { - resolve(); - }, 0); - return socketTask; - }, ConnectSocketProtocol, ConnectSocketOptions); - const sendSocketMessage = defineAsyncApi(API_SEND_SOCKET_MESSAGE, (args, { resolve, reject }) => { - const socketTask = socketTasks[0]; - if (!socketTask || socketTask.readyState !== socketTask.OPEN) { - reject('WebSocket is not connected'); - return; - } - socketTask.send({ data: args.data }, false); - resolve(); - }, SendSocketMessageProtocol); - const closeSocket = defineAsyncApi(API_CLOSE_SOCKET, (args, { resolve, reject }) => { - const socketTask = socketTasks[0]; - if (!socketTask) { - reject('WebSocket is not connected'); - return; - } - socketTask.readyState = socketTask.CLOSING; - socketTask.close(args, false); - resolve(); - }, CloseSocketProtocol); - function on(event) { - const api = `onSocket${shared.capitalize(event)}`; - return defineOnApi(api, () => { - globalEvent[event] = api; - }); - } - const onSocketOpen = /*#__PURE__*/ on('open'); - const onSocketError = /*#__PURE__*/ on('error'); - const onSocketMessage = /*#__PURE__*/ on('message'); - const onSocketClose = /*#__PURE__*/ on('close'); - - class UploadTask { - constructor(uploader) { - this._callbacks = []; - this._uploader = uploader; - uploader.addEventListener('statechanged', (upload, status) => { - if (upload.uploadedSize && upload.totalSize) { - this._callbacks.forEach((callback) => { - callback({ - progress: parseInt(String((upload.uploadedSize / upload.totalSize) * 100)), - totalBytesSent: upload.uploadedSize, - totalBytesExpectedToSend: upload.totalSize, - }); - }); - } - }); - } - abort() { - this._uploader.abort(); - } - onProgressUpdate(callback) { - if (typeof callback !== 'function') { - return; - } - this._callbacks.push(callback); - } - onHeadersReceived() { } - offProgressUpdate(callback) { - const index = this._callbacks.indexOf(callback); - if (index >= 0) { - this._callbacks.splice(index, 1); - } - } - offHeadersReceived() { } - } - const uploadFile = defineTaskApi(API_UPLOAD_FILE, ({ url, timeout, header, formData, files, filePath, name }, { resolve, reject }) => { - const uploader = plus.uploader.createUpload(url, { - timeout, - // 需要与其它平台上的表现保持一致,不走重试的逻辑。 - retry: 0, - retryInterval: 0, - }, (upload, statusCode) => { - if (statusCode) { - resolve({ - data: upload.responseText, - statusCode, - }); - } - else { - reject(`statusCode: ${statusCode}`); - } - }); - for (const name in header) { - if (shared.hasOwn(header, name)) { - uploader.setRequestHeader(name, String(header[name])); - } - } - for (const name in formData) { - if (shared.hasOwn(formData, name)) { - uploader.addData(name, String(formData[name])); - } - } - if (files && files.length) { - files.forEach((file) => { - uploader.addFile(getRealPath(file.uri), { - key: file.name || 'file', - }); - }); - } - else { - uploader.addFile(getRealPath(filePath), { - key: name, - }); - } - const uploadFileTask = new UploadTask(uploader); - uploader.start(); - return uploadFileTask; - }, UploadFileProtocol, UploadFileOptions); - - const audios = {}; - const evts = [ - 'play', - 'canplay', - 'ended', - 'stop', - 'waiting', - 'seeking', - 'seeked', - 'pause', - ]; - const AUDIO_DEFAULT_SESSION_CATEGORY = 'playback'; - const initStateChage = (audioId) => { - const audio = audios[audioId]; - if (!audio) { - return; - } - if (!audio.initStateChage) { - audio.initStateChage = true; - audio.addEventListener('error', (error) => { - onAudioStateChange({ - state: 'error', - audioId, - errMsg: 'MediaError', - errCode: error.code, - }); - }); - evts.forEach((event) => { - audio.addEventListener(event, () => { - // 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题 - if (event === 'play') { - audio.isStopped = false; - } - else if (event === 'stop') { - audio.isStopped = true; - } - onAudioStateChange({ - state: event, - audioId, - }); - }); - }); - } - }; - function createAudioInstance() { - const audioId = `${Date.now()}${Math.random()}`; - const audio = (audios[audioId] = plus.audio.createPlayer('')); // 此处空字符串必填 - audio.src = ''; - audio.volume = 1; - audio.startTime = 0; - audio.setSessionCategory(AUDIO_DEFAULT_SESSION_CATEGORY); - return { - errMsg: 'createAudioInstance:ok', - audioId, - }; - } - function setAudioState({ audioId, src, startTime, autoplay = false, loop = false, obeyMuteSwitch, volume, sessionCategory = AUDIO_DEFAULT_SESSION_CATEGORY, }) { - const audio = audios[audioId]; - if (audio) { - const style = { - loop, - autoplay, - }; - if (src) { - audio.src = style.src = getRealPath(src); - } - if (startTime) { - audio.startTime = style.startTime = startTime; - } - if (typeof volume === 'number') { - audio.volume = style.volume = volume; - } - audio.setStyles(style); - if (sessionCategory) { - audio.setSessionCategory(sessionCategory); - } - initStateChage(audioId); - } - return { - errMsg: 'setAudioState:ok', - }; - } - function getAudioState({ audioId }) { - const audio = audios[audioId]; - if (!audio) { - return { - errMsg: 'getAudioState:fail', - }; - } - const { src, startTime, volume } = audio; - return { - errMsg: 'getAudioState:ok', - duration: 1e3 * (audio.getDuration() || 0), - currentTime: audio.isStopped ? 0 : 1e3 * audio.getPosition(), - paused: audio.isPaused(), - src, - volume, - startTime: 1e3 * startTime, - buffered: 1e3 * audio.getBuffered(), - }; - } - function operateAudio({ operationType, audioId, currentTime, }) { - const audio = audios[audioId]; - switch (operationType) { - case 'play': - case 'pause': - case 'stop': - audio[operationType === 'play' && audio.isPaused() ? 'resume' : operationType](); - break; - case 'seek': - typeof currentTime != 'undefined' ? audio.seekTo(currentTime / 1e3) : ''; - break; - } - return { - errMsg: 'operateAudio:ok', - }; - } - const innerAudioContexts = Object.create(null); - const onAudioStateChange = ({ state, audioId, errMsg, errCode, }) => { - const audio = innerAudioContexts[audioId]; - if (audio) { - emit(audio, state, errMsg, errCode); - if (state === 'play') { - const oldCurrentTime = audio.currentTime; - audio.__timing = setInterval(() => { - const currentTime = audio.currentTime; - if (currentTime !== oldCurrentTime) { - emit(audio, 'timeUpdate'); - } - }, 200); - } - else if (state === 'pause' || state === 'stop' || state === 'error') { - clearInterval(audio.__timing); - } - } - }; - const props$1 = [ - { - name: 'src', - cache: true, - }, - { - name: 'startTime', - default: 0, - cache: true, - }, - { - name: 'autoplay', - default: false, - cache: true, - }, - { - name: 'loop', - default: false, - cache: true, - }, - { - name: 'obeyMuteSwitch', - default: true, - readonly: true, - cache: true, - }, - { - name: 'duration', - readonly: true, - }, - { - name: 'currentTime', - readonly: true, - }, - { - name: 'paused', - readonly: true, - }, - { - name: 'buffered', - readonly: true, - }, - { - name: 'volume', - }, - ]; - class InnerAudioContext { - constructor(id) { - this.id = id; - this._callbacks = {}; - this._options = {}; - // 初始化事件监听列表 - innerAudioContextEventNames.forEach((eventName) => { - this._callbacks[eventName] = []; - }); - props$1.forEach((item) => { - const name = item.name; - Object.defineProperty(this, name, { - get: () => { - const result = item.cache - ? this._options - : getAudioState({ - audioId: this.id, - }); - const value = name in result ? result[name] : item.default; - return typeof value === 'number' && name !== 'volume' - ? value / 1e3 - : value; - }, - set: item.readonly - ? undefined - : (value) => { - this._options[name] = value; - setAudioState(shared.extend({}, this._options, { - audioId: this.id, - })); - }, - }); - }); - initInnerAudioContextEventOnce(); - } - play() { - this._operate('play'); - } - pause() { - this._operate('pause'); - } - stop() { - this._operate('stop'); - } - seek(position) { - this._operate('seek', { - currentTime: position * 1e3, - }); - } - destroy() { - clearInterval(this.__timing); - if (audios[this.id]) { - audios[this.id].close(); - delete audios[this.id]; - } - delete innerAudioContexts[this.id]; - } - _operate(type, options) { - operateAudio(shared.extend({}, options, { - audioId: this.id, - operationType: type, - })); - } - } - const initInnerAudioContextEventOnce = /*#__PURE__*/ once(() => { - // 批量设置音频上下文事件监听方法 - innerAudioContextEventNames.forEach((eventName) => { - InnerAudioContext.prototype[eventName] = function (callback) { - if (typeof callback === 'function') { - this._callbacks[eventName].push(callback); - } - }; - }); - // 批量设置音频上下文事件取消监听方法 - innerAudioContextOffEventNames.forEach((eventName) => { - InnerAudioContext.prototype[eventName] = function (callback) { - const callbacks = this._callbacks[eventName]; - const index = callbacks.indexOf(callback); - if (index >= 0) { - callbacks.splice(index, 1); - } - }; - }); - }); - function emit(audio, state, errMsg, errCode) { - const name = `on${shared.capitalize(state)}`; - audio._callbacks[name].forEach((callback) => { - if (typeof callback === 'function') { - callback(state === 'error' - ? { - errMsg, - errCode, - } - : {}); - } - }); - } - /** - * 创建音频上下文 - */ - const createInnerAudioContext = defineSyncApi(API_CREATE_INNER_AUDIO_CONTEXT, () => { - const { audioId } = createAudioInstance(); - const innerAudioContext = new InnerAudioContext(audioId); - innerAudioContexts[audioId] = innerAudioContext; - return innerAudioContext; - }); - - const eventNames = [ - 'canplay', - 'play', - 'pause', - 'stop', - 'ended', - 'timeUpdate', - 'prev', - 'next', - 'error', - 'waiting', - ]; - const callbacks = { - canplay: [], - play: [], - pause: [], - stop: [], - ended: [], - timeUpdate: [], - prev: [], - next: [], - error: [], - waiting: [], - }; - let audio; - let timeUpdateTimer = null; - const TIME_UPDATE = 250; - const events = ['play', 'pause', 'ended', 'stop', 'canplay']; - function startTimeUpdateTimer() { - stopTimeUpdateTimer(); - timeUpdateTimer = setInterval(() => { - onBackgroundAudioStateChange({ state: 'timeUpdate' }); - }, TIME_UPDATE); - } - function stopTimeUpdateTimer() { - if (timeUpdateTimer !== null) { - clearInterval(timeUpdateTimer); - } - } - function initMusic() { - if (audio) { - return; - } - const publish = UniServiceJSBridge.invokeOnCallback; - audio = plus.audio.createPlayer({ - autoplay: true, - backgroundControl: true, - }); - audio.src = - audio.title = - audio.epname = - audio.singer = - audio.coverImgUrl = - audio.webUrl = - ''; - audio.startTime = 0; - events.forEach((event) => { - audio.addEventListener(event, () => { - // 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题 - if (event === 'play') { - audio.isStopped = false; - startTimeUpdateTimer(); - } - else if (event === 'stop') { - audio.isStopped = true; - } - if (event === 'pause' || event === 'ended' || event === 'stop') { - stopTimeUpdateTimer(); - } - const eventName = `onMusic${event[0].toUpperCase() + event.substr(1)}`; - publish(eventName, { - dataUrl: audio.src, - errMsg: `${eventName}:ok`, - }); - onBackgroundAudioStateChange({ - state: event, - dataUrl: audio.src, - }); - }); - }); - audio.addEventListener('waiting', () => { - stopTimeUpdateTimer(); - onBackgroundAudioStateChange({ - state: 'waiting', - dataUrl: audio.src, - }); - }); - audio.addEventListener('error', (err) => { - stopTimeUpdateTimer(); - publish('onMusicError', { - dataUrl: audio.src, - errMsg: 'Error:' + err.message, - }); - onBackgroundAudioStateChange({ - state: 'error', - dataUrl: audio.src, - errMsg: err.message, - errCode: err.code, - }); - }); - // @ts-ignore - audio.addEventListener('prev', () => publish('onBackgroundAudioPrev')); - // @ts-ignore - audio.addEventListener('next', () => publish('onBackgroundAudioNext')); - } - function getBackgroundAudioState() { - let data = { - duration: 0, - currentTime: 0, - paused: false, - src: '', - buffered: 0, - title: '', - epname: '', - singer: '', - coverImgUrl: '', - webUrl: '', - startTime: 0, - errMsg: 'getBackgroundAudioState:ok', - }; - if (audio) { - const newData = { - duration: audio.getDuration() || 0, - currentTime: audio.isStopped ? 0 : audio.getPosition(), - paused: audio.isPaused(), - src: audio.src, - buffered: audio.getBuffered(), - title: audio.title, - epname: audio.epname, - singer: audio.singer, - coverImgUrl: audio.coverImgUrl, - webUrl: audio.webUrl, - startTime: audio.startTime, - }; - data = shared.extend(data, newData); - } - return data; - } - function setMusicState(args) { - initMusic(); - const props = [ - 'src', - 'startTime', - 'coverImgUrl', - 'webUrl', - 'singer', - 'epname', - 'title', - ]; - const style = {}; - Object.keys(args).forEach((key) => { - if (props.indexOf(key) >= 0) { - let val = args[key]; - if (key === props[0] && val) { - val = getRealPath(val); - } - audio[key] = style[key] = val; - } - }); - audio.setStyles(style); - } - function operateMusicPlayer({ operationType, src, position, api = 'operateMusicPlayer', title, coverImgUrl, }) { - var operationTypes = ['resume', 'pause', 'stop']; - if (operationTypes.indexOf(operationType) > 0) { - audio && audio[operationType](); - } - else if (operationType === 'play') { - setMusicState({ - src, - startTime: position, - title, - coverImgUrl, - }); - audio.play(); - } - else if (operationType === 'seek') { - audio && audio.seekTo(position); - } - return { - errMsg: `${api}:ok`, - }; - } - function operateBackgroundAudio({ operationType, src, startTime, currentTime, }) { - return operateMusicPlayer({ - operationType, - src, - position: startTime || currentTime || 0, - api: 'operateBackgroundAudio', - }); - } - function onBackgroundAudioStateChange({ state, errMsg, errCode, dataUrl, }) { - callbacks[state].forEach((callback) => { - if (typeof callback === 'function') { - callback(state === 'error' - ? { - errMsg, - errCode, - } - : {}); - } - }); - } - const onInitBackgroundAudioManager = /*#__PURE__*/ once(() => { - eventNames.forEach((item) => { - BackgroundAudioManager.prototype[`on${shared.capitalize(item)}`] = - function (callback) { - callbacks[item].push(callback); - }; - }); - }); - const props = [ - { - name: 'duration', - readonly: true, - }, - { - name: 'currentTime', - readonly: true, - }, - { - name: 'paused', - readonly: true, - }, - { - name: 'src', - cache: true, - }, - { - name: 'startTime', - default: 0, - cache: true, - }, - { - name: 'buffered', - readonly: true, - }, - { - name: 'title', - cache: true, - }, - { - name: 'epname', - cache: true, - }, - { - name: 'singer', - cache: true, - }, - { - name: 'coverImgUrl', - cache: true, - }, - { - name: 'webUrl', - cache: true, - }, - { - name: 'protocol', - readonly: true, - default: 'http', - }, - ]; - class BackgroundAudioManager { - constructor() { - this._options = {}; - props.forEach((item) => { - const name = item.name; - Object.defineProperty(this, name, { - get: () => { - const result = item.cache ? this._options : getBackgroundAudioState(); - return name in result ? result[name] : item.default; - }, - set: item.readonly - ? undefined - : (value) => { - this._options[name] = value; - setMusicState(this._options); - }, - }); - }); - onInitBackgroundAudioManager(); - } - play() { - this._operate('play'); - } - pause() { - this._operate('pause'); - } - stop() { - this._operate('stop'); - } - seek(position) { - this._operate('seek', { - currentTime: position, - }); - } - _operate(type, options) { - operateBackgroundAudio(shared.extend({}, options, { - operationType: type, - })); - } - } - let backgroundAudioManager; - const getBackgroundAudioManager = defineSyncApi(API_GET_BACKGROUND_AUDIO_MANAGER, () => backgroundAudioManager || - (backgroundAudioManager = new BackgroundAudioManager())); - - class LivePusherContext { - constructor(id, ctx) { - this.id = id; - this.ctx = ctx; - } - start(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'start', option); - } - stop(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'stop', option); - } - pause(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'pause', option); - } - resume(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'resume', option); - } - switchCamera(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'switchCamera', option); - } - snapshot(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'snapshot', option); - } - toggleTorch(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'toggleTorch', option); - } - playBGM(option) { - return invokeVmMethod(this.ctx, 'playBGM', option); - } - stopBGM(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'stopBGM', option); - } - pauseBGM(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'pauseBGM', option); - } - resumeBGM(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'resumeBGM', option); - } - setBGMVolume(option) { - return invokeVmMethod(this.ctx, 'setBGMVolume', option); - } - startPreview(option) { - return invokeVmMethodWithoutArgs(this.ctx, 'startPreview', option); - } - stopPreview(args) { - return invokeVmMethodWithoutArgs(this.ctx, 'stopPreview', args); - } - } - const createLivePusherContext = defineSyncApi(API_CREATE_LIVE_PUSHER_CONTEXT, (id, vm) => { - if (!vm) { - return console.warn('uni.createLivePusherContext: 2 arguments required, but only 1 present'); - } - const elm = findElmById(id, vm); - if (!elm) { - return console.warn('Can not find `' + id + '`'); - } - return new LivePusherContext(id, elm); - }, CreateLivePusherContextProtocol); - - const PI = 3.1415926535897932384626; - const a = 6378245.0; - const ee = 0.00669342162296594323; - function gcj02towgs84(lng, lat) { - lat = +lat; - lng = +lng; - if (outOfChina(lng, lat)) { - return [lng, lat]; - } - let dlat = _transformlat(lng - 105.0, lat - 35.0); - let dlng = _transformlng(lng - 105.0, lat - 35.0); - const radlat = (lat / 180.0) * PI; - let magic = Math.sin(radlat); - magic = 1 - ee * magic * magic; - const sqrtmagic = Math.sqrt(magic); - dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI); - dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI); - const mglat = lat + dlat; - const mglng = lng + dlng; - return [lng * 2 - mglng, lat * 2 - mglat]; - } - function wgs84togcj02(lng, lat) { - lat = +lat; - lng = +lng; - if (outOfChina(lng, lat)) { - return [lng, lat]; - } - let dlat = _transformlat(lng - 105.0, lat - 35.0); - let dlng = _transformlng(lng - 105.0, lat - 35.0); - const radlat = (lat / 180.0) * PI; - let magic = Math.sin(radlat); - magic = 1 - ee * magic * magic; - const sqrtmagic = Math.sqrt(magic); - dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI); - dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI); - const mglat = lat + dlat; - const mglng = lng + dlng; - return [mglng, mglat]; - } - const outOfChina = function (lng, lat) { - return (lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271 || false); - }; - const _transformlat = function (lng, lat) { - let ret = -100.0 + - 2.0 * lng + - 3.0 * lat + - 0.2 * lat * lat + - 0.1 * lng * lat + - 0.2 * Math.sqrt(Math.abs(lng)); - ret += - ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * - 2.0) / - 3.0; - ret += - ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / - 3.0; - ret += - ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * - 2.0) / - 3.0; - return ret; - }; - const _transformlng = function (lng, lat) { - let ret = 300.0 + - lng + - 2.0 * lat + - 0.1 * lng * lng + - 0.1 * lng * lat + - 0.1 * Math.sqrt(Math.abs(lng)); - ret += - ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * - 2.0) / - 3.0; - ret += - ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / - 3.0; - ret += - ((150.0 * Math.sin((lng / 12.0) * PI) + - 300.0 * Math.sin((lng / 30.0) * PI)) * - 2.0) / - 3.0; - return ret; - }; - - function getLocationSuccess(type, position, resolve) { - const coords = position.coords; - if (type !== position.coordsType) { - let coordArray; - if (type === 'wgs84') { - coordArray = gcj02towgs84(coords.longitude, coords.latitude); - } - else if (type === 'gcj02') { - coordArray = wgs84togcj02(coords.longitude, coords.latitude); - } - if (coordArray) { - coords.longitude = coordArray[0]; - coords.latitude = coordArray[1]; - } - } - resolve({ - type, - altitude: coords.altitude || 0, - latitude: coords.latitude, - longitude: coords.longitude, - speed: coords.speed, - accuracy: coords.accuracy, - address: position.address, - errMsg: 'getLocation:ok', - }); - } - const getLocation = defineAsyncApi(API_GET_LOCATION, ({ type = 'wgs84', geocode = false, altitude = false, highAccuracyExpireTime, isHighAccuracy = false, }, { resolve, reject }) => { - plus.geolocation.getCurrentPosition((position) => { - getLocationSuccess(type, position, resolve); - }, (e) => { - // 坐标地址解析失败 - if (e.code === 1501) { - getLocationSuccess(type, e, resolve); - return; - } - reject('getLocation:fail ' + e.message); - }, { - geocode: geocode, - enableHighAccuracy: isHighAccuracy || altitude, - timeout: highAccuracyExpireTime, - coordsType: type, - }); - }, GetLocationProtocol, GetLocationOptions); - - const chooseLocation = defineAsyncApi(API_CHOOSE_LOCATION, (options, { resolve, reject }) => { - const statusBarStyle = getStatusBarStyle(); - const isDark = statusBarStyle !== 'light'; - let result; - const page = showPage({ - url: '__uniappchooselocation', - data: options, - style: { - // @ts-expect-error - animationType: options.animationType || 'slide-in-bottom', - // @ts-expect-error - titleNView: false, - popGesture: 'close', - scrollIndicator: 'none', - }, - onMessage({ event, detail, }) { - if (event === 'selected') { - result = detail; - } - }, - onClose() { - if (isDark) { - plus.navigator.setStatusBarStyle('dark'); - } - result ? resolve(result) : reject('cancel'); - }, - }); - if (isDark) { - plus.navigator.setStatusBarStyle('light'); - page.webview.addEventListener('popGesture', ({ type, result }) => { - if (type === 'start') { - plus.navigator.setStatusBarStyle('dark'); - } - else if (type === 'end' && !result) { - plus.navigator.setStatusBarStyle('light'); - } - }); - } - }, ChooseLocationProtocol); - - const openLocation = defineAsyncApi(API_OPEN_LOCATION, (data, { resolve, reject }) => { - showPage({ - url: '__uniappopenlocation', - data, - style: { - titleNView: { - type: 'transparent', - }, - popGesture: 'close', - backButtonAutoControl: 'close', - }, - onClose() { - reject('cancel'); - }, - }); - return resolve(); - }, OpenLocationProtocol, OpenLocationOptions); - - const showModal = defineAsyncApi(API_SHOW_MODAL, ({ title = '', content = '', showCancel = true, cancelText, cancelColor, confirmText, confirmColor, editable = false, placeholderText = '', } = {}, { resolve }) => { - const buttons = showCancel ? [cancelText, confirmText] : [confirmText]; - const tip = editable ? placeholderText : buttons; - content = content || ' '; - plus.nativeUI[editable ? 'prompt' : 'confirm'](content, (e) => { - if (showCancel) { - const isConfirm = e.index === 1; - const res = { - confirm: isConfirm, - cancel: e.index === 0 || e.index === -1, - }; - isConfirm && editable && (res.content = e.value); - resolve(res); - } - else { - const res = { - confirm: e.index === 0, - cancel: false, - }; - editable && (res.content = e.value); - resolve(res); - } - }, title, tip, buttons); - }, ShowModalProtocol, ShowModalOptions); - - const showActionSheet = defineAsyncApi(API_SHOW_ACTION_SHEET, ({ itemList = [], itemColor = '#000000', title = '', alertText = '', popover, }, { resolve, reject }) => { - initI18nShowActionSheetMsgsOnce(); - const { t } = useI18n(); - const options = { - title, - cancel: t('uni.showActionSheet.cancel'), - buttons: itemList.map((item) => ({ - title: item, - color: itemColor, - })), - }; - if (title || alertText) { - options.title = alertText || title; - } - plus.nativeUI.actionSheet(shared.extend(options, { - popover, - }), (e) => { - if (e.index > 0) { - resolve({ - tapIndex: e.index - 1, - }); - } - else { - reject('showActionSheet:fail cancel'); - } - }); - }, ShowActionSheetProtocol, ShowActionSheetOptions); - - let toast; - let isShowToast = false; - let toastType = ''; - let timeout; - const showLoading = defineAsyncApi(API_SHOW_LOADING, (args, callbacks) => _showToast(shared.extend({}, args, { - type: 'loading', - icon: 'loading', - }), callbacks), ShowLoadingProtocol, ShowLoadingOptions); - const _showToast = ({ title = '', icon = 'success', image = '', duration = 1500, mask = false, position, type = 'toast', style, }, { resolve, reject }) => { - hide(''); - toastType = type; - if (['top', 'center', 'bottom'].includes(String(position))) { - // 仅可以关闭 richtext 类型,但 iOS 部分情况换行显示有问题 - plus.nativeUI.toast(title, { - verticalAlign: position, - }); - isShowToast = true; - } - else { - if (icon && !~['success', 'loading', 'error', 'none'].indexOf(icon)) { - icon = 'success'; - } - const waitingOptions = { - modal: mask, - back: 'transmit', - padding: '10px', - size: '16px', // 固定字体大小 - }; - if (!image && (!icon || icon === 'none')) { - // 无图 - // waitingOptions.width = '120px' - // waitingOptions.height = '40px' - waitingOptions.loading = { - display: 'none', - }; - } - else { - waitingOptions.width = '140px'; - waitingOptions.height = '112px'; - } - if (image) { - waitingOptions.loading = { - display: 'block', - height: '55px', - icon: image, - interval: duration, - }; - } - else { - if (['success', 'error'].indexOf(icon) !== -1) { - waitingOptions.loading = { - display: 'block', - height: '55px', - icon: icon === 'success' ? '__uniappsuccess.png' : '__uniapperror.png', - interval: duration, - }; - } - } - try { - toast = plus.nativeUI.showWaiting(title, shared.extend(waitingOptions, style)); - } - catch (error) { - reject(`${error}`); - } - } - if (toastType === 'toast') - timeout = setTimeout(() => { - hide(''); - }, duration); - return resolve(); - }; - const showToast = defineAsyncApi(API_SHOW_TOAST, _showToast, ShowToastProtocol, ShowToastOptions); - const hideToast = defineAsyncApi(API_HIDE_TOAST, (_, callbacks) => hide('toast', callbacks)); - const hideLoading = defineAsyncApi(API_HIDE_LOADING, (_, callbacks) => hide('loading', callbacks)); - function hide(type = 'toast', callbacks) { - if (type && type !== toastType) { - // 应该不需要失败回调,在页面后退时,会主动 hideToast 和 hideLoading,如果 reject 会出异常。 - return callbacks && callbacks.resolve(); - } - if (timeout) { - clearTimeout(timeout); - timeout = null; - } - if (isShowToast) { - plus.nativeUI.closeToast(); - } - else if (toast && toast.close) { - toast.close(); - } - toast = null; - isShowToast = false; - toastType = ''; - return callbacks && callbacks.resolve(); - } + defaultFontSize: 16, + viewport: plus_.screen.resolutionWidth, + }, + }; + style = extend(defaultStyle, style); + const page = plus_.webview.create('', pageId, style, { + extras: { + from: getPageId(), + runtime: getRuntime(), + data, + useGlobalEvent: !BroadcastChannel_, + }, + }); + page.addEventListener('close', onClose); + addEventListener(pageId, (message) => { + if (typeof onMessage === 'function') { + onMessage(message.data); + } + if (!message.keep) { + page.close('auto'); + } + }); + page.show(style.animationType, style.animationDuration); + return new Page(page); +} - const startPullDownRefresh = defineAsyncApi(API_START_PULL_DOWN_REFRESH, (_args, { resolve, reject }) => { - let webview = getPullDownRefreshWebview(); - if (webview) { - webview.endPullToRefresh(); - } - webview = getCurrentWebview(); - if (!webview) { - return reject(); - } - webview.beginPullToRefresh(); - setPullDownRefreshWebview(webview); - resolve(); - }); - - const stopPullDownRefresh = defineAsyncApi(API_STOP_PULL_DOWN_REFRESH, (_args, { resolve, reject }) => { - const webview = getPullDownRefreshWebview() || getCurrentWebview(); - if (!webview) { - return reject(); - } - webview.endPullToRefresh(); - setPullDownRefreshWebview(null); - resolve(); - }); - - const loadFontFace = defineAsyncApi(API_LOAD_FONT_FACE, (options, { resolve, reject }) => { - const pageId = getPageIdByVm(getCurrentPageVm()); - UniServiceJSBridge.invokeViewMethod(API_LOAD_FONT_FACE, options, pageId, (err) => { - if (err) { - reject(err); - } - else { - resolve(); - } - }); - }, LoadFontFaceProtocol); - - const pageScrollTo = defineAsyncApi(API_PAGE_SCROLL_TO, (options, { resolve }) => { - const pageId = getPageIdByVm(getCurrentPageVm()); - UniServiceJSBridge.invokeViewMethod(API_PAGE_SCROLL_TO, options, pageId, resolve); - }, PageScrollToProtocol, PageScrollToOptions); - - const setNavigationBarTitle = defineAsyncApi(API_SET_NAVIGATION_BAR_TITLE, ({ __page__, title }, { resolve, reject }) => { - const webview = getWebview(__page__); - if (webview) { - const style = webview.getStyle(); - if (style && style.titleNView) { - webview.setStyle({ - titleNView: { - titleText: title, - }, - }); - } - resolve(); - } - else { - reject(); - } - }, SetNavigationBarTitleProtocol); - const showNavigationBarLoading = defineAsyncApi(API_SHOW_NAVIGATION_BAR_LOADING, (_, { resolve }) => { - plus.nativeUI.showWaiting('', { - modal: false, - }); - resolve(); - }); - const hideNavigationBarLoading = defineAsyncApi(API_HIDE_NAVIGATION_BAR_LOADING, (_, { resolve }) => { - plus.nativeUI.closeWaiting(); - resolve(); - }); - function setPageStatusBarStyle(statusBarStyle) { - const pages = getCurrentPages(); - if (!pages.length) { - return; - } - // 框架内部页面跳转会从这里获取style配置 - pages[pages.length - 1].$page.statusBarStyle = statusBarStyle; - } - const setNavigationBarColor = defineAsyncApi(API_SET_NAVIGATION_BAR_COLOR, ({ __page__, frontColor, backgroundColor }, { resolve, reject }) => { - const webview = getWebview(__page__); - if (webview) { - const styles = {}; - if (frontColor) { - styles.titleColor = frontColor; - } - if (backgroundColor) { - styles.backgroundColor = backgroundColor; - } - const statusBarStyle = frontColor === '#000000' ? 'dark' : 'light'; - plus.navigator.setStatusBarStyle(statusBarStyle); - // 用户调用api时同时改变当前页配置,这样在系统调用设置时,可以避免覆盖用户设置 - setPageStatusBarStyle(statusBarStyle); - const style = webview.getStyle(); - if (style && style.titleNView) { - if (style.titleNView.autoBackButton) { - styles.backButton = styles.backButton || {}; - styles.backButton.color = frontColor; - } - webview.setStyle({ - titleNView: styles, - }); - } - resolve(); - } - else { - reject(); - } - }, SetNavigationBarColorProtocol, SetNavigationBarColorOptions); - - const setTabBarBadge = defineAsyncApi(API_SET_TAB_BAR_BADGE, ({ index, text }, { resolve, reject }) => { - tabBar$1.setTabBarBadge('text', index, text); - resolve(); - }, SetTabBarBadgeProtocol, SetTabBarBadgeOptions); - const setTabBarItem = defineAsyncApi(API_SET_TAB_BAR_ITEM, ({ index, text, iconPath, selectedIconPath, pagePath, visible }, { resolve, reject }) => { - tabBar$1.setTabBarItem(index, text, iconPath, selectedIconPath, visible); - const route = pagePath && __uniRoutes.find(({ path }) => path === pagePath); - if (route) { - const meta = route.meta; - meta.isTabBar = true; - meta.tabBarIndex = index; - meta.isQuit = true; - const tabBar = __uniConfig.tabBar; - if (tabBar && tabBar.list && tabBar.list[index] && pagePath) { - tabBar.list[index].pagePath = pagePath.startsWith('/') - ? pagePath.substring(1) - : pagePath; - } - } - resolve(); - }, SetTabBarItemProtocol, SetTabBarItemOptions); - const setTabBarStyle = defineAsyncApi(API_SET_TAB_BAR_STYLE, (style = {}, { resolve, reject }) => { - if (!isTabBarPage()) { - return reject('not TabBar page'); - } - const borderStyles = { - black: 'rgba(0,0,0,0.4)', - white: 'rgba(255,255,255,0.4)', - }; - const borderStyle = style.borderStyle; - if (borderStyle && borderStyle in borderStyles) { - style.borderStyle = borderStyles[borderStyle]; - } - tabBar$1.setTabBarStyle(style); - resolve(); - }, SetTabBarStyleProtocol, SetTabBarStyleOptions); - const hideTabBar = defineAsyncApi(API_HIDE_TAB_BAR, (args, { resolve, reject }) => { - const animation = args && args.animation; - if (!isTabBarPage()) { - return reject('not TabBar page'); - } - tabBar$1.hideTabBar(Boolean(animation)); - resolve(); - }, HideTabBarProtocol); - const showTabBar = defineAsyncApi(API_SHOW_TAB_BAR, (args, { resolve, reject }) => { - const animation = args && args.animation; - if (!isTabBarPage()) { - return reject('not TabBar page'); - } - tabBar$1.showTabBar(Boolean(animation)); - resolve(); - }, ShowTabBarProtocol); - const showTabBarRedDot = defineAsyncApi(API_SHOW_TAB_BAR_RED_DOT, ({ index }, { resolve, reject }) => { - tabBar$1.setTabBarBadge('redDot', index); - resolve(); - }, ShowTabBarRedDotProtocol, ShowTabBarRedDotOptions); - const setTabBarBadgeNone = (index) => tabBar$1.setTabBarBadge('none', index); - const removeTabBarBadge = defineAsyncApi(API_REMOVE_TAB_BAR_BADGE, ({ index }, { resolve, reject }) => { - setTabBarBadgeNone(index); - resolve(); - }, RemoveTabBarBadgeProtocol, RemoveTabBarBadgeOptions); - const hideTabBarRedDot = defineAsyncApi(API_HIDE_TAB_BAR_RED_DOT, ({ index }, { resolve, reject }) => { - setTabBarBadgeNone(index); - resolve(); - }, HideTabBarRedDotProtocol, HideTabBarRedDotOptions); - - const VD_SYNC = 'vdSync'; - const APP_SERVICE_ID = '__uniapp__service'; - const ON_WEBVIEW_READY = 'onWebviewReady'; - const ACTION_TYPE_DICT = 0; - const WEBVIEW_INSERTED = 'webviewInserted'; - const WEBVIEW_REMOVED = 'webviewRemoved'; - - const EVENT_TYPE_NAME = 'UniAppSubNVue'; - class SubNvue { - constructor(id, isSub) { - this.callbacks = []; - const webview = (this.webview = plus.webview.getWebviewById(id)); - this.isSub = isSub || false; - if (webview.__uniapp_mask_id) { - const maskWebview = (this.maskWebview = - webview.__uniapp_mask_id === '0' - ? { - setStyle({ mask }) { - requireNativePlugin('uni-tabview').setMask({ - color: mask, - }); - }, - } - : plus.webview.getWebviewById(webview.__uniapp_mask_id)); - const closeMask = function () { - maskWebview.setStyle({ - mask: 'none', - }); - }; - webview.addEventListener('hide', closeMask); - webview.addEventListener('close', closeMask); - } - } - show(...args) { - if (this.maskWebview) { - const maskColor = this.webview.__uniapp_mask; - this.maskWebview.setStyle({ - mask: maskColor, - }); - } - this.webview.show(...args); - } - hide(...args) { - this.webview.hide(...args); - } - setStyle(style) { - this.webview.setStyle(style); - } - initMessage() { - if (this.messageReady) { - return; - } - this.messageReady = true; - const listener = (event) => { - if (event.data && event.data.type === EVENT_TYPE_NAME) { - const target = event.data.target; - if (target.id === this.webview.id && target.isSub === this.isSub) { - this.callbacks.forEach((callback) => { - callback({ - origin: this.webview.__uniapp_host, - data: event.data.data, - }); - }); - } - } - }; - const globalEvent = requireNativePlugin('globalEvent'); - globalEvent.addEventListener('plusMessage', listener); - this.webview.addEventListener('close', () => { - // TODO 暂时仅清空回调 - this.callbacks.length = 0; - // globalEvent.removeEventListener('plusMessage', listener) - }); - } - postMessage(data) { - const webviewExt = plus.webview; - webviewExt.postMessageToUniNView({ - type: EVENT_TYPE_NAME, - data, - target: { - id: this.webview.id, - isSub: !this.isSub, - }, - }, APP_SERVICE_ID); - } - onMessage(callback) { - this.initMessage(); - this.callbacks.push(callback); - } - } - const getSubNVueById = function (id, isSub) { - // TODO 暂时通过 isSub 区分来自 subNVue 页面 - return new SubNvue(id, isSub); - }; - - let lastStatusBarStyle; - let oldSetStatusBarStyle = plus.navigator.setStatusBarStyle; - function restoreOldSetStatusBarStyle(setStatusBarStyle) { - oldSetStatusBarStyle = setStatusBarStyle; - } - function newSetStatusBarStyle(style) { - lastStatusBarStyle = style; - oldSetStatusBarStyle(style); - } - plus.navigator.setStatusBarStyle = newSetStatusBarStyle; - function setStatusBarStyle(statusBarStyle) { - if (!statusBarStyle) { - const page = getCurrentPage(); - if (!page) { - return; - } - statusBarStyle = page.$page.statusBarStyle; - if (!statusBarStyle || statusBarStyle === lastStatusBarStyle) { - return; - } - } - if (statusBarStyle === lastStatusBarStyle) { - return; - } - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('setStatusBarStyle', statusBarStyle)); - } - lastStatusBarStyle = statusBarStyle; - plus.navigator.setStatusBarStyle(statusBarStyle); - } +const scanCode = defineAsyncApi(API_SCAN_CODE, (options, { resolve, reject }) => { + initI18nScanCodeMsgsOnce(); + const { t } = useI18n(); + const statusBarStyle = getStatusBarStyle(); + const isDark = statusBarStyle !== 'light'; + let result; + let success = false; + const page = showPage({ + url: '__uniappscan', + data: Object.assign({}, options, { + messages: { + fail: t('uni.scanCode.fail'), + 'flash.on': t('uni.scanCode.flash.on'), + 'flash.off': t('uni.scanCode.flash.off'), + }, + }), + style: { + // @ts-expect-error + animationType: options.animationType || 'pop-in', + titleNView: { + autoBackButton: true, + type: 'float', + // @ts-expect-error + titleText: options.titleText || t('uni.scanCode.title'), + titleColor: '#ffffff', + backgroundColor: 'rgba(0,0,0,0)', + buttons: !options.onlyFromCamera + ? [ + { + // @ts-expect-error + text: options.albumText || t('uni.scanCode.album'), + fontSize: '17px', + width: '60px', + onclick: () => { + page.sendMessage({ + type: 'gallery', + }); + }, + }, + ] + : [], + }, + popGesture: 'close', + background: '#000000', + backButtonAutoControl: 'close', + }, + onMessage({ event, detail, }) { + result = detail; + success = event === 'marked'; + }, + onClose() { + if (isDark) { + plus.navigator.setStatusBarStyle('dark'); + } + result + ? success + ? (delete result.message, resolve(result)) + : reject(result.message) + : reject('cancel'); + }, + }); + if (isDark) { + plus.navigator.setStatusBarStyle('light'); + page.webview.addEventListener('popGesture', ({ type, result }) => { + if (type === 'start') { + plus.navigator.setStatusBarStyle('dark'); + } + else if (type === 'end' && !result) { + plus.navigator.setStatusBarStyle('light'); + } + }); + } +}, ScanCodeProtocol); + +const onThemeChange = defineOnApi(ON_THEME_CHANGE, () => { + UniServiceJSBridge.on(ON_THEME_CHANGE, (res) => { + UniServiceJSBridge.invokeOnCallback(ON_THEME_CHANGE, res); + }); +}); + +const getScreenBrightness = defineAsyncApi(API_GET_SCREEN_BRIGHTNESS, (_, { resolve }) => { + const value = plus.screen.getBrightness(false); + resolve({ value }); +}); +const setScreenBrightness = defineAsyncApi(API_SET_SCREEN_BRIGHTNESS, (options, { resolve }) => { + plus.screen.setBrightness(options.value, false); + resolve(); +}); +const setKeepScreenOn = defineAsyncApi(API_SET_KEEP_SCREEN_ON, (options, { resolve }) => { + plus.device.setWakelock(!!options.keepScreenOn); + resolve(); +}); + +const getImageInfo = defineAsyncApi(API_GET_IMAGE_INFO, (options, { resolve, reject }) => { + const path = TEMP_PATH + '/download/'; + plus.io.getImageInfo(extend(options, { + savePath: path, + filename: path, + success: warpPlusSuccessCallback(resolve), + fail: warpPlusErrorCallback(reject), + })); +}, GetImageInfoProtocol, GetImageInfoOptions); + +const getVideoInfo = defineAsyncApi(API_GET_VIDEO_INFO, (options, { resolve, reject }) => { + plus.io.getVideoInfo({ + filePath: options.src, + success: (data) => { + return { + orientation: data.orientation, + type: data.type, + duration: data.duration, + size: data.size, + height: data.height, + width: data.width, + fps: data.fps || 30, + bitrate: data.bitrate, + }; + }, + fail: warpPlusErrorCallback(reject), + }); +}, GetVideoInfoProtocol, GetVideoInfoOptions); + +const previewImage = defineAsyncApi(API_PREVIEW_IMAGE, ({ current = 0, indicator = 'number', loop = false, urls, longPressActions }, { resolve, reject }) => { + initI18nPreviewImageMsgsOnce(); + const { t } = useI18n(); + urls = urls.map((url) => getRealPath(url)); + const index = Number(current); + if (isNaN(index)) { + current = urls.indexOf(getRealPath(current)); + current = current < 0 ? 0 : current; + } + else { + current = index; + } + plus.nativeUI.previewImage(urls, { + current, + indicator, + loop, + onLongPress: function (res) { + let itemList = []; + let itemColor = ''; + const hasLongPressActions = longPressActions && isPlainObject(longPressActions); + if (!hasLongPressActions) { + itemList = [t('uni.previewImage.button.save')]; + itemColor = '#000000'; + } + else { + itemList = longPressActions.itemList + ? longPressActions.itemList + : []; + itemColor = longPressActions.itemColor + ? longPressActions.itemColor + : '#000000'; + } + const options = { + buttons: itemList.map((item) => ({ + title: item, + color: itemColor, + })), + cancel: t('uni.previewImage.cancel'), + }; + plus.nativeUI.actionSheet(options, (e) => { + if (e.index > 0) { + if (hasLongPressActions) { + typeof longPressActions.success === 'function' && + longPressActions.success({ + tapIndex: e.index - 1, + index: res.index, + }); + return; + } + plus.gallery.save(res.url, () => { + plus.nativeUI.toast(t('uni.previewImage.save.success')); + }, function () { + plus.nativeUI.toast(t('uni.previewImage.save.fail')); + }); + } + else if (hasLongPressActions) { + typeof longPressActions.fail === 'function' && + longPressActions.fail({ + errMsg: 'showActionSheet:fail cancel', + }); + } + }); + }, + }); + resolve(); +}, PreviewImageProtocol, PreviewImageOptions); +const closePreviewImage = defineAsyncApi(API_CLOSE_PREVIEW_IMAGE, (_, { resolve, reject }) => { + try { + // @ts-expect-error + plus.nativeUI.closePreviewImage(); + resolve(); + } + catch (error) { + reject(); + } +}); + +let recorder; +let recording = false; +let recordTimeout; +const publishRecorderStateChange = (state, res = {}) => { + onRecorderStateChange(extend({ + state, + }, res)); +}; +const Recorder = { + start({ duration = 60000, sampleRate, numberOfChannels, encodeBitRate, format = 'mp3', frameSize, + // audioSource = 'auto', + }) { + if (recording) { + return publishRecorderStateChange('start'); + } + recorder = plus.audio.getRecorder(); + recorder.record({ + format, + samplerate: sampleRate ? String(sampleRate) : '', + filename: TEMP_PATH + '/recorder/', + }, (res) => publishRecorderStateChange('stop', { + tempFilePath: res, + }), (err) => publishRecorderStateChange('error', { + errMsg: err.message, + })); + recordTimeout = setTimeout(() => { + Recorder.stop(); + }, duration); + publishRecorderStateChange('start'); + recording = true; + }, + stop() { + if (recording) { + recorder.stop(); + recording = false; + recordTimeout && clearTimeout(recordTimeout); + } + }, + pause() { + if (recording) { + publishRecorderStateChange('error', { + errMsg: 'Unsupported operation: pause', + }); + } + }, + resume() { + if (recording) { + publishRecorderStateChange('error', { + errMsg: 'Unsupported operation: resume', + }); + } + }, +}; +const callbacks$1 = { + pause: null, + resume: null, + start: null, + stop: null, + error: null, +}; +function onRecorderStateChange(res) { + const state = res.state; + delete res.state; + delete res.errMsg; + if (state && typeof callbacks$1[state] === 'function') { + callbacks$1[state](res); + } +} +class RecorderManager { + constructor() { } + onError(callback) { + callbacks$1.error = callback; + } + onFrameRecorded(callback) { } + onInterruptionBegin(callback) { } + onInterruptionEnd(callback) { } + onPause(callback) { + callbacks$1.pause = callback; + } + onResume(callback) { + callbacks$1.resume = callback; + } + onStart(callback) { + callbacks$1.start = callback; + } + onStop(callback) { + callbacks$1.stop = callback; + } + pause() { + Recorder.pause(); + } + resume() { + Recorder.resume(); + } + start(options) { + Recorder.start(options); + } + stop() { + Recorder.stop(); + } +} +let recorderManager; +const getRecorderManager = defineSyncApi(API_GET_RECORDER_MANAGER, () => recorderManager || (recorderManager = new RecorderManager())); + +const saveVideoToPhotosAlbum = defineAsyncApi(API_SAVE_VIDEO_TO_PHOTOS_ALBUM, (options, { resolve, reject }) => { + plus.gallery.save(options.filePath, warpPlusSuccessCallback(resolve), warpPlusErrorCallback(reject)); +}, SaveVideoToPhotosAlbumProtocol, SaveVideoToPhotosAlbumOptions); + +const saveImageToPhotosAlbum = defineAsyncApi(API_SAVE_IMAGE_TO_PHOTOS_ALBUM, (options, { resolve, reject }) => { + plus.gallery.save(options.filePath, warpPlusSuccessCallback(resolve), warpPlusErrorCallback(reject)); +}, SaveImageToPhotosAlbumProtocol, SaveImageToPhotosAlbumOptions); + +const compressImage = defineAsyncApi(API_COMPRESS_IMAGE, (options, { resolve, reject }) => { + const dst = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(options.src)}`; + plus.zip.compressImage(extend({}, options, { + dst, + }), () => { + resolve({ + tempFilePath: dst, + }); + }, reject); +}, CompressImageProtocol, CompressImageOptions); + +const compressVideo = defineAsyncApi(API_COMPRESS_VIDEO, (options, { resolve, reject }) => { + const filename = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(options.src)}`; + plus.zip.compressVideo(extend({}, options, { + filename, + }), () => { + resolve({ + tempFilePath: filename, + }); + }, reject); +}, CompressVideoProtocol, CompressVideoOptions); + +/** + * 获取文件信息 + * @param {string} filePath 文件路径 + * @returns {Promise} 文件信息Promise + */ +function getFileInfo(filePath) { + return new Promise((resolve, reject) => { + plus.io.resolveLocalFileSystemURL(filePath, function (entry) { + entry.getMetadata(resolve, reject, false); + }, reject); + }); +} +const chooseImage = defineAsyncApi(API_CHOOSE_IMAGE, ({ count, sizeType, sourceType, crop } = {}, { resolve, reject }) => { + initI18nChooseImageMsgsOnce(); + const { t } = useI18n(); + const errorCallback = warpPlusErrorCallback(reject); + function successCallback(paths) { + const tempFiles = []; + const tempFilePaths = []; + Promise.all(paths.map((path) => getFileInfo(path))) + .then((filesInfo) => { + filesInfo.forEach((file, index) => { + const path = paths[index]; + tempFilePaths.push(path); + tempFiles.push({ path, size: file.size }); + }); + resolve({ + tempFilePaths, + tempFiles, + }); + }) + .catch(errorCallback); + } + function openCamera() { + const camera = plus.camera.getCamera(); + camera.captureImage((path) => successCallback([path]), errorCallback, { + filename: TEMP_PATH + '/camera/', + resolution: 'high', + crop, + // @ts-expect-error + sizeType, + }); + } + function openAlbum() { + // @ts-ignore 5+此API分单选和多选,多选返回files:string[] + plus.gallery.pick(({ files }) => successCallback(files), errorCallback, { + maximum: count, + multiple: true, + system: false, + filename: TEMP_PATH + '/gallery/', + permissionAlert: true, + crop, + // @ts-expect-error + sizeType, + }); + } + if (sourceType.length === 1) { + if (sourceType.includes('album')) { + openAlbum(); + return; + } + else if (sourceType.includes('camera')) { + openCamera(); + return; + } + } + plus.nativeUI.actionSheet({ + cancel: t('uni.chooseImage.cancel'), + buttons: [ + { + title: t('uni.chooseImage.sourceType.camera'), + }, + { + title: t('uni.chooseImage.sourceType.album'), + }, + ], + }, (e) => { + switch (e.index) { + case 1: + openCamera(); + break; + case 2: + openAlbum(); + break; + default: + errorCallback(); + break; + } + }); +}, ChooseImageProtocol, ChooseImageOptions); + +const chooseVideo = defineAsyncApi(API_CHOOSE_VIDEO, ({ sourceType, compressed, maxDuration, camera }, { resolve, reject }) => { + initI18nChooseVideoMsgsOnce(); + const { t } = useI18n(); + const errorCallback = warpPlusErrorCallback(reject); + function successCallback(tempFilePath) { + plus.io.getVideoInfo({ + filePath: tempFilePath, + success(videoInfo) { + const result = { + errMsg: 'chooseVideo:ok', + tempFilePath: tempFilePath, + size: videoInfo.size, + duration: videoInfo.duration, + width: videoInfo.width, + height: videoInfo.height, + }; + // @ts-expect-error tempFile、name 仅H5支持 + resolve(result); + }, + fail: errorCallback, + }); + } + function openAlbum() { + plus.gallery.pick( + // @ts-ignore 5+此API分单选和多选,多选返回files:string[] + ({ files }) => successCallback(files[0]), errorCallback, { + filter: 'video', + system: false, + // 不启用 multiple 时 system 无效 + multiple: true, + maximum: 1, + filename: TEMP_PATH + '/gallery/', + permissionAlert: true, + // @ts-expect-error 新增参数,用于视频压缩 + videoCompress: compressed, + }); + } + function openCamera() { + const plusCamera = plus.camera.getCamera(); + plusCamera.startVideoCapture(successCallback, errorCallback, { + index: camera === 'front' ? '2' : '1', + videoMaximumDuration: maxDuration, + filename: TEMP_PATH + '/camera/', + // @ts-expect-error 新增参数,用于视频压缩 + videoCompress: compressed, + }); + } + if (sourceType.length === 1) { + if (sourceType.includes('album')) { + openAlbum(); + return; + } + else if (sourceType.includes('camera')) { + openCamera(); + return; + } + } + plus.nativeUI.actionSheet({ + cancel: t('uni.chooseVideo.cancel'), + buttons: [ + { + title: t('uni.chooseVideo.sourceType.camera'), + }, + { + title: t('uni.chooseVideo.sourceType.album'), + }, + ], + }, (e) => { + switch (e.index) { + case 1: + openCamera(); + break; + case 2: + openAlbum(); + break; + default: + errorCallback(); + break; + } + }); +}, ChooseVideoProtocol, ChooseVideoOptions); + +const showKeyboard = defineAsyncApi(API_SHOW_KEYBOARD, (_, { resolve }) => { + plus.key.showSoftKeybord(); + resolve(); +}); +const hideKeyboard = defineAsyncApi(API_HIDE_KEYBOARD, (_, { resolve }) => { + plus.key.hideSoftKeybord(); + resolve(); +}); +function onKeyboardHeightChangeCallback(res) { + UniServiceJSBridge.invokeOnCallback(ON_KEYBOARD_HEIGHT_CHANGE, res); +} +const onKeyboardHeightChange = defineOnApi(ON_KEYBOARD_HEIGHT_CHANGE, () => { + UniServiceJSBridge.on(ON_KEYBOARD_HEIGHT_CHANGE, onKeyboardHeightChangeCallback); +}); +const offKeyboardHeightChange = defineOffApi(ON_KEYBOARD_HEIGHT_CHANGE, () => { + UniServiceJSBridge.off(ON_KEYBOARD_HEIGHT_CHANGE, onKeyboardHeightChangeCallback); +}); + +class DownloadTask { + constructor(downloader) { + this._callbacks = []; + this._downloader = downloader; + downloader.addEventListener('statechanged', (download, status) => { + if (download.downloadedSize && download.totalSize) { + this._callbacks.forEach((callback) => { + callback({ + progress: Math.round((download.downloadedSize / download.totalSize) * 100), + totalBytesWritten: download.downloadedSize, + totalBytesExpectedToWrite: download.totalSize, + }); + }); + } + }); + } + abort() { + this._downloader.abort(); + } + onProgressUpdate(callback) { + if (typeof callback !== 'function') { + return; + } + this._callbacks.push(callback); + } + offProgressUpdate(callback) { + const index = this._callbacks.indexOf(callback); + if (index >= 0) { + this._callbacks.splice(index, 1); + } + } + onHeadersReceived(callback) { + throw new Error('Method not implemented.'); + } + offHeadersReceived(callback) { + throw new Error('Method not implemented.'); + } +} +const downloadFile = defineTaskApi(API_DOWNLOAD_FILE, ({ url, header, timeout }, { resolve, reject }) => { + timeout = + (timeout || + (__uniConfig.networkTimeout && __uniConfig.networkTimeout.request) || + 60 * 1000) / 1000; + const downloader = plus.downloader.createDownload(url, { + timeout, + filename: TEMP_PATH + '/download/', + // 需要与其它平台上的表现保持一致,不走重试的逻辑。 + retry: 0, + retryInterval: 0, + }, (download, statusCode) => { + if (statusCode) { + resolve({ + tempFilePath: download.filename, + statusCode, + }); + } + else { + reject(`statusCode: ${statusCode}`); + } + }); + const downloadTask = new DownloadTask(downloader); + for (const name in header) { + if (hasOwn$1(header, name)) { + downloader.setRequestHeader(name, header[name]); + } + } + downloader.start(); + return downloadTask; +}, DownloadFileProtocol, DownloadFileOptions); + +const cookiesParse = (header) => { + let cookiesStr = header['Set-Cookie'] || header['set-cookie']; + let cookiesArr = []; + if (!cookiesStr) { + return []; + } + if (cookiesStr[0] === '[' && cookiesStr[cookiesStr.length - 1] === ']') { + cookiesStr = cookiesStr.slice(1, -1); + } + const handleCookiesArr = cookiesStr.split(';'); + for (let i = 0; i < handleCookiesArr.length; i++) { + if (handleCookiesArr[i].indexOf('Expires=') !== -1 || + handleCookiesArr[i].indexOf('expires=') !== -1) { + cookiesArr.push(handleCookiesArr[i].replace(',', '')); + } + else { + cookiesArr.push(handleCookiesArr[i]); + } + } + cookiesArr = cookiesArr.join(';').split(','); + return cookiesArr; +}; +function formatResponse(res, args) { + if (typeof res.data === 'string' && res.data.charCodeAt(0) === 65279) { + res.data = res.data.substr(1); + } + res.statusCode = parseInt(String(res.statusCode), 10); + if (isPlainObject(res.header)) { + res.header = Object.keys(res.header).reduce(function (ret, key) { + const value = res.header[key]; + if (Array.isArray(value)) { + ret[key] = value.join(','); + } + else if (typeof value === 'string') { + ret[key] = value; + } + return ret; + }, {}); + } + if (args.dataType && args.dataType.toLowerCase() === 'json') { + try { + res.data = JSON.parse(res.data); + } + catch (e) { } + } + return res; +} +/** + * 请求任务类 + */ +class RequestTask { + constructor(requestTask) { + this._requestTask = requestTask; + } + abort() { + this._requestTask.abort(); + } + offHeadersReceived() { } + onHeadersReceived() { } +} +const request = defineTaskApi(API_REQUEST, (args, { resolve, reject }) => { + let { header, method, data, timeout, url, responseType, sslVerify, firstIpv4, + // @ts-ignore tls 缺少 types 类型 + tls, } = args; + let contentType; + for (const name in header) { + if (name.toLowerCase() === 'content-type') { + contentType = header[name]; + break; + } + } + if (method !== 'GET' && + contentType.indexOf('application/json') === 0 && + isPlainObject(data)) { + data = JSON.stringify(data); + } + const stream = requireNativePlugin('stream'); + const headers = {}; + let abortTimeout; + let aborted; + let hasContentType = false; + for (const name in header) { + if (!hasContentType && name.toLowerCase() === 'content-type') { + hasContentType = true; + headers['Content-Type'] = header[name]; + // TODO 需要重构 + if (method !== 'GET' && + header[name].indexOf('application/x-www-form-urlencoded') === 0 && + typeof data !== 'string' && + !(data instanceof ArrayBuffer)) { + const bodyArray = []; + for (const key in data) { + if (hasOwn$1(data, key)) { + bodyArray.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])); + } + } + data = bodyArray.join('&'); + } + } + else { + headers[name] = header[name]; + } + } + if (!hasContentType && method === 'POST') { + headers['Content-Type'] = + 'application/x-www-form-urlencoded; charset=UTF-8'; + } + if (timeout) { + abortTimeout = setTimeout(() => { + aborted = true; + reject('timeout'); + }, timeout + 200); // TODO +200 发消息到原生层有时间开销,以后考虑由原生层回调超时 + } + const options = { + method, + url: url.trim(), + headers, + type: responseType === 'arraybuffer' ? 'base64' : 'text', + timeout: timeout || 6e5, + // 配置和weex模块内相反 + sslVerify: !sslVerify, + firstIpv4: firstIpv4, + tls, + }; + let withArrayBuffer = false; + if (method !== 'GET') { + if (toString.call(data) === '[object ArrayBuffer]') { + withArrayBuffer = true; + } + else { + options.body = typeof data === 'string' ? data : JSON.stringify(data); + } + } + const callback = ({ ok, status, data, headers, errorMsg, }) => { + if (aborted) { + return; + } + if (abortTimeout) { + clearTimeout(abortTimeout); + } + const statusCode = status; + if (statusCode > 0) { + resolve(formatResponse({ + data: ok && responseType === 'arraybuffer' + ? base64ToArrayBuffer(data) + : data, + statusCode, + header: headers, + cookies: cookiesParse(headers), + }, args)); + } + else { + let errMsg = 'abort statusCode:' + statusCode; + if (errorMsg) { + errMsg = errMsg + ' ' + errorMsg; + } + reject(errMsg); + } + }; + if (withArrayBuffer) { + stream.fetchWithArrayBuffer({ + '@type': 'binary', + base64: arrayBufferToBase64(data), + }, options, callback); + } + else { + stream.fetch(options, callback); + } + return new RequestTask({ + abort() { + aborted = true; + if (abortTimeout) { + clearTimeout(abortTimeout); + } + reject('abort'); + }, + }); +}, RequestProtocol, RequestOptions); +const configMTLS = defineAsyncApi(API_CONFIG_MTLS, ({ certificates }, { resolve, reject }) => { + const stream = requireNativePlugin('stream'); + stream.configMTLS(certificates, ({ type, code, message }) => { + switch (type) { + case 'success': + resolve({ code }); + break; + case 'fail': + reject(message, { code }); + break; + } + }); +}, ConfigMTLSProtocol, ConfigMTLSOptions); + +const socketTasks = []; +const socketsMap = {}; +const globalEvent = { + open: '', + close: '', + error: '', + message: '', +}; +let socket; +function createSocketTask(args) { + const socketId = String(Date.now()); + let errMsg; + try { + if (!socket) { + socket = requireNativePlugin('uni-webSocket'); + bindSocketCallBack(socket); + } + socket.WebSocket({ + id: socketId, + url: args.url, + protocol: Array.isArray(args.protocols) + ? args.protocols.join(',') + : args.protocols, + header: args.header, + }); + } + catch (error) { + errMsg = error; + } + return { socket, socketId, errMsg }; +} +function bindSocketCallBack(socket) { + socket.onopen((e) => { + const curSocket = socketsMap[e.id]; + if (!curSocket) + return; + curSocket._socketOnOpen(); + }); + socket.onmessage((e) => { + const curSocket = socketsMap[e.id]; + if (!curSocket) + return; + curSocket._socketOnMessage(e); + }); + socket.onerror((e) => { + const curSocket = socketsMap[e.id]; + if (!curSocket) + return; + curSocket._socketOnError(); + }); + socket.onclose((e) => { + const curSocket = socketsMap[e.id]; + if (!curSocket) + return; + curSocket._socketOnClose(); + }); +} +class SocketTask { + constructor(socket, socketId) { + this.id = socketId; + this._socket = socket; + this._callbacks = { + open: [], + close: [], + error: [], + message: [], + }; + this.CLOSED = 3; + this.CLOSING = 2; + this.CONNECTING = 0; + this.OPEN = 1; + this.readyState = this.CLOSED; + if (!this._socket) + return; + } + _socketOnOpen() { + this.readyState = this.OPEN; + this.socketStateChange('open'); + } + _socketOnMessage(e) { + this.socketStateChange('message', { + data: typeof e.data === 'object' + ? base64ToArrayBuffer(e.data.base64) + : e.data, + }); + } + _socketOnError() { + this.socketStateChange('error'); + this.onErrorOrClose(); + } + _socketOnClose() { + this.socketStateChange('close'); + this.onErrorOrClose(); + } + onErrorOrClose() { + this.readyState = this.CLOSED; + delete socketsMap[this.id]; + const index = socketTasks.indexOf(this); + if (index >= 0) { + socketTasks.splice(index, 1); + } + } + socketStateChange(name, res = {}) { + const data = name === 'message' ? res : {}; + if (this === socketTasks[0] && globalEvent[name]) { + UniServiceJSBridge.invokeOnCallback(globalEvent[name], data); + } + // WYQ fix: App平台修复websocket onOpen时发送数据报错的Bug + this._callbacks[name].forEach((callback) => { + if (typeof callback === 'function') { + callback(data); + } + }); + } + send(args, callopt = true) { + if (this.readyState !== this.OPEN) { + callOptions(args, 'sendSocketMessage:fail WebSocket is not connected'); + } + try { + this._socket.send({ + id: this.id, + data: typeof args.data === 'object' + ? { + '@type': 'binary', + base64: arrayBufferToBase64(args.data), + } + : args.data, + }); + callopt && callOptions(args, 'sendSocketMessage:ok'); + } + catch (error) { + callopt && callOptions(args, `sendSocketMessage:fail ${error}`); + } + } + close(args, callopt = true) { + this.readyState = this.CLOSING; + try { + this._socket.close(extend({ + id: this.id, + args, + })); + callopt && callOptions(args, 'closeSocket:ok'); + } + catch (error) { + callopt && callOptions(args, `closeSocket:fail ${error}`); + } + } + onOpen(callback) { + this._callbacks.open.push(callback); + } + onClose(callback) { + this._callbacks.close.push(callback); + } + onError(callback) { + this._callbacks.error.push(callback); + } + onMessage(callback) { + this._callbacks.message.push(callback); + } +} +const connectSocket = defineTaskApi(API_CONNECT_SOCKET, ({ url, protocols, header, method }, { resolve, reject }) => { + const { socket, socketId, errMsg } = createSocketTask({ + url, + protocols, + header, + method, + }); + const socketTask = new SocketTask(socket, socketId); + if (errMsg) { + setTimeout(() => { + reject(errMsg); + }, 0); + } + else { + socketTasks.push(socketTask); + socketsMap[socketId] = socketTask; + } + setTimeout(() => { + resolve(); + }, 0); + return socketTask; +}, ConnectSocketProtocol, ConnectSocketOptions); +const sendSocketMessage = defineAsyncApi(API_SEND_SOCKET_MESSAGE, (args, { resolve, reject }) => { + const socketTask = socketTasks[0]; + if (!socketTask || socketTask.readyState !== socketTask.OPEN) { + reject('WebSocket is not connected'); + return; + } + socketTask.send({ data: args.data }, false); + resolve(); +}, SendSocketMessageProtocol); +const closeSocket = defineAsyncApi(API_CLOSE_SOCKET, (args, { resolve, reject }) => { + const socketTask = socketTasks[0]; + if (!socketTask) { + reject('WebSocket is not connected'); + return; + } + socketTask.readyState = socketTask.CLOSING; + socketTask.close(args, false); + resolve(); +}, CloseSocketProtocol); +function on(event) { + const api = `onSocket${capitalize(event)}`; + return defineOnApi(api, () => { + globalEvent[event] = api; + }); +} +const onSocketOpen = /*#__PURE__*/ on('open'); +const onSocketError = /*#__PURE__*/ on('error'); +const onSocketMessage = /*#__PURE__*/ on('message'); +const onSocketClose = /*#__PURE__*/ on('close'); + +class UploadTask { + constructor(uploader) { + this._callbacks = []; + this._uploader = uploader; + uploader.addEventListener('statechanged', (upload, status) => { + if (upload.uploadedSize && upload.totalSize) { + this._callbacks.forEach((callback) => { + callback({ + progress: parseInt(String((upload.uploadedSize / upload.totalSize) * 100)), + totalBytesSent: upload.uploadedSize, + totalBytesExpectedToSend: upload.totalSize, + }); + }); + } + }); + } + abort() { + this._uploader.abort(); + } + onProgressUpdate(callback) { + if (typeof callback !== 'function') { + return; + } + this._callbacks.push(callback); + } + onHeadersReceived() { } + offProgressUpdate(callback) { + const index = this._callbacks.indexOf(callback); + if (index >= 0) { + this._callbacks.splice(index, 1); + } + } + offHeadersReceived() { } +} +const uploadFile = defineTaskApi(API_UPLOAD_FILE, ({ url, timeout, header, formData, files, filePath, name }, { resolve, reject }) => { + const uploader = plus.uploader.createUpload(url, { + timeout, + // 需要与其它平台上的表现保持一致,不走重试的逻辑。 + retry: 0, + retryInterval: 0, + }, (upload, statusCode) => { + if (statusCode) { + resolve({ + data: upload.responseText, + statusCode, + }); + } + else { + reject(`statusCode: ${statusCode}`); + } + }); + for (const name in header) { + if (hasOwn$1(header, name)) { + uploader.setRequestHeader(name, String(header[name])); + } + } + for (const name in formData) { + if (hasOwn$1(formData, name)) { + uploader.addData(name, String(formData[name])); + } + } + if (files && files.length) { + files.forEach((file) => { + uploader.addFile(getRealPath(file.uri), { + key: file.name || 'file', + }); + }); + } + else { + uploader.addFile(getRealPath(filePath), { + key: name, + }); + } + const uploadFileTask = new UploadTask(uploader); + uploader.start(); + return uploadFileTask; +}, UploadFileProtocol, UploadFileOptions); + +const audios = {}; +const evts = [ + 'play', + 'canplay', + 'ended', + 'stop', + 'waiting', + 'seeking', + 'seeked', + 'pause', +]; +const AUDIO_DEFAULT_SESSION_CATEGORY = 'playback'; +const initStateChage = (audioId) => { + const audio = audios[audioId]; + if (!audio) { + return; + } + if (!audio.initStateChage) { + audio.initStateChage = true; + audio.addEventListener('error', (error) => { + onAudioStateChange({ + state: 'error', + audioId, + errMsg: 'MediaError', + errCode: error.code, + }); + }); + evts.forEach((event) => { + audio.addEventListener(event, () => { + // 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题 + if (event === 'play') { + audio.isStopped = false; + } + else if (event === 'stop') { + audio.isStopped = true; + } + onAudioStateChange({ + state: event, + audioId, + }); + }); + }); + } +}; +function createAudioInstance() { + const audioId = `${Date.now()}${Math.random()}`; + const audio = (audios[audioId] = plus.audio.createPlayer('')); // 此处空字符串必填 + audio.src = ''; + audio.volume = 1; + audio.startTime = 0; + audio.setSessionCategory(AUDIO_DEFAULT_SESSION_CATEGORY); + return { + errMsg: 'createAudioInstance:ok', + audioId, + }; +} +function setAudioState({ audioId, src, startTime, autoplay = false, loop = false, obeyMuteSwitch, volume, sessionCategory = AUDIO_DEFAULT_SESSION_CATEGORY, }) { + const audio = audios[audioId]; + if (audio) { + const style = { + loop, + autoplay, + }; + if (src) { + audio.src = style.src = getRealPath(src); + } + if (startTime) { + audio.startTime = style.startTime = startTime; + } + if (typeof volume === 'number') { + audio.volume = style.volume = volume; + } + audio.setStyles(style); + if (sessionCategory) { + audio.setSessionCategory(sessionCategory); + } + initStateChage(audioId); + } + return { + errMsg: 'setAudioState:ok', + }; +} +function getAudioState({ audioId }) { + const audio = audios[audioId]; + if (!audio) { + return { + errMsg: 'getAudioState:fail', + }; + } + const { src, startTime, volume } = audio; + return { + errMsg: 'getAudioState:ok', + duration: 1e3 * (audio.getDuration() || 0), + currentTime: audio.isStopped ? 0 : 1e3 * audio.getPosition(), + paused: audio.isPaused(), + src, + volume, + startTime: 1e3 * startTime, + buffered: 1e3 * audio.getBuffered(), + }; +} +function operateAudio({ operationType, audioId, currentTime, }) { + const audio = audios[audioId]; + switch (operationType) { + case 'play': + case 'pause': + case 'stop': + audio[operationType === 'play' && audio.isPaused() ? 'resume' : operationType](); + break; + case 'seek': + typeof currentTime != 'undefined' ? audio.seekTo(currentTime / 1e3) : ''; + break; + } + return { + errMsg: 'operateAudio:ok', + }; +} +const innerAudioContexts = Object.create(null); +const onAudioStateChange = ({ state, audioId, errMsg, errCode, }) => { + const audio = innerAudioContexts[audioId]; + if (audio) { + emit(audio, state, errMsg, errCode); + if (state === 'play') { + const oldCurrentTime = audio.currentTime; + audio.__timing = setInterval(() => { + const currentTime = audio.currentTime; + if (currentTime !== oldCurrentTime) { + emit(audio, 'timeUpdate'); + } + }, 200); + } + else if (state === 'pause' || state === 'stop' || state === 'error') { + clearInterval(audio.__timing); + } + } +}; +const props$1 = [ + { + name: 'src', + cache: true, + }, + { + name: 'startTime', + default: 0, + cache: true, + }, + { + name: 'autoplay', + default: false, + cache: true, + }, + { + name: 'loop', + default: false, + cache: true, + }, + { + name: 'obeyMuteSwitch', + default: true, + readonly: true, + cache: true, + }, + { + name: 'duration', + readonly: true, + }, + { + name: 'currentTime', + readonly: true, + }, + { + name: 'paused', + readonly: true, + }, + { + name: 'buffered', + readonly: true, + }, + { + name: 'volume', + }, +]; +class InnerAudioContext { + constructor(id) { + this.id = id; + this._callbacks = {}; + this._options = {}; + // 初始化事件监听列表 + innerAudioContextEventNames.forEach((eventName) => { + this._callbacks[eventName] = []; + }); + props$1.forEach((item) => { + const name = item.name; + Object.defineProperty(this, name, { + get: () => { + const result = item.cache + ? this._options + : getAudioState({ + audioId: this.id, + }); + const value = name in result ? result[name] : item.default; + return typeof value === 'number' && name !== 'volume' + ? value / 1e3 + : value; + }, + set: item.readonly + ? undefined + : (value) => { + this._options[name] = value; + setAudioState(extend({}, this._options, { + audioId: this.id, + })); + }, + }); + }); + initInnerAudioContextEventOnce(); + } + play() { + this._operate('play'); + } + pause() { + this._operate('pause'); + } + stop() { + this._operate('stop'); + } + seek(position) { + this._operate('seek', { + currentTime: position * 1e3, + }); + } + destroy() { + clearInterval(this.__timing); + if (audios[this.id]) { + audios[this.id].close(); + delete audios[this.id]; + } + delete innerAudioContexts[this.id]; + } + _operate(type, options) { + operateAudio(extend({}, options, { + audioId: this.id, + operationType: type, + })); + } +} +const initInnerAudioContextEventOnce = /*#__PURE__*/ once(() => { + // 批量设置音频上下文事件监听方法 + innerAudioContextEventNames.forEach((eventName) => { + InnerAudioContext.prototype[eventName] = function (callback) { + if (typeof callback === 'function') { + this._callbacks[eventName].push(callback); + } + }; + }); + // 批量设置音频上下文事件取消监听方法 + innerAudioContextOffEventNames.forEach((eventName) => { + InnerAudioContext.prototype[eventName] = function (callback) { + const callbacks = this._callbacks[eventName]; + const index = callbacks.indexOf(callback); + if (index >= 0) { + callbacks.splice(index, 1); + } + }; + }); +}); +function emit(audio, state, errMsg, errCode) { + const name = `on${capitalize(state)}`; + audio._callbacks[name].forEach((callback) => { + if (typeof callback === 'function') { + callback(state === 'error' + ? { + errMsg, + errCode, + } + : {}); + } + }); +} +/** + * 创建音频上下文 + */ +const createInnerAudioContext = defineSyncApi(API_CREATE_INNER_AUDIO_CONTEXT, () => { + const { audioId } = createAudioInstance(); + const innerAudioContext = new InnerAudioContext(audioId); + innerAudioContexts[audioId] = innerAudioContext; + return innerAudioContext; +}); + +const eventNames = [ + 'canplay', + 'play', + 'pause', + 'stop', + 'ended', + 'timeUpdate', + 'prev', + 'next', + 'error', + 'waiting', +]; +const callbacks = { + canplay: [], + play: [], + pause: [], + stop: [], + ended: [], + timeUpdate: [], + prev: [], + next: [], + error: [], + waiting: [], +}; +let audio; +let timeUpdateTimer = null; +const TIME_UPDATE = 250; +const events = ['play', 'pause', 'ended', 'stop', 'canplay']; +function startTimeUpdateTimer() { + stopTimeUpdateTimer(); + timeUpdateTimer = setInterval(() => { + onBackgroundAudioStateChange({ state: 'timeUpdate' }); + }, TIME_UPDATE); +} +function stopTimeUpdateTimer() { + if (timeUpdateTimer !== null) { + clearInterval(timeUpdateTimer); + } +} +function initMusic() { + if (audio) { + return; + } + const publish = UniServiceJSBridge.invokeOnCallback; + audio = plus.audio.createPlayer({ + autoplay: true, + backgroundControl: true, + }); + audio.src = + audio.title = + audio.epname = + audio.singer = + audio.coverImgUrl = + audio.webUrl = + ''; + audio.startTime = 0; + events.forEach((event) => { + audio.addEventListener(event, () => { + // 添加 isStopped 属性是为了解决 安卓设备停止播放后获取播放进度不正确的问题 + if (event === 'play') { + audio.isStopped = false; + startTimeUpdateTimer(); + } + else if (event === 'stop') { + audio.isStopped = true; + } + if (event === 'pause' || event === 'ended' || event === 'stop') { + stopTimeUpdateTimer(); + } + const eventName = `onMusic${event[0].toUpperCase() + event.substr(1)}`; + publish(eventName, { + dataUrl: audio.src, + errMsg: `${eventName}:ok`, + }); + onBackgroundAudioStateChange({ + state: event, + dataUrl: audio.src, + }); + }); + }); + audio.addEventListener('waiting', () => { + stopTimeUpdateTimer(); + onBackgroundAudioStateChange({ + state: 'waiting', + dataUrl: audio.src, + }); + }); + audio.addEventListener('error', (err) => { + stopTimeUpdateTimer(); + publish('onMusicError', { + dataUrl: audio.src, + errMsg: 'Error:' + err.message, + }); + onBackgroundAudioStateChange({ + state: 'error', + dataUrl: audio.src, + errMsg: err.message, + errCode: err.code, + }); + }); + // @ts-ignore + audio.addEventListener('prev', () => publish('onBackgroundAudioPrev')); + // @ts-ignore + audio.addEventListener('next', () => publish('onBackgroundAudioNext')); +} +function getBackgroundAudioState() { + let data = { + duration: 0, + currentTime: 0, + paused: false, + src: '', + buffered: 0, + title: '', + epname: '', + singer: '', + coverImgUrl: '', + webUrl: '', + startTime: 0, + errMsg: 'getBackgroundAudioState:ok', + }; + if (audio) { + const newData = { + duration: audio.getDuration() || 0, + currentTime: audio.isStopped ? 0 : audio.getPosition(), + paused: audio.isPaused(), + src: audio.src, + buffered: audio.getBuffered(), + title: audio.title, + epname: audio.epname, + singer: audio.singer, + coverImgUrl: audio.coverImgUrl, + webUrl: audio.webUrl, + startTime: audio.startTime, + }; + data = extend(data, newData); + } + return data; +} +function setMusicState(args) { + initMusic(); + const props = [ + 'src', + 'startTime', + 'coverImgUrl', + 'webUrl', + 'singer', + 'epname', + 'title', + ]; + const style = {}; + Object.keys(args).forEach((key) => { + if (props.indexOf(key) >= 0) { + let val = args[key]; + if (key === props[0] && val) { + val = getRealPath(val); + } + audio[key] = style[key] = val; + } + }); + audio.setStyles(style); +} +function operateMusicPlayer({ operationType, src, position, api = 'operateMusicPlayer', title, coverImgUrl, }) { + var operationTypes = ['resume', 'pause', 'stop']; + if (operationTypes.indexOf(operationType) > 0) { + audio && audio[operationType](); + } + else if (operationType === 'play') { + setMusicState({ + src, + startTime: position, + title, + coverImgUrl, + }); + audio.play(); + } + else if (operationType === 'seek') { + audio && audio.seekTo(position); + } + return { + errMsg: `${api}:ok`, + }; +} +function operateBackgroundAudio({ operationType, src, startTime, currentTime, }) { + return operateMusicPlayer({ + operationType, + src, + position: startTime || currentTime || 0, + api: 'operateBackgroundAudio', + }); +} +function onBackgroundAudioStateChange({ state, errMsg, errCode, dataUrl, }) { + callbacks[state].forEach((callback) => { + if (typeof callback === 'function') { + callback(state === 'error' + ? { + errMsg, + errCode, + } + : {}); + } + }); +} +const onInitBackgroundAudioManager = /*#__PURE__*/ once(() => { + eventNames.forEach((item) => { + BackgroundAudioManager.prototype[`on${capitalize(item)}`] = + function (callback) { + callbacks[item].push(callback); + }; + }); +}); +const props = [ + { + name: 'duration', + readonly: true, + }, + { + name: 'currentTime', + readonly: true, + }, + { + name: 'paused', + readonly: true, + }, + { + name: 'src', + cache: true, + }, + { + name: 'startTime', + default: 0, + cache: true, + }, + { + name: 'buffered', + readonly: true, + }, + { + name: 'title', + cache: true, + }, + { + name: 'epname', + cache: true, + }, + { + name: 'singer', + cache: true, + }, + { + name: 'coverImgUrl', + cache: true, + }, + { + name: 'webUrl', + cache: true, + }, + { + name: 'protocol', + readonly: true, + default: 'http', + }, +]; +class BackgroundAudioManager { + constructor() { + this._options = {}; + props.forEach((item) => { + const name = item.name; + Object.defineProperty(this, name, { + get: () => { + const result = item.cache ? this._options : getBackgroundAudioState(); + return name in result ? result[name] : item.default; + }, + set: item.readonly + ? undefined + : (value) => { + this._options[name] = value; + setMusicState(this._options); + }, + }); + }); + onInitBackgroundAudioManager(); + } + play() { + this._operate('play'); + } + pause() { + this._operate('pause'); + } + stop() { + this._operate('stop'); + } + seek(position) { + this._operate('seek', { + currentTime: position, + }); + } + _operate(type, options) { + operateBackgroundAudio(extend({}, options, { + operationType: type, + })); + } +} +let backgroundAudioManager; +const getBackgroundAudioManager = defineSyncApi(API_GET_BACKGROUND_AUDIO_MANAGER, () => backgroundAudioManager || + (backgroundAudioManager = new BackgroundAudioManager())); + +class LivePusherContext { + constructor(id, ctx) { + this.id = id; + this.ctx = ctx; + } + start(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'start', option); + } + stop(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'stop', option); + } + pause(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'pause', option); + } + resume(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'resume', option); + } + switchCamera(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'switchCamera', option); + } + snapshot(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'snapshot', option); + } + toggleTorch(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'toggleTorch', option); + } + playBGM(option) { + return invokeVmMethod(this.ctx, 'playBGM', option); + } + stopBGM(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'stopBGM', option); + } + pauseBGM(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'pauseBGM', option); + } + resumeBGM(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'resumeBGM', option); + } + setBGMVolume(option) { + return invokeVmMethod(this.ctx, 'setBGMVolume', option); + } + startPreview(option) { + return invokeVmMethodWithoutArgs(this.ctx, 'startPreview', option); + } + stopPreview(args) { + return invokeVmMethodWithoutArgs(this.ctx, 'stopPreview', args); + } +} +const createLivePusherContext = defineSyncApi(API_CREATE_LIVE_PUSHER_CONTEXT, (id, vm) => { + if (!vm) { + return console.warn('uni.createLivePusherContext: 2 arguments required, but only 1 present'); + } + const elm = findElmById(id, vm); + if (!elm) { + return console.warn('Can not find `' + id + '`'); + } + return new LivePusherContext(id, elm); +}, CreateLivePusherContextProtocol); + +const PI = 3.1415926535897932384626; +const a = 6378245.0; +const ee = 0.00669342162296594323; +function gcj02towgs84(lng, lat) { + lat = +lat; + lng = +lng; + if (outOfChina(lng, lat)) { + return [lng, lat]; + } + let dlat = _transformlat(lng - 105.0, lat - 35.0); + let dlng = _transformlng(lng - 105.0, lat - 35.0); + const radlat = (lat / 180.0) * PI; + let magic = Math.sin(radlat); + magic = 1 - ee * magic * magic; + const sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI); + dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI); + const mglat = lat + dlat; + const mglng = lng + dlng; + return [lng * 2 - mglng, lat * 2 - mglat]; +} +function wgs84togcj02(lng, lat) { + lat = +lat; + lng = +lng; + if (outOfChina(lng, lat)) { + return [lng, lat]; + } + let dlat = _transformlat(lng - 105.0, lat - 35.0); + let dlng = _transformlng(lng - 105.0, lat - 35.0); + const radlat = (lat / 180.0) * PI; + let magic = Math.sin(radlat); + magic = 1 - ee * magic * magic; + const sqrtmagic = Math.sqrt(magic); + dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI); + dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI); + const mglat = lat + dlat; + const mglng = lng + dlng; + return [mglng, mglat]; +} +const outOfChina = function (lng, lat) { + return (lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271 || false); +}; +const _transformlat = function (lng, lat) { + let ret = -100.0 + + 2.0 * lng + + 3.0 * lat + + 0.2 * lat * lat + + 0.1 * lng * lat + + 0.2 * Math.sqrt(Math.abs(lng)); + ret += + ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * + 2.0) / + 3.0; + ret += + ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / + 3.0; + ret += + ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * + 2.0) / + 3.0; + return ret; +}; +const _transformlng = function (lng, lat) { + let ret = 300.0 + + lng + + 2.0 * lat + + 0.1 * lng * lng + + 0.1 * lng * lat + + 0.1 * Math.sqrt(Math.abs(lng)); + ret += + ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * + 2.0) / + 3.0; + ret += + ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / + 3.0; + ret += + ((150.0 * Math.sin((lng / 12.0) * PI) + + 300.0 * Math.sin((lng / 30.0) * PI)) * + 2.0) / + 3.0; + return ret; +}; + +function getLocationSuccess(type, position, resolve) { + const coords = position.coords; + if (type !== position.coordsType) { + let coordArray; + if (type === 'wgs84') { + coordArray = gcj02towgs84(coords.longitude, coords.latitude); + } + else if (type === 'gcj02') { + coordArray = wgs84togcj02(coords.longitude, coords.latitude); + } + if (coordArray) { + coords.longitude = coordArray[0]; + coords.latitude = coordArray[1]; + } + } + resolve({ + type, + altitude: coords.altitude || 0, + latitude: coords.latitude, + longitude: coords.longitude, + speed: coords.speed, + accuracy: coords.accuracy, + address: position.address, + errMsg: 'getLocation:ok', + }); +} +const getLocation = defineAsyncApi(API_GET_LOCATION, ({ type = 'wgs84', geocode = false, altitude = false, highAccuracyExpireTime, isHighAccuracy = false, }, { resolve, reject }) => { + plus.geolocation.getCurrentPosition((position) => { + getLocationSuccess(type, position, resolve); + }, (e) => { + // 坐标地址解析失败 + if (e.code === 1501) { + getLocationSuccess(type, e, resolve); + return; + } + reject('getLocation:fail ' + e.message); + }, { + geocode: geocode, + enableHighAccuracy: isHighAccuracy || altitude, + timeout: highAccuracyExpireTime, + coordsType: type, + }); +}, GetLocationProtocol, GetLocationOptions); + +const chooseLocation = defineAsyncApi(API_CHOOSE_LOCATION, (options, { resolve, reject }) => { + const statusBarStyle = getStatusBarStyle(); + const isDark = statusBarStyle !== 'light'; + let result; + const page = showPage({ + url: '__uniappchooselocation', + data: options, + style: { + // @ts-expect-error + animationType: options.animationType || 'slide-in-bottom', + // @ts-expect-error + titleNView: false, + popGesture: 'close', + scrollIndicator: 'none', + }, + onMessage({ event, detail, }) { + if (event === 'selected') { + result = detail; + } + }, + onClose() { + if (isDark) { + plus.navigator.setStatusBarStyle('dark'); + } + result ? resolve(result) : reject('cancel'); + }, + }); + if (isDark) { + plus.navigator.setStatusBarStyle('light'); + page.webview.addEventListener('popGesture', ({ type, result }) => { + if (type === 'start') { + plus.navigator.setStatusBarStyle('dark'); + } + else if (type === 'end' && !result) { + plus.navigator.setStatusBarStyle('light'); + } + }); + } +}, ChooseLocationProtocol); + +const openLocation = defineAsyncApi(API_OPEN_LOCATION, (data, { resolve, reject }) => { + showPage({ + url: '__uniappopenlocation', + data, + style: { + titleNView: { + type: 'transparent', + }, + popGesture: 'close', + backButtonAutoControl: 'close', + }, + onClose() { + reject('cancel'); + }, + }); + return resolve(); +}, OpenLocationProtocol, OpenLocationOptions); + +const showModal = defineAsyncApi(API_SHOW_MODAL, ({ title = '', content = '', showCancel = true, cancelText, cancelColor, confirmText, confirmColor, editable = false, placeholderText = '', } = {}, { resolve }) => { + const buttons = showCancel ? [cancelText, confirmText] : [confirmText]; + const tip = editable ? placeholderText : buttons; + content = content || ' '; + plus.nativeUI[editable ? 'prompt' : 'confirm'](content, (e) => { + if (showCancel) { + const isConfirm = e.index === 1; + const res = { + confirm: isConfirm, + cancel: e.index === 0 || e.index === -1, + }; + isConfirm && editable && (res.content = e.value); + resolve(res); + } + else { + const res = { + confirm: e.index === 0, + cancel: false, + }; + editable && (res.content = e.value); + resolve(res); + } + }, title, tip, buttons); +}, ShowModalProtocol, ShowModalOptions); + +const showActionSheet = defineAsyncApi(API_SHOW_ACTION_SHEET, ({ itemList = [], itemColor = '#000000', title = '', alertText = '', popover, }, { resolve, reject }) => { + initI18nShowActionSheetMsgsOnce(); + const { t } = useI18n(); + const options = { + title, + cancel: t('uni.showActionSheet.cancel'), + buttons: itemList.map((item) => ({ + title: item, + color: itemColor, + })), + }; + if (title || alertText) { + options.title = alertText || title; + } + plus.nativeUI.actionSheet(extend(options, { + popover, + }), (e) => { + if (e.index > 0) { + resolve({ + tapIndex: e.index - 1, + }); + } + else { + reject('showActionSheet:fail cancel'); + } + }); +}, ShowActionSheetProtocol, ShowActionSheetOptions); + +let toast; +let isShowToast = false; +let toastType = ''; +let timeout; +const showLoading = defineAsyncApi(API_SHOW_LOADING, (args, callbacks) => _showToast(extend({}, args, { + type: 'loading', + icon: 'loading', +}), callbacks), ShowLoadingProtocol, ShowLoadingOptions); +const _showToast = ({ title = '', icon = 'success', image = '', duration = 1500, mask = false, position, type = 'toast', style, }, { resolve, reject }) => { + hide(''); + toastType = type; + if (['top', 'center', 'bottom'].includes(String(position))) { + // 仅可以关闭 richtext 类型,但 iOS 部分情况换行显示有问题 + plus.nativeUI.toast(title, { + verticalAlign: position, + }); + isShowToast = true; + } + else { + if (icon && !~['success', 'loading', 'error', 'none'].indexOf(icon)) { + icon = 'success'; + } + const waitingOptions = { + modal: mask, + back: 'transmit', + padding: '10px', + size: '16px', // 固定字体大小 + }; + if (!image && (!icon || icon === 'none')) { + // 无图 + // waitingOptions.width = '120px' + // waitingOptions.height = '40px' + waitingOptions.loading = { + display: 'none', + }; + } + else { + waitingOptions.width = '140px'; + waitingOptions.height = '112px'; + } + if (image) { + waitingOptions.loading = { + display: 'block', + height: '55px', + icon: image, + interval: duration, + }; + } + else { + if (['success', 'error'].indexOf(icon) !== -1) { + waitingOptions.loading = { + display: 'block', + height: '55px', + icon: icon === 'success' ? '__uniappsuccess.png' : '__uniapperror.png', + interval: duration, + }; + } + } + try { + toast = plus.nativeUI.showWaiting(title, extend(waitingOptions, style)); + } + catch (error) { + reject(`${error}`); + } + } + if (toastType === 'toast') + timeout = setTimeout(() => { + hide(''); + }, duration); + return resolve(); +}; +const showToast = defineAsyncApi(API_SHOW_TOAST, _showToast, ShowToastProtocol, ShowToastOptions); +const hideToast = defineAsyncApi(API_HIDE_TOAST, (_, callbacks) => hide('toast', callbacks)); +const hideLoading = defineAsyncApi(API_HIDE_LOADING, (_, callbacks) => hide('loading', callbacks)); +function hide(type = 'toast', callbacks) { + if (type && type !== toastType) { + // 应该不需要失败回调,在页面后退时,会主动 hideToast 和 hideLoading,如果 reject 会出异常。 + return callbacks && callbacks.resolve(); + } + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + if (isShowToast) { + plus.nativeUI.closeToast(); + } + else if (toast && toast.close) { + toast.close(); + } + toast = null; + isShowToast = false; + toastType = ''; + return callbacks && callbacks.resolve(); +} - function restoreGlobal(newVue, newWeex, newPlus, newSetTimeout, newClearTimeout, newSetInterval, newClearInterval) { - // 确保部分全局变量 是 app-service 中的 - // 若首页 nvue 初始化比 app-service 快,导致框架处于该 nvue 环境下 - // plus 如果不用 app-service,资源路径会出问题 - // 若首页 nvue 被销毁,如 redirectTo 或 reLaunch,则这些全局功能会损坏 - // 设置 vue3 - // @ts-ignore 最终vue会被替换为vue - vue = newVue; - if (plus !== newPlus) { - if ((process.env.NODE_ENV !== 'production')) { - console.log(`[restoreGlobal][${Date.now()}]`); - } - weex = newWeex; - // @ts-ignore - plus = newPlus; - restoreOldSetStatusBarStyle(plus.navigator.setStatusBarStyle); - plus.navigator.setStatusBarStyle = newSetStatusBarStyle; - /* eslint-disable no-global-assign */ - // @ts-ignore - setTimeout = newSetTimeout; - // @ts-ignore - clearTimeout = newClearTimeout; - // @ts-ignore - setInterval = newSetInterval; - // @ts-ignore - clearInterval = newClearInterval; - } - __uniConfig.serviceReady = true; - } +const startPullDownRefresh = defineAsyncApi(API_START_PULL_DOWN_REFRESH, (_args, { resolve, reject }) => { + let webview = getPullDownRefreshWebview(); + if (webview) { + webview.endPullToRefresh(); + } + webview = getCurrentWebview(); + if (!webview) { + return reject(); + } + webview.beginPullToRefresh(); + setPullDownRefreshWebview(webview); + resolve(); +}); + +const stopPullDownRefresh = defineAsyncApi(API_STOP_PULL_DOWN_REFRESH, (_args, { resolve, reject }) => { + const webview = getPullDownRefreshWebview() || getCurrentWebview(); + if (!webview) { + return reject(); + } + webview.endPullToRefresh(); + setPullDownRefreshWebview(null); + resolve(); +}); + +const loadFontFace = defineAsyncApi(API_LOAD_FONT_FACE, (options, { resolve, reject }) => { + const pageId = getPageIdByVm(getCurrentPageVm()); + UniServiceJSBridge.invokeViewMethod(API_LOAD_FONT_FACE, options, pageId, (err) => { + if (err) { + reject(err); + } + else { + resolve(); + } + }); +}, LoadFontFaceProtocol); + +const pageScrollTo = defineAsyncApi(API_PAGE_SCROLL_TO, (options, { resolve }) => { + const pageId = getPageIdByVm(getCurrentPageVm()); + UniServiceJSBridge.invokeViewMethod(API_PAGE_SCROLL_TO, options, pageId, resolve); +}, PageScrollToProtocol, PageScrollToOptions); + +const setNavigationBarTitle = defineAsyncApi(API_SET_NAVIGATION_BAR_TITLE, ({ __page__, title }, { resolve, reject }) => { + const webview = getWebview(__page__); + if (webview) { + const style = webview.getStyle(); + if (style && style.titleNView) { + webview.setStyle({ + titleNView: { + titleText: title, + }, + }); + } + resolve(); + } + else { + reject(); + } +}, SetNavigationBarTitleProtocol); +const showNavigationBarLoading = defineAsyncApi(API_SHOW_NAVIGATION_BAR_LOADING, (_, { resolve }) => { + plus.nativeUI.showWaiting('', { + modal: false, + }); + resolve(); +}); +const hideNavigationBarLoading = defineAsyncApi(API_HIDE_NAVIGATION_BAR_LOADING, (_, { resolve }) => { + plus.nativeUI.closeWaiting(); + resolve(); +}); +function setPageStatusBarStyle(statusBarStyle) { + const pages = getCurrentPages(); + if (!pages.length) { + return; + } + // 框架内部页面跳转会从这里获取style配置 + pages[pages.length - 1].$page.statusBarStyle = statusBarStyle; +} +const setNavigationBarColor = defineAsyncApi(API_SET_NAVIGATION_BAR_COLOR, ({ __page__, frontColor, backgroundColor }, { resolve, reject }) => { + const webview = getWebview(__page__); + if (webview) { + const styles = {}; + if (frontColor) { + styles.titleColor = frontColor; + } + if (backgroundColor) { + styles.backgroundColor = backgroundColor; + } + const statusBarStyle = frontColor === '#000000' ? 'dark' : 'light'; + plus.navigator.setStatusBarStyle(statusBarStyle); + // 用户调用api时同时改变当前页配置,这样在系统调用设置时,可以避免覆盖用户设置 + setPageStatusBarStyle(statusBarStyle); + const style = webview.getStyle(); + if (style && style.titleNView) { + if (style.titleNView.autoBackButton) { + styles.backButton = styles.backButton || {}; + styles.backButton.color = frontColor; + } + webview.setStyle({ + titleNView: styles, + }); + } + resolve(); + } + else { + reject(); + } +}, SetNavigationBarColorProtocol, SetNavigationBarColorOptions); + +const setTabBarBadge = defineAsyncApi(API_SET_TAB_BAR_BADGE, ({ index, text }, { resolve, reject }) => { + tabBar$1.setTabBarBadge('text', index, text); + resolve(); +}, SetTabBarBadgeProtocol, SetTabBarBadgeOptions); +const setTabBarItem = defineAsyncApi(API_SET_TAB_BAR_ITEM, ({ index, text, iconPath, selectedIconPath, pagePath, visible }, { resolve, reject }) => { + tabBar$1.setTabBarItem(index, text, iconPath, selectedIconPath, visible); + const route = pagePath && __uniRoutes.find(({ path }) => path === pagePath); + if (route) { + const meta = route.meta; + meta.isTabBar = true; + meta.tabBarIndex = index; + meta.isQuit = true; + const tabBar = __uniConfig.tabBar; + if (tabBar && tabBar.list && tabBar.list[index] && pagePath) { + tabBar.list[index].pagePath = pagePath.startsWith('/') + ? pagePath.substring(1) + : pagePath; + } + } + resolve(); +}, SetTabBarItemProtocol, SetTabBarItemOptions); +const setTabBarStyle = defineAsyncApi(API_SET_TAB_BAR_STYLE, (style = {}, { resolve, reject }) => { + if (!isTabBarPage()) { + return reject('not TabBar page'); + } + const borderStyles = { + black: 'rgba(0,0,0,0.4)', + white: 'rgba(255,255,255,0.4)', + }; + const borderStyle = style.borderStyle; + if (borderStyle && borderStyle in borderStyles) { + style.borderStyle = borderStyles[borderStyle]; + } + tabBar$1.setTabBarStyle(style); + resolve(); +}, SetTabBarStyleProtocol, SetTabBarStyleOptions); +const hideTabBar = defineAsyncApi(API_HIDE_TAB_BAR, (args, { resolve, reject }) => { + const animation = args && args.animation; + if (!isTabBarPage()) { + return reject('not TabBar page'); + } + tabBar$1.hideTabBar(Boolean(animation)); + resolve(); +}, HideTabBarProtocol); +const showTabBar = defineAsyncApi(API_SHOW_TAB_BAR, (args, { resolve, reject }) => { + const animation = args && args.animation; + if (!isTabBarPage()) { + return reject('not TabBar page'); + } + tabBar$1.showTabBar(Boolean(animation)); + resolve(); +}, ShowTabBarProtocol); +const showTabBarRedDot = defineAsyncApi(API_SHOW_TAB_BAR_RED_DOT, ({ index }, { resolve, reject }) => { + tabBar$1.setTabBarBadge('redDot', index); + resolve(); +}, ShowTabBarRedDotProtocol, ShowTabBarRedDotOptions); +const setTabBarBadgeNone = (index) => tabBar$1.setTabBarBadge('none', index); +const removeTabBarBadge = defineAsyncApi(API_REMOVE_TAB_BAR_BADGE, ({ index }, { resolve, reject }) => { + setTabBarBadgeNone(index); + resolve(); +}, RemoveTabBarBadgeProtocol, RemoveTabBarBadgeOptions); +const hideTabBarRedDot = defineAsyncApi(API_HIDE_TAB_BAR_RED_DOT, ({ index }, { resolve, reject }) => { + setTabBarBadgeNone(index); + resolve(); +}, HideTabBarRedDotProtocol, HideTabBarRedDotOptions); + +const VD_SYNC = 'vdSync'; +const APP_SERVICE_ID = '__uniapp__service'; +const ON_WEBVIEW_READY = 'onWebviewReady'; +const ACTION_TYPE_DICT = 0; +const WEBVIEW_INSERTED = 'webviewInserted'; +const WEBVIEW_REMOVED = 'webviewRemoved'; + +const EVENT_TYPE_NAME = 'UniAppSubNVue'; +class SubNvue { + constructor(id, isSub) { + this.callbacks = []; + const webview = (this.webview = plus.webview.getWebviewById(id)); + this.isSub = isSub || false; + if (webview.__uniapp_mask_id) { + const maskWebview = (this.maskWebview = + webview.__uniapp_mask_id === '0' + ? { + setStyle({ mask }) { + requireNativePlugin('uni-tabview').setMask({ + color: mask, + }); + }, + } + : plus.webview.getWebviewById(webview.__uniapp_mask_id)); + const closeMask = function () { + maskWebview.setStyle({ + mask: 'none', + }); + }; + webview.addEventListener('hide', closeMask); + webview.addEventListener('close', closeMask); + } + } + show(...args) { + if (this.maskWebview) { + const maskColor = this.webview.__uniapp_mask; + this.maskWebview.setStyle({ + mask: maskColor, + }); + } + this.webview.show(...args); + } + hide(...args) { + this.webview.hide(...args); + } + setStyle(style) { + this.webview.setStyle(style); + } + initMessage() { + if (this.messageReady) { + return; + } + this.messageReady = true; + const listener = (event) => { + if (event.data && event.data.type === EVENT_TYPE_NAME) { + const target = event.data.target; + if (target.id === this.webview.id && target.isSub === this.isSub) { + this.callbacks.forEach((callback) => { + callback({ + origin: this.webview.__uniapp_host, + data: event.data.data, + }); + }); + } + } + }; + const globalEvent = requireNativePlugin('globalEvent'); + globalEvent.addEventListener('plusMessage', listener); + this.webview.addEventListener('close', () => { + // TODO 暂时仅清空回调 + this.callbacks.length = 0; + // globalEvent.removeEventListener('plusMessage', listener) + }); + } + postMessage(data) { + const webviewExt = plus.webview; + webviewExt.postMessageToUniNView({ + type: EVENT_TYPE_NAME, + data, + target: { + id: this.webview.id, + isSub: !this.isSub, + }, + }, APP_SERVICE_ID); + } + onMessage(callback) { + this.initMessage(); + this.callbacks.push(callback); + } +} +const getSubNVueById = function (id, isSub) { + // TODO 暂时通过 isSub 区分来自 subNVue 页面 + return new SubNvue(id, isSub); +}; + +let lastStatusBarStyle; +let oldSetStatusBarStyle = plus.navigator.setStatusBarStyle; +function restoreOldSetStatusBarStyle(setStatusBarStyle) { + oldSetStatusBarStyle = setStatusBarStyle; +} +function newSetStatusBarStyle(style) { + lastStatusBarStyle = style; + oldSetStatusBarStyle(style); +} +plus.navigator.setStatusBarStyle = newSetStatusBarStyle; +function setStatusBarStyle(statusBarStyle) { + if (!statusBarStyle) { + const page = getCurrentPage(); + if (!page) { + return; + } + statusBarStyle = page.$page.statusBarStyle; + if (!statusBarStyle || statusBarStyle === lastStatusBarStyle) { + return; + } + } + if (statusBarStyle === lastStatusBarStyle) { + return; + } + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('setStatusBarStyle', statusBarStyle)); + } + lastStatusBarStyle = statusBarStyle; + plus.navigator.setStatusBarStyle(statusBarStyle); +} - const providers = { - oauth(callback) { - plus.oauth.getServices((services) => { - services = services; - const provider = []; - services.forEach(({ id }) => { - provider.push(id); - }); - callback(null, provider); - }, (err) => { - err = err; - callback(err); - }); - }, - share(callback) { - plus.share.getServices((services) => { - services = services; - const provider = []; - services.forEach(({ id }) => { - provider.push(id); - }); - callback(null, provider); - }, (err) => { - callback(err); - }); - }, - payment(callback) { - plus.payment.getChannels((services) => { - const provider = []; - services.forEach(({ id }) => { - provider.push(id); - }); - callback(null, provider); - }, (err) => { - callback(err); - }); - }, - push(callback) { - if (typeof weex !== 'undefined' || typeof plus !== 'undefined') { - callback(null, [plus.push.getClientInfo().id]); - } - else { - callback(null, []); - } - }, - }; - const getProvider = defineAsyncApi(API_GET_PROVIDER, ({ service }, { resolve, reject }) => { - if (providers[service]) { - providers[service]((err, provider) => { - if (err) { - reject(err.message); - } - else { - resolve({ - service, - provider: provider, - }); - } - }); - } - else { - reject('service not found'); - } - }, GetProviderProtocol); - - let univerifyManager; - function getService(provider) { - return new Promise((resolve, reject) => { - plus.oauth.getServices((services) => { - const service = services.find(({ id }) => id === provider); - service ? resolve(service) : reject(new Error('provider not find')); - }, reject); - }); - } - const login = defineAsyncApi(API_LOGIN, (params, { resolve, reject }) => { - const provider = params.provider || 'weixin'; - const errorCallback = warpPlusErrorCallback(reject); - const authOptions = provider === 'apple' - ? { scope: 'email' } - : params.univerifyStyle - ? { - univerifyStyle: univerifyButtonsClickHandling(params.univerifyStyle, errorCallback), - } - : {}; - getService(provider) - .then((service) => { - function login() { - if (params.onlyAuthorize && provider === 'weixin') { - service.authorize(({ code }) => { - resolve({ - code, - authResult: '', - }); - }, errorCallback); - return; - } - service.login((res) => { - const authResult = res.target.authResult; - resolve({ - code: authResult.code, - authResult: authResult, - }); - }, errorCallback, authOptions); - } - // 先注销再登录 - // apple登录logout之后无法重新触发获取email,fullname;一键登录无logout - if (provider === 'apple' || provider === 'univerify') { - login(); - } - else { - service.logout(login, login); - } - }) - .catch(errorCallback); - }, LoginProtocol); - const baseGetUserInfo = (params, { resolve, reject }) => { - const provider = params.provider || 'weixin'; - const errorCallback = warpPlusErrorCallback(reject); - getService(provider) - .then((loginService) => { - loginService.getUserInfo((res) => { - let userInfo = { nickName: '' }; - if (provider === 'weixin') { - const wechatUserInfo = loginService.userInfo; - if (wechatUserInfo) - userInfo = { - openId: wechatUserInfo.openid, - nickName: wechatUserInfo.nickname, - gender: wechatUserInfo.sex, - city: wechatUserInfo.city, - province: wechatUserInfo.province, - country: wechatUserInfo.country, - avatarUrl: wechatUserInfo.headimgurl, - unionId: wechatUserInfo.unionid, - }; - } - else if (provider === 'apple') { - const appleInfo = loginService.appleInfo; - if (appleInfo) - userInfo = { - openId: appleInfo.user, - fullName: appleInfo.fullName, - email: appleInfo.email, - authorizationCode: appleInfo.authorizationCode, - identityToken: appleInfo.identityToken, - realUserStatus: appleInfo.realUserStatus, - }; - } - else { - userInfo = loginService.userInfo; - if (userInfo) { - userInfo.openId = - userInfo.openId || - userInfo.openid || - loginService.authResult.openid; - userInfo.nickName = userInfo.nickName || userInfo.nickname; - userInfo.avatarUrl = userInfo.avatarUrl || userInfo.headimgurl; - } - } - let result = {}; - // @ts-ignore - if (params.data && params.data.api_name === 'webapi_getuserinfo') { - result.data = { - data: JSON.stringify(userInfo), - rawData: '', - signature: '', - encryptedData: '', - iv: '', - }; - } - else { - result.userInfo = userInfo; - } - resolve(result); - }, errorCallback); - }) - .catch(() => { - reject('请先调用 uni.login'); - }); - }; - const getUserInfo = defineAsyncApi(API_GET_USER_INFO, baseGetUserInfo, GetUserInfoProtocol); - /** - * 获取用户信息-兼容 - */ - const getUserProfile = defineAsyncApi(API_GET_USER_PROFILE, baseGetUserInfo, GgetUserProfileProtocol); - const preLogin = defineAsyncApi(API_PRE_LOGIN, ({ provider }, { resolve, reject }) => { - const successCallback = warpPlusSuccessCallback(resolve); - const errorCallback = warpPlusErrorCallback(reject); - getService(provider) - .then((service) => service.preLogin(successCallback, errorCallback)) - .catch(errorCallback); - }, PreLoginProtocol, PreLoginOptions); - const _closeAuthView = () => getService('univerify').then((service) => service.closeAuthView()); - const closeAuthView = defineSyncApi(API_CLOSE_AUTH_VIEW, _closeAuthView); - const getCheckBoxState = defineAsyncApi(API_GET_CHECK_BOX_STATE, (_, { resolve, reject }) => { - const successCallback = warpPlusSuccessCallback(resolve); - const errorCallback = warpPlusErrorCallback(reject); - try { - getService('univerify').then((service) => { - // @ts-expect-error - const state = service.getCheckBoxState(); - successCallback({ state }); - }); - } - catch (error) { - errorCallback(error); - } - }); - /** - * 一键登录自定义登陆按钮点击处理 - */ - function univerifyButtonsClickHandling(univerifyStyle, errorCallback) { - if (shared.isPlainObject(univerifyStyle) && - shared.isPlainObject(univerifyStyle.buttons) && - shared.toTypeString(univerifyStyle.buttons.list) === '[object Array]') { - univerifyStyle.buttons.list.forEach((button, index) => { - univerifyStyle.buttons.list[index].onclick = function () { - const res = { - code: '30008', - message: '用户点击了自定义按钮', - index, - provider: button.provider, - }; - shared.isPlainObject(univerifyManager) - ? univerifyManager._triggerUniverifyButtonsClick(res) - : _closeAuthView().then(() => { - errorCallback(res); - }); - }; - }); - } - return univerifyStyle; - } - class UniverifyManager { - constructor() { - this.provider = 'univerify'; - this.eventName = 'api.univerifyButtonsClick'; - } - close() { - closeAuthView(); - } - login(options) { - login(this._getOptions(options)); - } - getCheckBoxState(options) { - getCheckBoxState(options); - } - preLogin(options) { - preLogin(this._getOptions(options)); - } - onButtonsClick(callback) { - UniServiceJSBridge.on(this.eventName, callback); - } - offButtonsClick(callback) { - UniServiceJSBridge.off(this.eventName, callback); - } - _triggerUniverifyButtonsClick(res) { - UniServiceJSBridge.emit(this.eventName, res); - } - _getOptions(options = {}) { - return shared.extend({}, options, { provider: this.provider }); - } - } - const getUniverifyManager = defineSyncApi(API_GET_UNIVERIFY_MANAGER, () => { - return univerifyManager || (univerifyManager = new UniverifyManager()); - }); - - const registerRuntime = defineSyncApi('registerRuntime', (runtime) => { - // @ts-expect-error - shared.extend(jsRuntime, runtime); - }); - - // 0:图文,1:纯文字,2:纯图片,3:音乐,4:视频,5:小程序 - const TYPES = { - 0: { - name: 'web', - title: '图文', - }, - 1: { - name: 'text', - title: '纯文字', - }, - 2: { - name: 'image', - title: '纯图片', - }, - 3: { - name: 'music', - title: '音乐', - }, - 4: { - name: 'video', - title: '视频', - }, - 5: { - name: 'miniProgram', - title: '小程序', - }, - }; - const parseParams = (args) => { - args.type = args.type || 0; - let { provider, type, title, summary: content, href, imageUrl, mediaUrl: media, scene, miniProgram, } = args; - if (typeof imageUrl === 'string' && imageUrl) { - imageUrl = getRealPath(imageUrl); - } - const shareType = TYPES[type]; - if (shareType) { - const sendMsg = { - provider, - type: shareType.name, - title, - content, - href, - pictures: [imageUrl], - thumbs: imageUrl ? [imageUrl] : undefined, - media, - miniProgram, - extra: { - scene, - }, - }; - if (provider === 'weixin' && (type === 1 || type === 2)) { - delete sendMsg.thumbs; - } - return sendMsg; - } - return '分享参数 type 不正确'; - }; - const sendShareMsg = function (service, params, resolve, reject, method = 'share') { - const errorCallback = warpPlusErrorCallback(reject); - service.send(params, () => { - resolve(); - }, errorCallback); - }; - const share = defineAsyncApi(API_SHREA, (params, { resolve, reject }) => { - const res = parseParams(params); - const errorCallback = warpPlusErrorCallback(reject); - if (typeof res === 'string') { - return reject(res); - } - else { - params = res; - } - plus.share.getServices((services) => { - const service = services.find(({ id }) => id === params.provider); - if (!service) { - reject('service not found'); - } - else { - if (service.authenticated) { - sendShareMsg(service, params, resolve, reject); - } - else { - service.authorize(() => sendShareMsg(service, params, resolve, reject), errorCallback); - } - } - }, errorCallback); - }, ShareProtocols, SahreOptions); - const shareWithSystem = defineAsyncApi(API_SHARE_WITH_SYSTEM, ({ type, imageUrl, summary, href }, { resolve, reject }) => { - const errorCallback = warpPlusErrorCallback(reject); - if (typeof imageUrl === 'string' && imageUrl) { - imageUrl = getRealPath(imageUrl); - } - plus.share.sendWithSystem({ - type, - pictures: imageUrl ? [imageUrl] : undefined, - content: summary, - href, - }, () => resolve(), errorCallback); - }, ShareWithSystemProtocols, ShareWithSystemOptions); - - const requestPayment = defineAsyncApi(API_REQUEST_PAYMENT, (params, { resolve, reject }) => { - const provider = params.provider; - const errorCallback = warpPlusErrorCallback(reject); - plus.payment.getChannels((services) => { - const service = services.find(({ id }) => id === provider); - if (!service) { - reject('service not found'); - } - else { - plus.payment.request(service, params.orderInfo, (res) => { - resolve(res); - }, errorCallback); - } - }, errorCallback); - }, RequestPaymentProtocol); - - function injectLifecycleHook(name, hook, publicThis, instance) { - if (shared.isFunction(hook)) { - vue.injectHook(name, hook.bind(publicThis), instance); - } - } - function initHooks(options, instance, publicThis) { - const mpType = options.mpType || publicThis.$mpType; - // 为了组件也可以监听部分生命周期,故不再判断mpType,统一添加on开头的生命周期 - Object.keys(options).forEach((name) => { - if (name.indexOf('on') === 0) { - const hooks = options[name]; - if (shared.isArray(hooks)) { - hooks.forEach((hook) => injectLifecycleHook(name, hook, publicThis, instance)); - } - else { - injectLifecycleHook(name, hooks, publicThis, instance); - } - } - }); - if (mpType === 'page') { - instance.__isVisible = true; - try { - invokeHook(publicThis, ON_LOAD, instance.attrs.__pageQuery); - delete instance.attrs.__pageQuery; - } - catch (e) { - console.error(e.message + LINEFEED + e.stack); - } - vue.nextTick(() => { - // 延迟onShow,保证组件的onShow也可以监听到 - invokeHook(publicThis, ON_SHOW); - }); - } - } +function restoreGlobal(newVue, newWeex, newPlus, newSetTimeout, newClearTimeout, newSetInterval, newClearInterval) { + // 确保部分全局变量 是 app-service 中的 + // 若首页 nvue 初始化比 app-service 快,导致框架处于该 nvue 环境下 + // plus 如果不用 app-service,资源路径会出问题 + // 若首页 nvue 被销毁,如 redirectTo 或 reLaunch,则这些全局功能会损坏 + // 设置 vue3 + // @ts-ignore 最终vue会被替换为vue + vue = newVue; + if (plus !== newPlus) { + if ((process.env.NODE_ENV !== 'production')) { + console.log(`[restoreGlobal][${Date.now()}]`); + } + weex = newWeex; + // @ts-ignore + plus = newPlus; + restoreOldSetStatusBarStyle(plus.navigator.setStatusBarStyle); + plus.navigator.setStatusBarStyle = newSetStatusBarStyle; + /* eslint-disable no-global-assign */ + // @ts-ignore + setTimeout = newSetTimeout; + // @ts-ignore + clearTimeout = newClearTimeout; + // @ts-ignore + setInterval = newSetInterval; + // @ts-ignore + clearInterval = newClearInterval; + } + __uniConfig.serviceReady = true; +} - function initRenderjs(options, instance) { - initModules(instance, options.$renderjs, options['$' + RENDERJS_MODULES]); - } - function initModules(instance, modules, moduleIds = {}) { - if (!shared.isArray(modules)) { - return; - } - const ownerId = instance.uid; - // 在vue的定制内核中,通过$wxsModules来判断事件函数源码中是否包含该模块调用 - // !$wxsModules.find(module => invokerSourceCode.indexOf('.' + module + '.') > -1) - const $wxsModules = (instance.$wxsModules || - (instance.$wxsModules = [])); - const ctx = instance.ctx; - modules.forEach((module) => { - if (moduleIds[module]) { - ctx[module] = proxyModule(ownerId, moduleIds[module], module); - $wxsModules.push(module); - } - else { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('initModules', modules, moduleIds)); - } - } - }); - } - function proxyModule(ownerId, moduleId, module) { - const target = {}; - return new Proxy(target, { - get(_, p) { - return (target[p] || - (target[p] = createModuleFunction(ownerId, moduleId, module, p))); - }, - }); - } - function createModuleFunction(ownerId, moduleId, module, name) { - const target = () => { }; - const toJSON = () => WXS_PROTOCOL + JSON.stringify([ownerId, moduleId, module + '.' + name]); - return new Proxy(target, { - get(_, p) { - if (p === 'toJSON') { - return toJSON; - } - return (target[p] || - (target[p] = createModuleFunction(ownerId, moduleId, module + '.' + name, p))); - }, - apply(_target, _thisArg, args) { - return (WXS_PROTOCOL + - JSON.stringify([ownerId, moduleId, module + '.' + name, [...args]])); - }, - }); - } +const providers = { + oauth(callback) { + plus.oauth.getServices((services) => { + services = services; + const provider = []; + services.forEach(({ id }) => { + provider.push(id); + }); + callback(null, provider); + }, (err) => { + err = err; + callback(err); + }); + }, + share(callback) { + plus.share.getServices((services) => { + services = services; + const provider = []; + services.forEach(({ id }) => { + provider.push(id); + }); + callback(null, provider); + }, (err) => { + callback(err); + }); + }, + payment(callback) { + plus.payment.getChannels((services) => { + const provider = []; + services.forEach(({ id }) => { + provider.push(id); + }); + callback(null, provider); + }, (err) => { + callback(err); + }); + }, + push(callback) { + if (typeof weex !== 'undefined' || typeof plus !== 'undefined') { + callback(null, [plus.push.getClientInfo().id]); + } + else { + callback(null, []); + } + }, +}; +const getProvider = defineAsyncApi(API_GET_PROVIDER, ({ service }, { resolve, reject }) => { + if (providers[service]) { + providers[service]((err, provider) => { + if (err) { + reject(err.message); + } + else { + resolve({ + service, + provider: provider, + }); + } + }); + } + else { + reject('service not found'); + } +}, GetProviderProtocol); + +let univerifyManager; +function getService(provider) { + return new Promise((resolve, reject) => { + plus.oauth.getServices((services) => { + const service = services.find(({ id }) => id === provider); + service ? resolve(service) : reject(new Error('provider not find')); + }, reject); + }); +} +const login = defineAsyncApi(API_LOGIN, (params, { resolve, reject }) => { + const provider = params.provider || 'weixin'; + const errorCallback = warpPlusErrorCallback(reject); + const authOptions = provider === 'apple' + ? { scope: 'email' } + : params.univerifyStyle + ? { + univerifyStyle: univerifyButtonsClickHandling(params.univerifyStyle, errorCallback), + } + : {}; + getService(provider) + .then((service) => { + function login() { + if (params.onlyAuthorize && provider === 'weixin') { + service.authorize(({ code }) => { + resolve({ + code, + authResult: '', + }); + }, errorCallback); + return; + } + service.login((res) => { + const authResult = res.target.authResult; + resolve({ + code: authResult.code, + authResult: authResult, + }); + }, errorCallback, authOptions); + } + // 先注销再登录 + // apple登录logout之后无法重新触发获取email,fullname;一键登录无logout + if (provider === 'apple' || provider === 'univerify') { + login(); + } + else { + service.logout(login, login); + } + }) + .catch(errorCallback); +}, LoginProtocol); +const baseGetUserInfo = (params, { resolve, reject }) => { + const provider = params.provider || 'weixin'; + const errorCallback = warpPlusErrorCallback(reject); + getService(provider) + .then((loginService) => { + loginService.getUserInfo((res) => { + let userInfo = { nickName: '' }; + if (provider === 'weixin') { + const wechatUserInfo = loginService.userInfo; + if (wechatUserInfo) + userInfo = { + openId: wechatUserInfo.openid, + nickName: wechatUserInfo.nickname, + gender: wechatUserInfo.sex, + city: wechatUserInfo.city, + province: wechatUserInfo.province, + country: wechatUserInfo.country, + avatarUrl: wechatUserInfo.headimgurl, + unionId: wechatUserInfo.unionid, + }; + } + else if (provider === 'apple') { + const appleInfo = loginService.appleInfo; + if (appleInfo) + userInfo = { + openId: appleInfo.user, + fullName: appleInfo.fullName, + email: appleInfo.email, + authorizationCode: appleInfo.authorizationCode, + identityToken: appleInfo.identityToken, + realUserStatus: appleInfo.realUserStatus, + }; + } + else { + userInfo = loginService.userInfo; + if (userInfo) { + userInfo.openId = + userInfo.openId || + userInfo.openid || + loginService.authResult.openid; + userInfo.nickName = userInfo.nickName || userInfo.nickname; + userInfo.avatarUrl = userInfo.avatarUrl || userInfo.headimgurl; + } + } + let result = {}; + // @ts-ignore + if (params.data && params.data.api_name === 'webapi_getuserinfo') { + result.data = { + data: JSON.stringify(userInfo), + rawData: '', + signature: '', + encryptedData: '', + iv: '', + }; + } + else { + result.userInfo = userInfo; + } + resolve(result); + }, errorCallback); + }) + .catch(() => { + reject('请先调用 uni.login'); + }); +}; +const getUserInfo = defineAsyncApi(API_GET_USER_INFO, baseGetUserInfo, GetUserInfoProtocol); +/** + * 获取用户信息-兼容 + */ +const getUserProfile = defineAsyncApi(API_GET_USER_PROFILE, baseGetUserInfo, GgetUserProfileProtocol); +const preLogin = defineAsyncApi(API_PRE_LOGIN, ({ provider }, { resolve, reject }) => { + const successCallback = warpPlusSuccessCallback(resolve); + const errorCallback = warpPlusErrorCallback(reject); + getService(provider) + .then((service) => service.preLogin(successCallback, errorCallback)) + .catch(errorCallback); +}, PreLoginProtocol, PreLoginOptions); +const _closeAuthView = () => getService('univerify').then((service) => service.closeAuthView()); +const closeAuthView = defineSyncApi(API_CLOSE_AUTH_VIEW, _closeAuthView); +const getCheckBoxState = defineAsyncApi(API_GET_CHECK_BOX_STATE, (_, { resolve, reject }) => { + const successCallback = warpPlusSuccessCallback(resolve); + const errorCallback = warpPlusErrorCallback(reject); + try { + getService('univerify').then((service) => { + // @ts-expect-error + const state = service.getCheckBoxState(); + successCallback({ state }); + }); + } + catch (error) { + errorCallback(error); + } +}); +/** + * 一键登录自定义登陆按钮点击处理 + */ +function univerifyButtonsClickHandling(univerifyStyle, errorCallback) { + if (isPlainObject(univerifyStyle) && + isPlainObject(univerifyStyle.buttons) && + toTypeString(univerifyStyle.buttons.list) === '[object Array]') { + univerifyStyle.buttons.list.forEach((button, index) => { + univerifyStyle.buttons.list[index].onclick = function () { + const res = { + code: '30008', + message: '用户点击了自定义按钮', + index, + provider: button.provider, + }; + isPlainObject(univerifyManager) + ? univerifyManager._triggerUniverifyButtonsClick(res) + : _closeAuthView().then(() => { + errorCallback(res); + }); + }; + }); + } + return univerifyStyle; +} +class UniverifyManager { + constructor() { + this.provider = 'univerify'; + this.eventName = 'api.univerifyButtonsClick'; + } + close() { + closeAuthView(); + } + login(options) { + login(this._getOptions(options)); + } + getCheckBoxState(options) { + getCheckBoxState(options); + } + preLogin(options) { + preLogin(this._getOptions(options)); + } + onButtonsClick(callback) { + UniServiceJSBridge.on(this.eventName, callback); + } + offButtonsClick(callback) { + UniServiceJSBridge.off(this.eventName, callback); + } + _triggerUniverifyButtonsClick(res) { + UniServiceJSBridge.emit(this.eventName, res); + } + _getOptions(options = {}) { + return extend({}, options, { provider: this.provider }); + } +} +const getUniverifyManager = defineSyncApi(API_GET_UNIVERIFY_MANAGER, () => { + return univerifyManager || (univerifyManager = new UniverifyManager()); +}); + +const registerRuntime = defineSyncApi('registerRuntime', (runtime) => { + // @ts-expect-error + extend(jsRuntime, runtime); +}); + +// 0:图文,1:纯文字,2:纯图片,3:音乐,4:视频,5:小程序 +const TYPES = { + 0: { + name: 'web', + title: '图文', + }, + 1: { + name: 'text', + title: '纯文字', + }, + 2: { + name: 'image', + title: '纯图片', + }, + 3: { + name: 'music', + title: '音乐', + }, + 4: { + name: 'video', + title: '视频', + }, + 5: { + name: 'miniProgram', + title: '小程序', + }, +}; +const parseParams = (args) => { + args.type = args.type || 0; + let { provider, type, title, summary: content, href, imageUrl, mediaUrl: media, scene, miniProgram, } = args; + if (typeof imageUrl === 'string' && imageUrl) { + imageUrl = getRealPath(imageUrl); + } + const shareType = TYPES[type]; + if (shareType) { + const sendMsg = { + provider, + type: shareType.name, + title, + content, + href, + pictures: [imageUrl], + thumbs: imageUrl ? [imageUrl] : undefined, + media, + miniProgram, + extra: { + scene, + }, + }; + if (provider === 'weixin' && (type === 1 || type === 2)) { + delete sendMsg.thumbs; + } + return sendMsg; + } + return '分享参数 type 不正确'; +}; +const sendShareMsg = function (service, params, resolve, reject, method = 'share') { + const errorCallback = warpPlusErrorCallback(reject); + service.send(params, () => { + resolve(); + }, errorCallback); +}; +const share = defineAsyncApi(API_SHREA, (params, { resolve, reject }) => { + const res = parseParams(params); + const errorCallback = warpPlusErrorCallback(reject); + if (typeof res === 'string') { + return reject(res); + } + else { + params = res; + } + plus.share.getServices((services) => { + const service = services.find(({ id }) => id === params.provider); + if (!service) { + reject('service not found'); + } + else { + if (service.authenticated) { + sendShareMsg(service, params, resolve, reject); + } + else { + service.authorize(() => sendShareMsg(service, params, resolve, reject), errorCallback); + } + } + }, errorCallback); +}, ShareProtocols, SahreOptions); +const shareWithSystem = defineAsyncApi(API_SHARE_WITH_SYSTEM, ({ type, imageUrl, summary, href }, { resolve, reject }) => { + const errorCallback = warpPlusErrorCallback(reject); + if (typeof imageUrl === 'string' && imageUrl) { + imageUrl = getRealPath(imageUrl); + } + plus.share.sendWithSystem({ + type, + pictures: imageUrl ? [imageUrl] : undefined, + content: summary, + href, + }, () => resolve(), errorCallback); +}, ShareWithSystemProtocols, ShareWithSystemOptions); + +const requestPayment = defineAsyncApi(API_REQUEST_PAYMENT, (params, { resolve, reject }) => { + const provider = params.provider; + const errorCallback = warpPlusErrorCallback(reject); + plus.payment.getChannels((services) => { + const service = services.find(({ id }) => id === provider); + if (!service) { + reject('service not found'); + } + else { + plus.payment.request(service, params.orderInfo, (res) => { + resolve(res); + }, errorCallback); + } + }, errorCallback); +}, RequestPaymentProtocol); + +function injectLifecycleHook(name, hook, publicThis, instance) { + if (isFunction(hook)) { + injectHook(name, hook.bind(publicThis), instance); + } +} +function initHooks(options, instance, publicThis) { + const mpType = options.mpType || publicThis.$mpType; + // 为了组件也可以监听部分生命周期,故不再判断mpType,统一添加on开头的生命周期 + Object.keys(options).forEach((name) => { + if (name.indexOf('on') === 0) { + const hooks = options[name]; + if (isArray$1(hooks)) { + hooks.forEach((hook) => injectLifecycleHook(name, hook, publicThis, instance)); + } + else { + injectLifecycleHook(name, hooks, publicThis, instance); + } + } + }); + if (mpType === 'page') { + instance.__isVisible = true; + try { + invokeHook(publicThis, ON_LOAD, instance.attrs.__pageQuery); + delete instance.attrs.__pageQuery; + } + catch (e) { + console.error(e.message + LINEFEED + e.stack); + } + nextTick(() => { + // 延迟onShow,保证组件的onShow也可以监听到 + invokeHook(publicThis, ON_SHOW); + }); + } +} - function initWxs(options, instance) { - initModules(instance, options.$wxs, options['$' + WXS_MODULES]); - } +function initRenderjs(options, instance) { + initModules(instance, options.$renderjs, options['$' + RENDERJS_MODULES]); +} +function initModules(instance, modules, moduleIds = {}) { + if (!isArray$1(modules)) { + return; + } + const ownerId = instance.uid; + // 在vue的定制内核中,通过$wxsModules来判断事件函数源码中是否包含该模块调用 + // !$wxsModules.find(module => invokerSourceCode.indexOf('.' + module + '.') > -1) + const $wxsModules = (instance.$wxsModules || + (instance.$wxsModules = [])); + const ctx = instance.ctx; + modules.forEach((module) => { + if (moduleIds[module]) { + ctx[module] = proxyModule(ownerId, moduleIds[module], module); + $wxsModules.push(module); + } + else { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('initModules', modules, moduleIds)); + } + } + }); +} +function proxyModule(ownerId, moduleId, module) { + const target = {}; + return new Proxy(target, { + get(_, p) { + return (target[p] || + (target[p] = createModuleFunction(ownerId, moduleId, module, p))); + }, + }); +} +function createModuleFunction(ownerId, moduleId, module, name) { + const target = () => { }; + const toJSON = () => WXS_PROTOCOL + JSON.stringify([ownerId, moduleId, module + '.' + name]); + return new Proxy(target, { + get(_, p) { + if (p === 'toJSON') { + return toJSON; + } + return (target[p] || + (target[p] = createModuleFunction(ownerId, moduleId, module + '.' + name, p))); + }, + apply(_target, _thisArg, args) { + return (WXS_PROTOCOL + + JSON.stringify([ownerId, moduleId, module + '.' + name, [...args]])); + }, + }); +} - function applyOptions(options, instance, publicThis) { - { - initWxs(options, instance); - initRenderjs(options, instance); - } - initHooks(options, instance, publicThis); - } +function initWxs(options, instance) { + initModules(instance, options.$wxs, options['$' + WXS_MODULES]); +} - function set(target, key, val) { - return (target[key] = val); - } +function applyOptions(options, instance, publicThis) { + { + initWxs(options, instance); + initRenderjs(options, instance); + } + initHooks(options, instance, publicThis); +} - function errorHandler(err, instance, info) { - if (!instance) { - throw err; - } - const app = getApp(); - if (!app || !app.$vm) { - throw err; - } - { - invokeHook(app.$vm, ON_ERROR, err); - } - } - function mergeAsArray(to, from) { - return to ? [...new Set([].concat(to, from))] : from; - } - function initOptionMergeStrategies(optionMergeStrategies) { - UniLifecycleHooks.forEach((name) => { - optionMergeStrategies[name] = mergeAsArray; - }); - } +function set(target, key, val) { + return (target[key] = val); +} - let realAtob; - const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; - if (typeof atob !== 'function') { - realAtob = function (str) { - str = String(str).replace(/[\t\n\f\r ]+/g, ''); - if (!b64re.test(str)) { - throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."); - } - // Adding the padding if missing, for semplicity - str += '=='.slice(2 - (str.length & 3)); - var bitmap; - var result = ''; - var r1; - var r2; - var i = 0; - for (; i < str.length;) { - bitmap = - (b64.indexOf(str.charAt(i++)) << 18) | - (b64.indexOf(str.charAt(i++)) << 12) | - ((r1 = b64.indexOf(str.charAt(i++))) << 6) | - (r2 = b64.indexOf(str.charAt(i++))); - result += - r1 === 64 - ? String.fromCharCode((bitmap >> 16) & 255) - : r2 === 64 - ? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255) - : String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255); - } - return result; - }; - } - else { - // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法 - realAtob = atob; - } - function b64DecodeUnicode(str) { - return decodeURIComponent(realAtob(str) - .split('') - .map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('')); - } - function getCurrentUserInfo() { - const token = uni.getStorageSync('uni_id_token') || ''; - const tokenArr = token.split('.'); - if (!token || tokenArr.length !== 3) { - return { - uid: null, - role: [], - permission: [], - tokenExpired: 0, - }; - } - let userInfo; - try { - userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); - } - catch (error) { - throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message); - } - userInfo.tokenExpired = userInfo.exp * 1000; - delete userInfo.exp; - delete userInfo.iat; - return userInfo; - } - function uniIdMixin(globalProperties) { - globalProperties.uniIDHasRole = function (roleId) { - const { role } = getCurrentUserInfo(); - return role.indexOf(roleId) > -1; - }; - globalProperties.uniIDHasPermission = function (permissionId) { - const { permission } = getCurrentUserInfo(); - return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1; - }; - globalProperties.uniIDTokenValid = function () { - const { tokenExpired } = getCurrentUserInfo(); - return tokenExpired > Date.now(); - }; - } +function errorHandler(err, instance, info) { + if (!instance) { + throw err; + } + const app = getApp(); + if (!app || !app.$vm) { + throw err; + } + { + invokeHook(app.$vm, ON_ERROR, err); + } +} +function mergeAsArray(to, from) { + return to ? [...new Set([].concat(to, from))] : from; +} +function initOptionMergeStrategies(optionMergeStrategies) { + UniLifecycleHooks.forEach((name) => { + optionMergeStrategies[name] = mergeAsArray; + }); +} - function initApp(app) { - const appConfig = app._context.config; - if (shared.isFunction(app._component.onError)) { - appConfig.errorHandler = errorHandler; - } - initOptionMergeStrategies(appConfig.optionMergeStrategies); - const globalProperties = appConfig.globalProperties; - { - uniIdMixin(globalProperties); - } - { - globalProperties.$set = set; - globalProperties.$applyOptions = applyOptions; - } - } +let realAtob; +const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; +if (typeof atob !== 'function') { + realAtob = function (str) { + str = String(str).replace(/[\t\n\f\r ]+/g, ''); + if (!b64re.test(str)) { + throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."); + } + // Adding the padding if missing, for semplicity + str += '=='.slice(2 - (str.length & 3)); + var bitmap; + var result = ''; + var r1; + var r2; + var i = 0; + for (; i < str.length;) { + bitmap = + (b64.indexOf(str.charAt(i++)) << 18) | + (b64.indexOf(str.charAt(i++)) << 12) | + ((r1 = b64.indexOf(str.charAt(i++))) << 6) | + (r2 = b64.indexOf(str.charAt(i++))); + result += + r1 === 64 + ? String.fromCharCode((bitmap >> 16) & 255) + : r2 === 64 + ? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255) + : String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255); + } + return result; + }; +} +else { + // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法 + realAtob = atob; +} +function b64DecodeUnicode(str) { + return decodeURIComponent(realAtob(str) + .split('') + .map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join('')); +} +function getCurrentUserInfo() { + const token = uni.getStorageSync('uni_id_token') || ''; + const tokenArr = token.split('.'); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0, + }; + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } + catch (error) { + throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message); + } + userInfo.tokenExpired = userInfo.exp * 1000; + delete userInfo.exp; + delete userInfo.iat; + return userInfo; +} +function uniIdMixin(globalProperties) { + globalProperties.uniIDHasRole = function (roleId) { + const { role } = getCurrentUserInfo(); + return role.indexOf(roleId) > -1; + }; + globalProperties.uniIDHasPermission = function (permissionId) { + const { permission } = getCurrentUserInfo(); + return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1; + }; + globalProperties.uniIDTokenValid = function () { + const { tokenExpired } = getCurrentUserInfo(); + return tokenExpired > Date.now(); + }; +} - let isInitEntryPage = false; - function initEntry() { - if (isInitEntryPage) { - return; - } - isInitEntryPage = true; - let entryPagePath; - let entryPageQuery; - const weexPlus = weex.requireModule('plus'); - if (weexPlus.getRedirectInfo) { - const { path, query, referrerInfo } = parseRedirectInfo(); - if (path) { - entryPagePath = path; - entryPageQuery = query; - } - __uniConfig.referrerInfo = referrerInfo; - } - else { - const argsJsonStr = plus.runtime.arguments; - if (!argsJsonStr) { - return; - } - try { - const args = JSON.parse(argsJsonStr); - entryPagePath = args.path || args.pathName; - entryPageQuery = args.query ? '?' + args.query : ''; - } - catch (e) { } - } - if (!entryPagePath || entryPagePath === __uniConfig.entryPagePath) { - if (entryPageQuery) { - __uniConfig.entryPageQuery = entryPageQuery; - } - return; - } - const entryRoute = addLeadingSlash(entryPagePath); - const routeOptions = getRouteOptions(entryRoute); - if (!routeOptions) { - return; - } - if (!routeOptions.meta.isTabBar) { - __uniConfig.realEntryPagePath = - __uniConfig.realEntryPagePath || __uniConfig.entryPagePath; - } - __uniConfig.entryPagePath = entryPagePath; - __uniConfig.entryPageQuery = entryPageQuery; - } +function initApp(app) { + const appConfig = app._context.config; + if (isFunction(app._component.onError)) { + appConfig.errorHandler = errorHandler; + } + initOptionMergeStrategies(appConfig.optionMergeStrategies); + const globalProperties = appConfig.globalProperties; + { + uniIdMixin(globalProperties); + } + { + globalProperties.$set = set; + globalProperties.$applyOptions = applyOptions; + } +} - function initTabBar() { - const { tabBar } = __uniConfig; - const len = tabBar && tabBar.list && tabBar.list.length; - if (!len) { - return; - } - const { entryPagePath } = __uniConfig; - tabBar.selectedIndex = 0; - const selected = tabBar.list.findIndex((page) => page.pagePath === entryPagePath); - tabBar$1.init(tabBar, (item, index) => { - uni.switchTab({ - url: addLeadingSlash(item.pagePath), - openType: 'switchTab', - from: 'tabBar', - success() { - invokeHook(ON_TAB_ITEM_TAP, { - index, - text: item.text, - pagePath: item.pagePath, - }); - }, - }); - }); - if (selected !== -1) { - // 取当前 tab 索引值 - tabBar.selectedIndex = selected; - selected !== 0 && tabBar$1.switchTab(entryPagePath); - } - } +let isInitEntryPage = false; +function initEntry() { + if (isInitEntryPage) { + return; + } + isInitEntryPage = true; + let entryPagePath; + let entryPageQuery; + const weexPlus = weex.requireModule('plus'); + if (weexPlus.getRedirectInfo) { + const { path, query, referrerInfo } = parseRedirectInfo(); + if (path) { + entryPagePath = path; + entryPageQuery = query; + } + __uniConfig.referrerInfo = referrerInfo; + } + else { + const argsJsonStr = plus.runtime.arguments; + if (!argsJsonStr) { + return; + } + try { + const args = JSON.parse(argsJsonStr); + entryPagePath = args.path || args.pathName; + entryPageQuery = args.query ? '?' + args.query : ''; + } + catch (e) { } + } + if (!entryPagePath || entryPagePath === __uniConfig.entryPagePath) { + if (entryPageQuery) { + __uniConfig.entryPageQuery = entryPageQuery; + } + return; + } + const entryRoute = addLeadingSlash(entryPagePath); + const routeOptions = getRouteOptions(entryRoute); + if (!routeOptions) { + return; + } + if (!routeOptions.meta.isTabBar) { + __uniConfig.realEntryPagePath = + __uniConfig.realEntryPagePath || __uniConfig.entryPagePath; + } + __uniConfig.entryPagePath = entryPagePath; + __uniConfig.entryPageQuery = entryPageQuery; +} - const sendHostEvent = sendNativeEvent; - const API_NAVIGATE_TO_MINI_PROGRAM = 'navigateToMiniProgram'; - const navigateToMiniProgram = defineAsyncApi(API_NAVIGATE_TO_MINI_PROGRAM, (data, { resolve, reject }) => { - sendHostEvent('navigateToUniMP', data, (res) => { - if (res.errMsg && res.errMsg.indexOf(':ok') === -1) { - return reject(res.errMsg.split(' ')[1]); - } - resolve(); - }); - }); - const hostEventCallbacks = []; - function onHostEventReceive(fn) { - hostEventCallbacks.push(fn); - } - const onNativeEventReceive = onHostEventReceive; - function invokeHostEvent(event, data) { - hostEventCallbacks.forEach((fn) => fn(event, data)); - } +function initTabBar() { + const { tabBar } = __uniConfig; + const len = tabBar && tabBar.list && tabBar.list.length; + if (!len) { + return; + } + const { entryPagePath } = __uniConfig; + tabBar.selectedIndex = 0; + const selected = tabBar.list.findIndex((page) => page.pagePath === entryPagePath); + tabBar$1.init(tabBar, (item, index) => { + uni.switchTab({ + url: addLeadingSlash(item.pagePath), + openType: 'switchTab', + from: 'tabBar', + success() { + invokeHook(ON_TAB_ITEM_TAP, { + index, + text: item.text, + pagePath: item.pagePath, + }); + }, + }); + }); + if (selected !== -1) { + // 取当前 tab 索引值 + tabBar.selectedIndex = selected; + selected !== 0 && tabBar$1.switchTab(entryPagePath); + } +} - const downgrade = plus.os.name === 'Android' && parseInt(plus.os.version) < 6; - const ANI_SHOW = downgrade ? 'slide-in-right' : 'pop-in'; - const ANI_DURATION = 300; - const ANI_CLOSE = downgrade ? 'slide-out-right' : 'pop-out'; - const VIEW_WEBVIEW_PATH = '_www/__uniappview.html'; - const WEBVIEW_ID_PREFIX = 'webviewId'; - const SDK_UNI_MP_NATIVE_EVENT = 'uniMPNativeEvent'; - - function initGlobalEvent() { - const plusGlobalEvent = plus.globalEvent; - const weexGlobalEvent = weex.requireModule('globalEvent'); - const emit = UniServiceJSBridge.emit; - if (weex.config.preload) { - plus.key.addEventListener(EVENT_BACKBUTTON, backbuttonListener); - } - else { - plusGlobalEvent.addEventListener('splashclosed', () => { - plus.key.addEventListener(EVENT_BACKBUTTON, backbuttonListener); - }); - } - plusGlobalEvent.addEventListener('pause', () => { - emit(ON_APP_ENTER_BACKGROUND); - }); - plusGlobalEvent.addEventListener('resume', () => { - const info = parseRedirectInfo(); - if (info && info.userAction) { - initEnterOptions(info); - } - emit(ON_APP_ENTER_FOREGROUND, getEnterOptions()); - }); - weexGlobalEvent.addEventListener('uistylechange', function (event) { - const args = { - theme: event.uistyle, - }; - emit(ON_THEME_CHANGE, args); - }); - let keyboardHeightChange = 0; - plusGlobalEvent.addEventListener('KeyboardHeightChange', function (event) { - // 安卓设备首次获取高度为 0 - if (keyboardHeightChange !== event.height) { - keyboardHeightChange = event.height; - emit(ON_KEYBOARD_HEIGHT_CHANGE, { - height: keyboardHeightChange, - }); - } - }); - weexGlobalEvent.addEventListener(SDK_UNI_MP_NATIVE_EVENT, function (res) { - if (res && res.event) { - invokeHostEvent(res.event, res.data); - } - }); - plusGlobalEvent.addEventListener('plusMessage', subscribePlusMessage); - // nvue webview post message - plusGlobalEvent.addEventListener('WebviewPostMessage', subscribePlusMessage); - } - function subscribePlusMessage({ data, }) { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('plusMessage', data)); - } - if (data && data.type) { - UniServiceJSBridge.subscribeHandler('plusMessage.' + data.type, data.args); - } - } - function onPlusMessage(type, callback, once = false) { - UniServiceJSBridge.subscribe('plusMessage.' + type, callback, once); - } - // function initEnterReLaunch(info: RedirectInfo) { - // __uniConfig.realEntryPagePath = - // __uniConfig.realEntryPagePath || __uniConfig.entryPagePath - // __uniConfig.entryPagePath = info.path - // __uniConfig.entryPageQuery = info.query - // $reLaunch( - // { url: addLeadingSlash(info.path) + info.query }, - // { resolve() {}, reject() {} } - // ) - // } - - function initAppLaunch(appVm) { - const { entryPagePath, entryPageQuery, referrerInfo } = __uniConfig; - const args = shared.extend({ - // 为了让 uni-stat 在 uni.onLaunch 中可以 mixin - app: { mixin: appVm.$.appContext.app.mixin }, - }, initLaunchOptions({ - path: entryPagePath, - query: entryPageQuery, - referrerInfo: referrerInfo, - })); - injectAppLaunchHooks(appVm.$); - invokeHook(appVm, ON_LAUNCH, args); - invokeHook(appVm, ON_SHOW, args); - // https://tower.im/teams/226535/todos/16905/ - const getAppState = weex.requireModule('plus').getAppState; - const appState = getAppState && Number(getAppState()); - if (appState === 2) { - invokeHook(appVm, ON_HIDE, args); - } - } +const sendHostEvent = sendNativeEvent; +const API_NAVIGATE_TO_MINI_PROGRAM = 'navigateToMiniProgram'; +const navigateToMiniProgram = defineAsyncApi(API_NAVIGATE_TO_MINI_PROGRAM, (data, { resolve, reject }) => { + sendHostEvent('navigateToUniMP', data, (res) => { + if (res.errMsg && res.errMsg.indexOf(':ok') === -1) { + return reject(res.errMsg.split(' ')[1]); + } + resolve(); + }); +}); +const hostEventCallbacks = []; +function onHostEventReceive(fn) { + hostEventCallbacks.push(fn); +} +const onNativeEventReceive = onHostEventReceive; +function invokeHostEvent(event, data) { + hostEventCallbacks.forEach((fn) => fn(event, data)); +} - // 统一处理路径 - function getPath(path) { - path = path.replace(/\/$/, ''); - return path.indexOf('_') === 0 - ? plus.io.convertLocalFileSystemURL(path) - : path; - } - function clearTempFile() { - const basePath = getPath(TEMP_PATH_BASE); - const tempPath = getPath(TEMP_PATH); - // 获取父目录 - const dirParts = tempPath.split('/'); - dirParts.pop(); - const dirPath = dirParts.join('/'); - plus.io.resolveLocalFileSystemURL(plus.io.convertAbsoluteFileSystem(dirPath), (entry) => { - const reader = entry.createReader(); - reader.readEntries(function (entry) { - // plus.d.ts 类型不对 - const entries = entry; - if (entries && entries.length) { - entries.forEach(function (entry) { - if (entry.isDirectory && - entry.fullPath.indexOf(basePath) === 0 && - entry.fullPath.indexOf(tempPath) !== 0) { - entry.removeRecursively(); - } - }); - } - }); - }); - } +const downgrade = plus.os.name === 'Android' && parseInt(plus.os.version) < 6; +const ANI_SHOW = downgrade ? 'slide-in-right' : 'pop-in'; +const ANI_DURATION = 300; +const ANI_CLOSE = downgrade ? 'slide-out-right' : 'pop-out'; +const VIEW_WEBVIEW_PATH = '_www/__uniappview.html'; +const WEBVIEW_ID_PREFIX = 'webviewId'; +const SDK_UNI_MP_NATIVE_EVENT = 'uniMPNativeEvent'; + +function initGlobalEvent() { + const plusGlobalEvent = plus.globalEvent; + const weexGlobalEvent = weex.requireModule('globalEvent'); + const emit = UniServiceJSBridge.emit; + if (weex.config.preload) { + plus.key.addEventListener(EVENT_BACKBUTTON, backbuttonListener); + } + else { + plusGlobalEvent.addEventListener('splashclosed', () => { + plus.key.addEventListener(EVENT_BACKBUTTON, backbuttonListener); + }); + } + plusGlobalEvent.addEventListener('pause', () => { + emit(ON_APP_ENTER_BACKGROUND); + }); + plusGlobalEvent.addEventListener('resume', () => { + const info = parseRedirectInfo(); + if (info && info.userAction) { + initEnterOptions(info); + } + emit(ON_APP_ENTER_FOREGROUND, getEnterOptions()); + }); + weexGlobalEvent.addEventListener('uistylechange', function (event) { + const args = { + theme: event.uistyle, + }; + emit(ON_THEME_CHANGE, args); + }); + let keyboardHeightChange = 0; + plusGlobalEvent.addEventListener('KeyboardHeightChange', function (event) { + // 安卓设备首次获取高度为 0 + if (keyboardHeightChange !== event.height) { + keyboardHeightChange = event.height; + emit(ON_KEYBOARD_HEIGHT_CHANGE, { + height: keyboardHeightChange, + }); + } + }); + weexGlobalEvent.addEventListener(SDK_UNI_MP_NATIVE_EVENT, function (res) { + if (res && res.event) { + invokeHostEvent(res.event, res.data); + } + }); + plusGlobalEvent.addEventListener('plusMessage', subscribePlusMessage); + // nvue webview post message + plusGlobalEvent.addEventListener('WebviewPostMessage', subscribePlusMessage); +} +function subscribePlusMessage({ data, }) { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('plusMessage', data)); + } + if (data && data.type) { + UniServiceJSBridge.subscribeHandler('plusMessage.' + data.type, data.args); + } +} +function onPlusMessage(type, callback, once = false) { + UniServiceJSBridge.subscribe('plusMessage.' + type, callback, once); +} +// function initEnterReLaunch(info: RedirectInfo) { +// __uniConfig.realEntryPagePath = +// __uniConfig.realEntryPagePath || __uniConfig.entryPagePath +// __uniConfig.entryPagePath = info.path +// __uniConfig.entryPageQuery = info.query +// $reLaunch( +// { url: addLeadingSlash(info.path) + info.query }, +// { resolve() {}, reject() {} } +// ) +// } + +function initAppLaunch(appVm) { + const { entryPagePath, entryPageQuery, referrerInfo } = __uniConfig; + const args = extend({ + // 为了让 uni-stat 在 uni.onLaunch 中可以 mixin + app: { mixin: appVm.$.appContext.app.mixin }, + }, initLaunchOptions({ + path: entryPagePath, + query: entryPageQuery, + referrerInfo: referrerInfo, + })); + injectAppLaunchHooks(appVm.$); + invokeHook(appVm, ON_LAUNCH, args); + invokeHook(appVm, ON_SHOW, args); + // https://tower.im/teams/226535/todos/16905/ + const getAppState = weex.requireModule('plus').getAppState; + const appState = getAppState && Number(getAppState()); + if (appState === 2) { + invokeHook(appVm, ON_HIDE, args); + } +} - let vueApp; - function getVueApp() { - return vueApp; - } - function initVueApp(appVm) { - const appContext = appVm.$.appContext; - vueApp = shared.extend(appContext.app, { - mountPage(pageComponent, pageProps, pageContainer) { - const vnode = vue.createVNode(pageComponent, pageProps); - // store app context on the root VNode. - // this will be set on the root instance on initial mount. - vnode.appContext = appContext; - vnode.__page_container__ = pageContainer; - vue.render(vnode, pageContainer); - const publicThis = vnode.component.proxy; - publicThis.__page_container__ = pageContainer; - return publicThis; - }, - unmountPage: (pageInstance) => { - const { __page_container__ } = pageInstance; - if (__page_container__) { - __page_container__.isUnmounted = true; - vue.render(null, __page_container__); - } - }, - }); - } +// 统一处理路径 +function getPath(path) { + path = path.replace(/\/$/, ''); + return path.indexOf('_') === 0 + ? plus.io.convertLocalFileSystemURL(path) + : path; +} +function clearTempFile() { + const basePath = getPath(TEMP_PATH_BASE); + const tempPath = getPath(TEMP_PATH); + // 获取父目录 + const dirParts = tempPath.split('/'); + dirParts.pop(); + const dirPath = dirParts.join('/'); + plus.io.resolveLocalFileSystemURL(plus.io.convertAbsoluteFileSystem(dirPath), (entry) => { + const reader = entry.createReader(); + reader.readEntries(function (entry) { + // plus.d.ts 类型不对 + const entries = entry; + if (entries && entries.length) { + entries.forEach(function (entry) { + if (entry.isDirectory && + entry.fullPath.indexOf(basePath) === 0 && + entry.fullPath.indexOf(tempPath) !== 0) { + entry.removeRecursively(); + } + }); + } + }); + }); +} - const pages = []; - function addCurrentPage(page) { - pages.push(page); - } - function getPageById(id) { - return pages.find((page) => page.$page.id === id); - } - function getAllPages() { - return pages; - } - function getCurrentPages$1() { - const curPages = []; - pages.forEach((page) => { - if (page.$.__isTabBar) { - if (page.$.__isActive) { - curPages.push(page); - } - } - else { - curPages.push(page); - } - }); - return curPages; - } - function removeCurrentPage() { - const page = getCurrentPage(); - if (!page) { - return; - } - removePage(page); - } - function removePage(curPage) { - const index = pages.findIndex((page) => page === curPage); - if (index === -1) { - return; - } - if (!curPage.$page.meta.isNVue) { - getVueApp().unmountPage(curPage); - } - pages.splice(index, 1); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('removePage', curPage.$page)); - } - } +let vueApp; +function getVueApp() { + return vueApp; +} +function initVueApp(appVm) { + const appContext = appVm.$.appContext; + vueApp = extend(appContext.app, { + mountPage(pageComponent, pageProps, pageContainer) { + const vnode = createVNode(pageComponent, pageProps); + // store app context on the root VNode. + // this will be set on the root instance on initial mount. + vnode.appContext = appContext; + vnode.__page_container__ = pageContainer; + render(vnode, pageContainer); + const publicThis = vnode.component.proxy; + publicThis.__page_container__ = pageContainer; + return publicThis; + }, + unmountPage: (pageInstance) => { + const { __page_container__ } = pageInstance; + if (__page_container__) { + __page_container__.isUnmounted = true; + render(null, __page_container__); + } + }, + }); +} - function onNodeEvent(nodeId, evt, pageNode) { - pageNode.fireEvent(nodeId, evt); - } +const pages = []; +function addCurrentPage(page) { + pages.push(page); +} +function getPageById(id) { + return pages.find((page) => page.$page.id === id); +} +function getAllPages() { + return pages; +} +function getCurrentPages$1() { + const curPages = []; + pages.forEach((page) => { + if (page.$.__isTabBar) { + if (page.$.__isActive) { + curPages.push(page); + } + } + else { + curPages.push(page); + } + }); + return curPages; +} +function removeCurrentPage() { + const page = getCurrentPage(); + if (!page) { + return; + } + removePage(page); +} +function removePage(curPage) { + const index = pages.findIndex((page) => page === curPage); + if (index === -1) { + return; + } + if (!curPage.$page.meta.isNVue) { + getVueApp().unmountPage(curPage); + } + pages.splice(index, 1); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('removePage', curPage.$page)); + } +} - function onVdSync(actions, pageId) { - // 从所有pages中获取 - const page = getPageById(parseInt(pageId)); - if (!page) { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('onVdSync', 'page', pageId, 'not found')); - } - return; - } - const pageNode = page.__page_container__; - actions.forEach((action) => { - switch (action[0]) { - case ACTION_TYPE_EVENT: - onNodeEvent(action[1], action[2], pageNode); - break; - } - }); - } +function onNodeEvent(nodeId, evt, pageNode) { + pageNode.fireEvent(nodeId, evt); +} - const _adDataCache = {}; - function getAdData(data, onsuccess, onerror) { - const { adpid, width } = data; - const key = adpid + '-' + width; - const adDataList = _adDataCache[key]; - if (adDataList && adDataList.length > 0) { - onsuccess(adDataList.splice(0, 1)[0]); - return; - } - plus.ad.getAds(data, (res) => { - const list = res.ads; - onsuccess(list.splice(0, 1)[0]); - _adDataCache[key] = adDataList ? adDataList.concat(list) : list; - }, (err) => { - onerror({ - errCode: err.code, - errMsg: err.message, - }); - }); - } - function subscribeAd() { - registerServiceMethod('getAdData', (args, resolve) => { - getAdData(args, (res) => { - resolve({ - code: 0, - data: res, - }); - }, (err) => { - resolve({ - code: 1, - message: err, - }); - }); - }); - } +function onVdSync(actions, pageId) { + // 从所有pages中获取 + const page = getPageById(parseInt(pageId)); + if (!page) { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('onVdSync', 'page', pageId, 'not found')); + } + return; + } + const pageNode = page.__page_container__; + actions.forEach((action) => { + switch (action[0]) { + case ACTION_TYPE_EVENT: + onNodeEvent(action[1], action[2], pageNode); + break; + } + }); +} - const API_ROUTE = [ - 'switchTab', - 'reLaunch', - 'redirectTo', - 'navigateTo', - 'navigateBack', - ]; - function subscribeNavigator() { - API_ROUTE.forEach((name) => { - registerServiceMethod(name, (args) => { - uni[name](shared.extend(args, { - fail(res) { - console.error(res.errMsg); - }, - })); - }); - }); - } +const _adDataCache = {}; +function getAdData(data, onsuccess, onerror) { + const { adpid, width } = data; + const key = adpid + '-' + width; + const adDataList = _adDataCache[key]; + if (adDataList && adDataList.length > 0) { + onsuccess(adDataList.splice(0, 1)[0]); + return; + } + plus.ad.getAds(data, (res) => { + const list = res.ads; + onsuccess(list.splice(0, 1)[0]); + _adDataCache[key] = adDataList ? adDataList.concat(list) : list; + }, (err) => { + onerror({ + errCode: err.code, + errMsg: err.message, + }); + }); +} +function subscribeAd() { + registerServiceMethod('getAdData', (args, resolve) => { + getAdData(args, (res) => { + resolve({ + code: 0, + data: res, + }); + }, (err) => { + resolve({ + code: 1, + message: err, + }); + }); + }); +} - function initNVue(webviewStyle, routeMeta, path) { - if (path && routeMeta.isNVue) { - webviewStyle.uniNView = { - path, - defaultFontSize: __uniConfig.defaultFontSize, - viewport: __uniConfig.viewport, - }; - } - } +const API_ROUTE = [ + 'switchTab', + 'reLaunch', + 'redirectTo', + 'navigateTo', + 'navigateBack', +]; +function subscribeNavigator() { + API_ROUTE.forEach((name) => { + registerServiceMethod(name, (args) => { + uni[name](extend(args, { + fail(res) { + console.error(res.errMsg); + }, + })); + }); + }); +} - const colorRE = /^#[a-z0-9]{6}$/i; - function isColor(color) { - return color && (colorRE.test(color) || color === 'transparent'); - } +function initNVue(webviewStyle, routeMeta, path) { + if (path && routeMeta.isNVue) { + webviewStyle.uniNView = { + path, + defaultFontSize: __uniConfig.defaultFontSize, + viewport: __uniConfig.viewport, + }; + } +} - function initBackgroundColor(webviewStyle, routeMeta) { - const { backgroundColor } = routeMeta; - if (!backgroundColor) { - return; - } - if (!isColor(backgroundColor)) { - return; - } - if (!webviewStyle.background) { - webviewStyle.background = backgroundColor; - } - if (!webviewStyle.backgroundColorTop) { - webviewStyle.backgroundColorTop = backgroundColor; - } - } +const colorRE = /^#[a-z0-9]{6}$/i; +function isColor(color) { + return color && (colorRE.test(color) || color === 'transparent'); +} - function initPopGesture(webviewStyle, routeMeta) { - // 不支持 hide - if (webviewStyle.popGesture === 'hide') { - delete webviewStyle.popGesture; - } - // 似乎没用了吧?记得是之前流应用时,需要 appback 的逻辑 - if (routeMeta.isQuit) { - webviewStyle.popGesture = (plus.os.name === 'iOS' ? 'appback' : 'none'); - } - } +function initBackgroundColor(webviewStyle, routeMeta) { + const { backgroundColor } = routeMeta; + if (!backgroundColor) { + return; + } + if (!isColor(backgroundColor)) { + return; + } + if (!webviewStyle.background) { + webviewStyle.background = backgroundColor; + } + if (!webviewStyle.backgroundColorTop) { + webviewStyle.backgroundColorTop = backgroundColor; + } +} - function initPullToRefresh(webviewStyle, routeMeta) { - if (!routeMeta.enablePullDownRefresh) { - return; - } - const pullToRefresh = normalizePullToRefreshRpx(shared.extend({}, plus.os.name === 'Android' - ? defaultAndroidPullToRefresh - : defaultPullToRefresh, routeMeta.pullToRefresh)); - webviewStyle.pullToRefresh = initWebviewPullToRefreshI18n(pullToRefresh, routeMeta); - } - function initWebviewPullToRefreshI18n(pullToRefresh, routeMeta) { - const i18nResult = initPullToRefreshI18n(pullToRefresh); - if (!i18nResult) { - return pullToRefresh; - } - const [contentdownI18n, contentoverI18n, contentrefreshI18n] = i18nResult; - if (contentdownI18n || contentoverI18n || contentrefreshI18n) { - uni.onLocaleChange(() => { - const webview = plus.webview.getWebviewById(routeMeta.id + ''); - if (!webview) { - return; - } - const newPullToRefresh = { - support: true, - }; - if (contentdownI18n) { - newPullToRefresh.contentdown = { - caption: pullToRefresh.contentdown.caption, - }; - } - if (contentoverI18n) { - newPullToRefresh.contentover = { - caption: pullToRefresh.contentover.caption, - }; - } - if (contentrefreshI18n) { - newPullToRefresh.contentrefresh = { - caption: pullToRefresh.contentrefresh.caption, - }; - } - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('updateWebview', webview.id, newPullToRefresh)); - } - webview.setStyle({ - pullToRefresh: newPullToRefresh, - }); - }); - } - return pullToRefresh; - } - const defaultAndroidPullToRefresh = { support: true, style: 'circle' }; - const defaultPullToRefresh = { - support: true, - style: 'default', - height: '50px', - range: '200px', - contentdown: { - caption: '', - }, - contentover: { - caption: '', - }, - contentrefresh: { - caption: '', - }, - }; - - function initTitleNView(webviewStyle, routeMeta) { - const { navigationBar } = routeMeta; - if (navigationBar.style === 'custom') { - return false; - } - let autoBackButton = true; - if (routeMeta.isQuit) { - autoBackButton = false; - } - const titleNView = { - autoBackButton, - }; - Object.keys(navigationBar).forEach((name) => { - const value = navigationBar[name]; - if (name === 'backgroundColor') { - titleNView.backgroundColor = isColor(value) - ? value - : BACKGROUND_COLOR; - } - else if (name === 'titleImage' && value) { - titleNView.tags = createTitleImageTags(value); - } - else if (name === 'buttons' && shared.isArray(value)) { - titleNView.buttons = value.map((button, index) => { - button.onclick = createTitleNViewBtnClick(index); - return button; - }); - } - else { - titleNView[name] = - value; - } - }); - webviewStyle.titleNView = initTitleNViewI18n(titleNView, routeMeta); - } - function initTitleNViewI18n(titleNView, routeMeta) { - const i18nResult = initNavigationBarI18n(titleNView); - if (!i18nResult) { - return titleNView; - } - const [titleTextI18n, searchInputPlaceholderI18n] = i18nResult; - if (titleTextI18n || searchInputPlaceholderI18n) { - uni.onLocaleChange(() => { - const webview = plus.webview.getWebviewById(routeMeta.id + ''); - if (!webview) { - return; - } - const newTitleNView = {}; - if (titleTextI18n) { - newTitleNView.titleText = titleNView.titleText; - } - if (searchInputPlaceholderI18n) { - newTitleNView.searchInput = { - placeholder: titleNView.searchInput.placeholder, - }; - } - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('updateWebview', webview.id, newTitleNView)); - } - webview.setStyle({ - titleNView: newTitleNView, - }); - }); - } - return titleNView; - } - function createTitleImageTags(titleImage) { - return [ - { - tag: 'img', - src: titleImage, - position: { - left: 'auto', - top: 'auto', - width: 'auto', - height: '26px', - }, - }, - ]; - } - function createTitleNViewBtnClick(index) { - return function onClick(btn) { - btn.index = index; - invokeHook(ON_NAVIGATION_BAR_BUTTON_TAP, btn); - }; - } +function initPopGesture(webviewStyle, routeMeta) { + // 不支持 hide + if (webviewStyle.popGesture === 'hide') { + delete webviewStyle.popGesture; + } + // 似乎没用了吧?记得是之前流应用时,需要 appback 的逻辑 + if (routeMeta.isQuit) { + webviewStyle.popGesture = (plus.os.name === 'iOS' ? 'appback' : 'none'); + } +} - function parseWebviewStyle(path, routeMeta, webview) { - const webviewStyle = { - bounce: 'vertical', - }; - Object.keys(routeMeta).forEach((name) => { - if (WEBVIEW_STYLE_BLACKLIST.indexOf(name) === -1) { - webviewStyle[name] = - routeMeta[name]; - } - }); - if (webview.id !== '1') { - // 首页 nvue 已经在 manifest.json 中设置了 uniNView,不能再次设置,否则会二次加载 - initNVue(webviewStyle, routeMeta, path); - } - initPopGesture(webviewStyle, routeMeta); - initBackgroundColor(webviewStyle, routeMeta); - initTitleNView(webviewStyle, routeMeta); - initPullToRefresh(webviewStyle, routeMeta); - return webviewStyle; - } - const WEBVIEW_STYLE_BLACKLIST = [ - 'id', - 'route', - 'isNVue', - 'isQuit', - 'isEntry', - 'isTabBar', - 'tabBarIndex', - 'windowTop', - 'topWindow', - 'leftWindow', - 'rightWindow', - 'maxWidth', - 'usingComponents', - 'disableScroll', - 'enablePullDownRefresh', - 'navigationBar', - 'pullToRefresh', - 'onReachBottomDistance', - 'pageOrientation', - 'backgroundColor', - ]; - - let id = 2; - function getWebviewId() { - return id; - } - function genWebviewId() { - return id++; - } - function encode(val) { - return val; - } - function initUniPageUrl(path, query) { - const queryString = query ? stringifyQuery$1(query, encode) : ''; - return { - path: path.substr(1), - query: queryString ? queryString.substr(1) : queryString, - }; - } - function initDebugRefresh(isTab, path, query) { - const queryString = query ? stringifyQuery$1(query, encode) : ''; - return { - isTab, - arguments: JSON.stringify({ - path: path.substr(1), - query: queryString ? queryString.substr(1) : queryString, - }), - }; - } +function initPullToRefresh(webviewStyle, routeMeta) { + if (!routeMeta.enablePullDownRefresh) { + return; + } + const pullToRefresh = normalizePullToRefreshRpx(extend({}, plus.os.name === 'Android' + ? defaultAndroidPullToRefresh + : defaultPullToRefresh, routeMeta.pullToRefresh)); + webviewStyle.pullToRefresh = initWebviewPullToRefreshI18n(pullToRefresh, routeMeta); +} +function initWebviewPullToRefreshI18n(pullToRefresh, routeMeta) { + const i18nResult = initPullToRefreshI18n(pullToRefresh); + if (!i18nResult) { + return pullToRefresh; + } + const [contentdownI18n, contentoverI18n, contentrefreshI18n] = i18nResult; + if (contentdownI18n || contentoverI18n || contentrefreshI18n) { + uni.onLocaleChange(() => { + const webview = plus.webview.getWebviewById(routeMeta.id + ''); + if (!webview) { + return; + } + const newPullToRefresh = { + support: true, + }; + if (contentdownI18n) { + newPullToRefresh.contentdown = { + caption: pullToRefresh.contentdown.caption, + }; + } + if (contentoverI18n) { + newPullToRefresh.contentover = { + caption: pullToRefresh.contentover.caption, + }; + } + if (contentrefreshI18n) { + newPullToRefresh.contentrefresh = { + caption: pullToRefresh.contentrefresh.caption, + }; + } + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('updateWebview', webview.id, newPullToRefresh)); + } + webview.setStyle({ + pullToRefresh: newPullToRefresh, + }); + }); + } + return pullToRefresh; +} +const defaultAndroidPullToRefresh = { support: true, style: 'circle' }; +const defaultPullToRefresh = { + support: true, + style: 'default', + height: '50px', + range: '200px', + contentdown: { + caption: '', + }, + contentover: { + caption: '', + }, + contentrefresh: { + caption: '', + }, +}; + +function initTitleNView(webviewStyle, routeMeta) { + const { navigationBar } = routeMeta; + if (navigationBar.style === 'custom') { + return false; + } + let autoBackButton = true; + if (routeMeta.isQuit) { + autoBackButton = false; + } + const titleNView = { + autoBackButton, + }; + Object.keys(navigationBar).forEach((name) => { + const value = navigationBar[name]; + if (name === 'backgroundColor') { + titleNView.backgroundColor = isColor(value) + ? value + : BACKGROUND_COLOR; + } + else if (name === 'titleImage' && value) { + titleNView.tags = createTitleImageTags(value); + } + else if (name === 'buttons' && isArray$1(value)) { + titleNView.buttons = value.map((button, index) => { + button.onclick = createTitleNViewBtnClick(index); + return button; + }); + } + else { + titleNView[name] = + value; + } + }); + webviewStyle.titleNView = initTitleNViewI18n(titleNView, routeMeta); +} +function initTitleNViewI18n(titleNView, routeMeta) { + const i18nResult = initNavigationBarI18n(titleNView); + if (!i18nResult) { + return titleNView; + } + const [titleTextI18n, searchInputPlaceholderI18n] = i18nResult; + if (titleTextI18n || searchInputPlaceholderI18n) { + uni.onLocaleChange(() => { + const webview = plus.webview.getWebviewById(routeMeta.id + ''); + if (!webview) { + return; + } + const newTitleNView = {}; + if (titleTextI18n) { + newTitleNView.titleText = titleNView.titleText; + } + if (searchInputPlaceholderI18n) { + newTitleNView.searchInput = { + placeholder: titleNView.searchInput.placeholder, + }; + } + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('updateWebview', webview.id, newTitleNView)); + } + webview.setStyle({ + titleNView: newTitleNView, + }); + }); + } + return titleNView; +} +function createTitleImageTags(titleImage) { + return [ + { + tag: 'img', + src: titleImage, + position: { + left: 'auto', + top: 'auto', + width: 'auto', + height: '26px', + }, + }, + ]; +} +function createTitleNViewBtnClick(index) { + return function onClick(btn) { + btn.index = index; + invokeHook(ON_NAVIGATION_BAR_BUTTON_TAP, btn); + }; +} - function createNVueWebview({ path, query, routeOptions, webviewStyle, }) { - const curWebviewId = genWebviewId(); - const curWebviewStyle = parseWebviewStyle(path, routeOptions.meta, { - id: curWebviewId + '', - }); - curWebviewStyle.uniPageUrl = initUniPageUrl(path, query); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('createNVueWebview', curWebviewId, path, curWebviewStyle)); - } - curWebviewStyle.isTab = !!routeOptions.meta.isTabBar; - return plus.webview.create('', String(curWebviewId), curWebviewStyle, shared.extend({ - nvue: true, - }, webviewStyle)); - } +function parseWebviewStyle(path, routeMeta, webview) { + const webviewStyle = { + bounce: 'vertical', + }; + Object.keys(routeMeta).forEach((name) => { + if (WEBVIEW_STYLE_BLACKLIST.indexOf(name) === -1) { + webviewStyle[name] = + routeMeta[name]; + } + }); + if (webview.id !== '1') { + // 首页 nvue 已经在 manifest.json 中设置了 uniNView,不能再次设置,否则会二次加载 + initNVue(webviewStyle, routeMeta, path); + } + initPopGesture(webviewStyle, routeMeta); + initBackgroundColor(webviewStyle, routeMeta); + initTitleNView(webviewStyle, routeMeta); + initPullToRefresh(webviewStyle, routeMeta); + return webviewStyle; +} +const WEBVIEW_STYLE_BLACKLIST = [ + 'id', + 'route', + 'isNVue', + 'isQuit', + 'isEntry', + 'isTabBar', + 'tabBarIndex', + 'windowTop', + 'topWindow', + 'leftWindow', + 'rightWindow', + 'maxWidth', + 'usingComponents', + 'disableScroll', + 'enablePullDownRefresh', + 'navigationBar', + 'pullToRefresh', + 'onReachBottomDistance', + 'pageOrientation', + 'backgroundColor', +]; + +let id = 2; +function getWebviewId() { + return id; +} +function genWebviewId() { + return id++; +} +function encode(val) { + return val; +} +function initUniPageUrl(path, query) { + const queryString = query ? stringifyQuery$1(query, encode) : ''; + return { + path: path.substr(1), + query: queryString ? queryString.substr(1) : queryString, + }; +} +function initDebugRefresh(isTab, path, query) { + const queryString = query ? stringifyQuery$1(query, encode) : ''; + return { + isTab, + arguments: JSON.stringify({ + path: path.substr(1), + query: queryString ? queryString.substr(1) : queryString, + }), + }; +} - let preloadWebview$1; - function setPreloadWebview(webview) { - preloadWebview$1 = webview; - } - function getPreloadWebview() { - return preloadWebview$1; - } - function createPreloadWebview() { - if (!preloadWebview$1 || preloadWebview$1.__uniapp_route) { - // 不存在,或已被使用 - preloadWebview$1 = plus.webview.create(VIEW_WEBVIEW_PATH, String(genWebviewId()), - // @ts-expect-error - { contentAdjust: false }); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('createPreloadWebview', preloadWebview$1.id)); - } - } - return preloadWebview$1; - } +function createNVueWebview({ path, query, routeOptions, webviewStyle, }) { + const curWebviewId = genWebviewId(); + const curWebviewStyle = parseWebviewStyle(path, routeOptions.meta, { + id: curWebviewId + '', + }); + curWebviewStyle.uniPageUrl = initUniPageUrl(path, query); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('createNVueWebview', curWebviewId, path, curWebviewStyle)); + } + curWebviewStyle.isTab = !!routeOptions.meta.isTabBar; + return plus.webview.create('', String(curWebviewId), curWebviewStyle, extend({ + nvue: true, + }, webviewStyle)); +} - function onWebviewClose(webview) { - const { popupSubNVueWebviews } = webview; - if (!popupSubNVueWebviews) { - return; - } - webview.addEventListener('close', () => { - Object.keys(popupSubNVueWebviews).forEach((id) => { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('onWebviewClose', webview.id, 'popupSubNVueWebview', id, 'close')); - } - popupSubNVueWebviews[id].close('none'); - }); - }); - } +let preloadWebview$1; +function setPreloadWebview(webview) { + preloadWebview$1 = webview; +} +function getPreloadWebview() { + return preloadWebview$1; +} +function createPreloadWebview() { + if (!preloadWebview$1 || preloadWebview$1.__uniapp_route) { + // 不存在,或已被使用 + preloadWebview$1 = plus.webview.create(VIEW_WEBVIEW_PATH, String(genWebviewId()), + // @ts-expect-error + { contentAdjust: false }); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('createPreloadWebview', preloadWebview$1.id)); + } + } + return preloadWebview$1; +} - /** - * 是否处于直达页面 - * @param page - * @returns - */ - function isDirectPage(page) { - return (__uniConfig.realEntryPagePath && - page.$page.route === __uniConfig.entryPagePath); - } - /** - * 重新启动到首页 - */ - function reLaunchEntryPage() { - __uniConfig.entryPagePath = __uniConfig.realEntryPagePath; - delete __uniConfig.realEntryPagePath; - uni.reLaunch({ - url: addLeadingSlash(__uniConfig.entryPagePath), - }); - } +function onWebviewClose(webview) { + const { popupSubNVueWebviews } = webview; + if (!popupSubNVueWebviews) { + return; + } + webview.addEventListener('close', () => { + Object.keys(popupSubNVueWebviews).forEach((id) => { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('onWebviewClose', webview.id, 'popupSubNVueWebview', id, 'close')); + } + popupSubNVueWebviews[id].close('none'); + }); + }); +} - function onWebviewPopGesture(webview) { - let popStartStatusBarStyle; - webview.addEventListener('popGesture', (e) => { - if (e.type === 'start') { - // 设置下一个页面的 statusBarStyle - const pages = getCurrentPages(); - const page = pages[pages.length - 2]; - popStartStatusBarStyle = lastStatusBarStyle; - const statusBarStyle = page && page.$page.statusBarStyle; - statusBarStyle && setStatusBarStyle(statusBarStyle); - } - else if (e.type === 'end' && !e.result) { - // 拖拽未完成,设置为当前状态栏前景色 - setStatusBarStyle(popStartStatusBarStyle); - } - else if (e.type === 'end' && e.result) { - const page = getCurrentPage(); - removeCurrentPage(); - setStatusBarStyle(); - if (page && isDirectPage(page)) { - reLaunchEntryPage(); - } - else { - // 触发前一个页面 onShow - invokeHook(ON_SHOW); - } - } - }); - } +/** + * 是否处于直达页面 + * @param page + * @returns + */ +function isDirectPage(page) { + return (__uniConfig.realEntryPagePath && + page.$page.route === __uniConfig.entryPagePath); +} +/** + * 重新启动到首页 + */ +function reLaunchEntryPage() { + __uniConfig.entryPagePath = __uniConfig.realEntryPagePath; + delete __uniConfig.realEntryPagePath; + uni.reLaunch({ + url: addLeadingSlash(__uniConfig.entryPagePath), + }); +} - function onWebviewRecovery(webview) { - if (webview.nvue) { - return; - } - const webviewId = webview.id; - const { subscribe, unsubscribe } = UniServiceJSBridge; - const onWebviewRecoveryReady = (_, pageId) => { - if (webviewId !== pageId) { - return; - } - unsubscribe(ON_WEBVIEW_READY, onWebviewRecoveryReady); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog(`Recovery`, webviewId, 'ready')); - } - const page = getPageById(parseInt(pageId)); - if (page) { - const pageNode = page.__page_container__; - pageNode.restore(); - } - }; - // @ts-expect-error - webview.addEventListener('recovery', () => { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('Recovery', webview.id)); - } - subscribe(ON_WEBVIEW_READY, onWebviewRecoveryReady); - }); - } +function onWebviewPopGesture(webview) { + let popStartStatusBarStyle; + webview.addEventListener('popGesture', (e) => { + if (e.type === 'start') { + // 设置下一个页面的 statusBarStyle + const pages = getCurrentPages(); + const page = pages[pages.length - 2]; + popStartStatusBarStyle = lastStatusBarStyle; + const statusBarStyle = page && page.$page.statusBarStyle; + statusBarStyle && setStatusBarStyle(statusBarStyle); + } + else if (e.type === 'end' && !e.result) { + // 拖拽未完成,设置为当前状态栏前景色 + setStatusBarStyle(popStartStatusBarStyle); + } + else if (e.type === 'end' && e.result) { + const page = getCurrentPage(); + removeCurrentPage(); + setStatusBarStyle(); + if (page && isDirectPage(page)) { + reLaunchEntryPage(); + } + else { + // 触发前一个页面 onShow + invokeHook(ON_SHOW); + } + } + }); +} - function onWebviewResize(webview) { - const { emit } = UniServiceJSBridge; - const onResize = function ({ width, height, }) { - const landscape = Math.abs(plus.navigator.getOrientation()) === 90; - const res = { - deviceOrientation: landscape ? 'landscape' : 'portrait', - size: { - windowWidth: Math.ceil(width), - windowHeight: Math.ceil(height), - }, - }; - emit(ON_RESIZE, res, parseInt(webview.id)); // Page lifecycle - }; - webview.addEventListener('resize', debounce(onResize, 50)); - } +function onWebviewRecovery(webview) { + if (webview.nvue) { + return; + } + const webviewId = webview.id; + const { subscribe, unsubscribe } = UniServiceJSBridge; + const onWebviewRecoveryReady = (_, pageId) => { + if (webviewId !== pageId) { + return; + } + unsubscribe(ON_WEBVIEW_READY, onWebviewRecoveryReady); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog(`Recovery`, webviewId, 'ready')); + } + const page = getPageById(parseInt(pageId)); + if (page) { + const pageNode = page.__page_container__; + pageNode.restore(); + } + }; + // @ts-expect-error + webview.addEventListener('recovery', () => { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('Recovery', webview.id)); + } + subscribe(ON_WEBVIEW_READY, onWebviewRecoveryReady); + }); +} - const WEBVIEW_LISTENERS = { - pullToRefresh: ON_PULL_DOWN_REFRESH, - titleNViewSearchInputChanged: ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, - titleNViewSearchInputConfirmed: ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, - titleNViewSearchInputClicked: ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, - titleNViewSearchInputFocusChanged: ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, - }; - function initWebviewEvent(webview) { - const id = parseInt(webview.id); - Object.keys(WEBVIEW_LISTENERS).forEach((name) => { - const hook = WEBVIEW_LISTENERS[name]; - webview.addEventListener(name, (e) => { - if (hook === ON_PULL_DOWN_REFRESH) { - // 设置当前正在下拉刷新的webview - setPullDownRefreshWebview(webview); - } - invokeHook(id, hook, e); - }); - }); - onWebviewClose(webview); - onWebviewResize(webview); - if (plus.os.name === 'iOS') { - onWebviewRecovery(webview); - onWebviewPopGesture(webview); - } - } +function onWebviewResize(webview) { + const { emit } = UniServiceJSBridge; + const onResize = function ({ width, height, }) { + const landscape = Math.abs(plus.navigator.getOrientation()) === 90; + const res = { + deviceOrientation: landscape ? 'landscape' : 'portrait', + size: { + windowWidth: Math.ceil(width), + windowHeight: Math.ceil(height), + }, + }; + emit(ON_RESIZE, res, parseInt(webview.id)); // Page lifecycle + }; + webview.addEventListener('resize', debounce(onResize, 50)); +} - function initWebviewStyle(webview, path, query, routeMeta) { - const webviewStyle = parseWebviewStyle(path, routeMeta, webview); - webviewStyle.uniPageUrl = initUniPageUrl(path, query); - const isTabBar = !!routeMeta.isTabBar; - if (!routeMeta.isNVue) { - webviewStyle.debugRefresh = initDebugRefresh(isTabBar, path, query); - } - else { - // android 需要使用 - webviewStyle.isTab = isTabBar; - } - webviewStyle.locale = weex.requireModule('plus').getLanguage(); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('updateWebview', webviewStyle)); - } - webview.setStyle(webviewStyle); - } +const WEBVIEW_LISTENERS = { + pullToRefresh: ON_PULL_DOWN_REFRESH, + titleNViewSearchInputChanged: ON_NAVIGATION_BAR_SEARCH_INPUT_CHANGED, + titleNViewSearchInputConfirmed: ON_NAVIGATION_BAR_SEARCH_INPUT_CONFIRMED, + titleNViewSearchInputClicked: ON_NAVIGATION_BAR_SEARCH_INPUT_CLICKED, + titleNViewSearchInputFocusChanged: ON_NAVIGATION_BAR_SEARCH_INPUT_FOCUS_CHANGED, +}; +function initWebviewEvent(webview) { + const id = parseInt(webview.id); + Object.keys(WEBVIEW_LISTENERS).forEach((name) => { + const hook = WEBVIEW_LISTENERS[name]; + webview.addEventListener(name, (e) => { + if (hook === ON_PULL_DOWN_REFRESH) { + // 设置当前正在下拉刷新的webview + setPullDownRefreshWebview(webview); + } + invokeHook(id, hook, e); + }); + }); + onWebviewClose(webview); + onWebviewResize(webview); + if (plus.os.name === 'iOS') { + onWebviewRecovery(webview); + onWebviewPopGesture(webview); + } +} - function initSubNVues(webview, path, routeMeta) { - const subNVues = routeMeta.subNVues || []; - subNVues.forEach((subNVue) => { - if (!subNVue.path) { - return; - } - const style = subNVue.style || {}; - const isNavigationBar = subNVue.type === 'navigationBar'; - const isPopup = subNVue.type === 'popup'; - style.uniNView = { - path: subNVue.path.replace('.nvue', '.js'), - defaultFontSize: __uniConfig.defaultFontSize, - viewport: __uniConfig.viewport, - }; - const extras = { - __uniapp_host: path, - __uniapp_origin: style.uniNView.path.split('?')[0].replace('.js', ''), - __uniapp_origin_id: webview.id, - __uniapp_origin_type: webview.__uniapp_type, - }; - let maskWebview; - if (isNavigationBar) { - style.position = 'dock'; - style.dock = 'top'; - style.top = '0'; - style.width = '100%'; - style.height = String(NAVBAR_HEIGHT + getStatusbarHeight()); - delete style.left; - delete style.right; - delete style.bottom; - delete style.margin; - } - else if (isPopup) { - style.position = 'absolute'; - if (isTabBarPage$1(path)) { - maskWebview = tabBar$1; - } - else { - maskWebview = webview; - } - extras.__uniapp_mask = style.mask || 'rgba(0,0,0,0.5)'; - extras.__uniapp_mask_id = maskWebview.id; - } - delete style.mask; - const subNVueWebview = plus.webview.create('', subNVue.id, style, extras); - if (isPopup) { - if (!maskWebview.popupSubNVueWebviews) { - maskWebview.popupSubNVueWebviews = {}; - } - maskWebview.popupSubNVueWebviews[subNVueWebview.id] = subNVueWebview; - const hideSubNVue = function () { - maskWebview.setStyle({ - mask: 'none', - }); - subNVueWebview.hide('auto'); - }; - maskWebview.addEventListener('maskClick', hideSubNVue); - let isRemoved = false; // 增加个 remove 标记,防止出错 - subNVueWebview.addEventListener('show', () => { - if (!isRemoved) { - plus.key.removeEventListener('backbutton', backbuttonListener); - plus.key.addEventListener('backbutton', hideSubNVue); - isRemoved = true; - } - }); - subNVueWebview.addEventListener('hide', () => { - if (isRemoved) { - plus.key.removeEventListener('backbutton', hideSubNVue); - plus.key.addEventListener('backbutton', backbuttonListener); - isRemoved = false; - } - }); - subNVueWebview.addEventListener('close', () => { - delete maskWebview.popupSubNVueWebviews[subNVueWebview.id]; - if (isRemoved) { - plus.key.removeEventListener('backbutton', hideSubNVue); - plus.key.addEventListener('backbutton', backbuttonListener); - isRemoved = false; - } - }); - } - else { - webview.append(subNVueWebview); - } - }); - } +function initWebviewStyle(webview, path, query, routeMeta) { + const webviewStyle = parseWebviewStyle(path, routeMeta, webview); + webviewStyle.uniPageUrl = initUniPageUrl(path, query); + const isTabBar = !!routeMeta.isTabBar; + if (!routeMeta.isNVue) { + webviewStyle.debugRefresh = initDebugRefresh(isTabBar, path, query); + } + else { + // android 需要使用 + webviewStyle.isTab = isTabBar; + } + webviewStyle.locale = weex.requireModule('plus').getLanguage(); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('updateWebview', webviewStyle)); + } + webview.setStyle(webviewStyle); +} - function initWebview(webview, path, query, routeMeta) { - // 首页或非 nvue 页面 - if (webview.id === '1' || !routeMeta.isNVue) { - initWebviewStyle(webview, path, query, routeMeta); - } - initSubNVues(webview, path, routeMeta); - initWebviewEvent(webview); - } +function initSubNVues(webview, path, routeMeta) { + const subNVues = routeMeta.subNVues || []; + subNVues.forEach((subNVue) => { + if (!subNVue.path) { + return; + } + const style = subNVue.style || {}; + const isNavigationBar = subNVue.type === 'navigationBar'; + const isPopup = subNVue.type === 'popup'; + style.uniNView = { + path: subNVue.path.replace('.nvue', '.js'), + defaultFontSize: __uniConfig.defaultFontSize, + viewport: __uniConfig.viewport, + }; + const extras = { + __uniapp_host: path, + __uniapp_origin: style.uniNView.path.split('?')[0].replace('.js', ''), + __uniapp_origin_id: webview.id, + __uniapp_origin_type: webview.__uniapp_type, + }; + let maskWebview; + if (isNavigationBar) { + style.position = 'dock'; + style.dock = 'top'; + style.top = '0'; + style.width = '100%'; + style.height = String(NAVBAR_HEIGHT + getStatusbarHeight()); + delete style.left; + delete style.right; + delete style.bottom; + delete style.margin; + } + else if (isPopup) { + style.position = 'absolute'; + if (isTabBarPage$1(path)) { + maskWebview = tabBar$1; + } + else { + maskWebview = webview; + } + extras.__uniapp_mask = style.mask || 'rgba(0,0,0,0.5)'; + extras.__uniapp_mask_id = maskWebview.id; + } + delete style.mask; + const subNVueWebview = plus.webview.create('', subNVue.id, style, extras); + if (isPopup) { + if (!maskWebview.popupSubNVueWebviews) { + maskWebview.popupSubNVueWebviews = {}; + } + maskWebview.popupSubNVueWebviews[subNVueWebview.id] = subNVueWebview; + const hideSubNVue = function () { + maskWebview.setStyle({ + mask: 'none', + }); + subNVueWebview.hide('auto'); + }; + maskWebview.addEventListener('maskClick', hideSubNVue); + let isRemoved = false; // 增加个 remove 标记,防止出错 + subNVueWebview.addEventListener('show', () => { + if (!isRemoved) { + plus.key.removeEventListener('backbutton', backbuttonListener); + plus.key.addEventListener('backbutton', hideSubNVue); + isRemoved = true; + } + }); + subNVueWebview.addEventListener('hide', () => { + if (isRemoved) { + plus.key.removeEventListener('backbutton', hideSubNVue); + plus.key.addEventListener('backbutton', backbuttonListener); + isRemoved = false; + } + }); + subNVueWebview.addEventListener('close', () => { + delete maskWebview.popupSubNVueWebviews[subNVueWebview.id]; + if (isRemoved) { + plus.key.removeEventListener('backbutton', hideSubNVue); + plus.key.addEventListener('backbutton', backbuttonListener); + isRemoved = false; + } + }); + } + else { + webview.append(subNVueWebview); + } + }); +} - function createWebview(options) { - if (options.routeOptions.meta.isNVue) { - return createNVueWebview(options); - } - if (getWebviewId() === 2) { - // 如果首页非 nvue,则直接返回 Launch Webview - return plus.webview.getLaunchWebview(); - } - return getPreloadWebview(); - } - function onWebviewReady(pageId, callback) { - UniServiceJSBridge.once(ON_WEBVIEW_READY + '.' + pageId, callback); - } +function initWebview(webview, path, query, routeMeta) { + // 首页或非 nvue 页面 + if (webview.id === '1' || !routeMeta.isNVue) { + initWebviewStyle(webview, path, query, routeMeta); + } + initSubNVues(webview, path, routeMeta); + initWebviewEvent(webview); +} - function closeWebview(webview, animationType, animationDuration) { - webview[webview.__preload__ ? 'hide' : 'close'](animationType, animationDuration); - } - function showWebview(webview, animationType, animationDuration, showCallback, delay) { - if (typeof delay === 'undefined') { - delay = webview.nvue ? 0 : 100; - } - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('showWebview', 'delay', delay)); - } - const execShowCallback = function () { - if (execShowCallback._called) { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('execShowCallback', 'prevent')); - } - return; - } - execShowCallback._called = true; - showCallback && showCallback(); - navigateFinish(); - }; - execShowCallback._called = false; - setTimeout(() => { - const timer = setTimeout(() => { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('showWebview', 'callback', 'timer')); - } - execShowCallback(); - }, animationDuration + 150); - webview.show(animationType, animationDuration, () => { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('showWebview', 'callback')); - } - if (!execShowCallback._called) { - clearTimeout(timer); - } - execShowCallback(); - }); - }, delay); - } - function backWebview(webview, callback) { - const children = webview.children(); - if (!children || !children.length) { - // 有子 webview - return callback(); - } - // 如果页面有subNvues,切使用了webview组件,则返回时子webview会取错,因此需要做id匹配 - const childWebview = children.find((webview) => webview.id.indexOf(WEBVIEW_ID_PREFIX) === 0) || - children[0]; - childWebview.canBack(({ canBack }) => { - if (canBack) { - childWebview.back(); // webview 返回 - } - else { - callback(); - } - }); - } +function createWebview(options) { + if (options.routeOptions.meta.isNVue) { + return createNVueWebview(options); + } + if (getWebviewId() === 2) { + // 如果首页非 nvue,则直接返回 Launch Webview + return plus.webview.getLaunchWebview(); + } + return getPreloadWebview(); +} +function onWebviewReady(pageId, callback) { + UniServiceJSBridge.once(ON_WEBVIEW_READY + '.' + pageId, callback); +} - let pendingNavigator = false; - function setPendingNavigator(path, callback, msg) { - pendingNavigator = { - path, - nvue: getRouteMeta(path).isNVue, - callback, - }; - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('setPendingNavigator', path, msg)); - } - } - function closePage(page, animationType, animationDuration) { - removePage(page); - closeWebview(page.$getAppWebview(), animationType, animationDuration); - } - function navigate(path, callback, isAppLaunch = false) { - if (!isAppLaunch && pendingNavigator) { - return console.error(`Waiting to navigate to: ${pendingNavigator.path}, do not operate continuously: ${path}.`); - } - if (__uniConfig.renderer === 'native') { - // 纯原生无需wait逻辑 - // 如果是首页还未初始化,需要等一等,其他无需等待 - if (getCurrentPages().length === 0) { - return setPendingNavigator(path, callback, 'waitForReady'); - } - return callback(); - } - // 未创建 preloadWebview 或 preloadWebview 已被使用 - const waitPreloadWebview = !preloadWebview$1 || (preloadWebview$1 && preloadWebview$1.__uniapp_route); - // 已创建未 loaded - const waitPreloadWebviewReady = preloadWebview$1 && !preloadWebview$1.loaded; - if (waitPreloadWebview || waitPreloadWebviewReady) { - setPendingNavigator(path, callback, waitPreloadWebview ? 'waitForCreate' : 'waitForReady'); - } - else { - callback(); - } - if (waitPreloadWebviewReady) { - onWebviewReady(preloadWebview$1.id, pendingNavigate); - } - } - function pendingNavigate() { - if (!pendingNavigator) { - return; - } - const { callback } = pendingNavigator; - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('pendingNavigate', pendingNavigator.path)); - } - pendingNavigator = false; - return callback(); - } - function navigateFinish() { - if (__uniConfig.renderer === 'native') { - if (!pendingNavigator) { - return; - } - if (pendingNavigator.nvue) { - return pendingNavigate(); - } - return; - } - // 创建预加载 - const preloadWebview = createPreloadWebview(); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('navigateFinish', 'preloadWebview', preloadWebview.id)); - } - if (!pendingNavigator) { - return; - } - if (pendingNavigator.nvue) { - return pendingNavigate(); - } - preloadWebview.loaded - ? pendingNavigator.callback() - : onWebviewReady(preloadWebview.id, pendingNavigate); - } +function closeWebview(webview, animationType, animationDuration) { + webview[webview.__preload__ ? 'hide' : 'close'](animationType, animationDuration); +} +function showWebview(webview, animationType, animationDuration, showCallback, delay) { + if (typeof delay === 'undefined') { + delay = webview.nvue ? 0 : 100; + } + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('showWebview', 'delay', delay)); + } + const execShowCallback = function () { + if (execShowCallback._called) { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('execShowCallback', 'prevent')); + } + return; + } + execShowCallback._called = true; + showCallback && showCallback(); + navigateFinish(); + }; + execShowCallback._called = false; + setTimeout(() => { + const timer = setTimeout(() => { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('showWebview', 'callback', 'timer')); + } + execShowCallback(); + }, animationDuration + 150); + webview.show(animationType, animationDuration, () => { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('showWebview', 'callback')); + } + if (!execShowCallback._called) { + clearTimeout(timer); + } + execShowCallback(); + }); + }, delay); +} +function backWebview(webview, callback) { + const children = webview.children(); + if (!children || !children.length) { + // 有子 webview + return callback(); + } + // 如果页面有subNvues,切使用了webview组件,则返回时子webview会取错,因此需要做id匹配 + const childWebview = children.find((webview) => webview.id.indexOf(WEBVIEW_ID_PREFIX) === 0) || + children[0]; + childWebview.canBack(({ canBack }) => { + if (canBack) { + childWebview.back(); // webview 返回 + } + else { + callback(); + } + }); +} - class UniPageNode extends UniNode { - constructor(pageId, options, setup = false) { - super(NODE_TYPE_PAGE, '#page', null); - this._id = 1; - this._created = false; - this._updating = false; - this._createActionMap = new Map(); - this.updateActions = []; - this.dicts = []; - this.nodeId = 0; - this.pageId = pageId; - this.pageNode = this; - this.options = options; - this.isUnmounted = false; - this.createAction = [ACTION_TYPE_PAGE_CREATE, options]; - this.createdAction = [ACTION_TYPE_PAGE_CREATED]; - this.normalizeDict = this._normalizeDict.bind(this); - this._update = this.update.bind(this); - setup && this.setup(); - } - _normalizeDict(value, normalizeValue = true) { - if (!shared.isPlainObject(value)) { - return this.addDict(value); - } - const dictArray = []; - Object.keys(value).forEach((n) => { - const dict = [this.addDict(n)]; - const v = value[n]; - if (normalizeValue) { - dict.push(this.addDict(v)); - } - else { - dict.push(v); - } - dictArray.push(dict); - }); - return dictArray; - } - addDict(value) { - const { dicts } = this; - const index = dicts.indexOf(value); - if (index > -1) { - return index; - } - return dicts.push(value) - 1; - } - onInjectHook(hook) { - if ((hook === ON_PAGE_SCROLL || hook === ON_REACH_BOTTOM) && - !this.scrollAction) { - this.scrollAction = [ - ACTION_TYPE_PAGE_SCROLL, - this.options.onReachBottomDistance, - ]; - this.push(this.scrollAction); - } - } - onCreate(thisNode, nodeName) { - pushCreateAction(this, thisNode.nodeId, nodeName); - return thisNode; - } - onInsertBefore(thisNode, newChild, refChild) { - pushInsertAction(this, newChild, thisNode.nodeId, (refChild && refChild.nodeId) || -1); - return newChild; - } - onRemoveChild(oldChild) { - pushRemoveAction(this, oldChild.nodeId); - return oldChild; - } - onAddEvent(thisNode, name, flag) { - if (thisNode.parentNode) { - pushAddEventAction(this, thisNode.nodeId, name, flag); - } - } - onAddWxsEvent(thisNode, name, wxsEvent, flag) { - if (thisNode.parentNode) { - pushAddWxsEventAction(this, thisNode.nodeId, name, wxsEvent, flag); - } - } - onRemoveEvent(thisNode, name) { - if (thisNode.parentNode) { - pushRemoveEventAction(this, thisNode.nodeId, name); - } - } - onSetAttribute(thisNode, qualifiedName, value) { - if (thisNode.parentNode) { - pushSetAttributeAction(this, thisNode.nodeId, qualifiedName, value); - } - } - onRemoveAttribute(thisNode, qualifiedName) { - if (thisNode.parentNode) { - pushRemoveAttributeAction(this, thisNode.nodeId, qualifiedName); - } - } - onTextContent(thisNode, text) { - if (thisNode.parentNode) { - pushSetTextAction(this, thisNode.nodeId, text); - } - } - onNodeValue(thisNode, val) { - if (thisNode.parentNode) { - pushSetTextAction(this, thisNode.nodeId, val); - } - } - genId() { - return this._id++; - } - push(action, extras) { - if (this.isUnmounted) { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('PageNode', 'push.prevent', action)); - } - return; - } - switch (action[0]) { - case ACTION_TYPE_CREATE: - this._createActionMap.set(action[1], action); - break; - case ACTION_TYPE_INSERT: - const createAction = this._createActionMap.get(action[1]); - if (createAction) { - createAction[3] = action[2]; // parentNodeId - createAction[4] = action[3]; // anchorId - if (extras) { - createAction[5] = extras; - } - } - else { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog(`Insert`, action, 'not found createAction')); - } - } - break; - } - // insert 被合并进 create - if (action[0] !== ACTION_TYPE_INSERT) { - this.updateActions.push(action); - } - if (!this._updating) { - this._updating = true; - vue.queuePostFlushCb(this._update); - } - } - restore() { - this.clear(); - this.push(this.createAction); - if (this.scrollAction) { - this.push(this.scrollAction); - } - const restoreNode = (node) => { - this.onCreate(node, node.nodeName); - this.onInsertBefore(node.parentNode, node, null); - node.childNodes.forEach((childNode) => { - restoreNode(childNode); - }); - }; - this.childNodes.forEach((childNode) => restoreNode(childNode)); - this.push(this.createdAction); - } - setup() { - this.send([this.createAction]); - } - update() { - const { dicts, updateActions, _createActionMap } = this; - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('PageNode', 'update', updateActions.length, _createActionMap.size)); - } - // 首次 - if (!this._created) { - this._created = true; - updateActions.push(this.createdAction); - } - if (updateActions.length) { - if (dicts.length) { - updateActions.unshift([ACTION_TYPE_DICT, dicts]); - } - this.send(updateActions); - } - this.clear(); - } - clear() { - this.dicts.length = 0; - this.updateActions.length = 0; - this._updating = false; - this._createActionMap.clear(); - } - send(action) { - UniServiceJSBridge.publishHandler(VD_SYNC, action, this.pageId); - } - fireEvent(id, evt) { - const node = findNodeById(id, this); - if (node) { - node.dispatchEvent(evt); - } - else if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('PageNode', 'fireEvent', id, 'not found', evt)); - } - } - } - function getPageNode(pageId) { - const page = getPageById(pageId); - if (!page) - return null; - return page.__page_container__; - } - function findNode(name, value, uniNode) { - if (typeof uniNode === 'number') { - uniNode = getPageNode(uniNode); - } - if (uniNode[name] === value) { - return uniNode; - } - const { childNodes } = uniNode; - for (let i = 0; i < childNodes.length; i++) { - const uniNode = findNode(name, value, childNodes[i]); - if (uniNode) { - return uniNode; - } - } - return null; - } - function findNodeById(nodeId, uniNode) { - return findNode('nodeId', nodeId, uniNode); - } - function findNodeByTagName(tagName, uniNode) { - return findNode('nodeName', tagName.toUpperCase(), uniNode); - } - function pushCreateAction(pageNode, nodeId, nodeName) { - pageNode.push([ - ACTION_TYPE_CREATE, - nodeId, - pageNode.addDict(nodeName), - -1, - -1, - ]); - } - function pushInsertAction(pageNode, newChild, parentNodeId, refChildId) { - const nodeJson = newChild.toJSON({ - attr: true, - normalize: pageNode.normalizeDict, - }); - pageNode.push([ACTION_TYPE_INSERT, newChild.nodeId, parentNodeId, refChildId], Object.keys(nodeJson).length ? nodeJson : undefined); - } - function pushRemoveAction(pageNode, nodeId) { - pageNode.push([ACTION_TYPE_REMOVE, nodeId]); - } - function pushAddEventAction(pageNode, nodeId, name, value) { - pageNode.push([ACTION_TYPE_ADD_EVENT, nodeId, pageNode.addDict(name), value]); - } - function pushAddWxsEventAction(pageNode, nodeId, name, wxsEvent, value) { - pageNode.push([ - ACTION_TYPE_ADD_WXS_EVENT, - nodeId, - pageNode.addDict(name), - pageNode.addDict(wxsEvent), - value, - ]); - } - function pushRemoveEventAction(pageNode, nodeId, name) { - pageNode.push([ACTION_TYPE_REMOVE_EVENT, nodeId, pageNode.addDict(name)]); - } - function normalizeAttrValue(pageNode, name, value) { - return name === 'style' && shared.isPlainObject(value) - ? pageNode.normalizeDict(value) - : pageNode.addDict(value); - } - function pushSetAttributeAction(pageNode, nodeId, name, value) { - pageNode.push([ - ACTION_TYPE_SET_ATTRIBUTE, - nodeId, - pageNode.addDict(name), - normalizeAttrValue(pageNode, name, value), - ]); - } - function pushRemoveAttributeAction(pageNode, nodeId, name) { - pageNode.push([ACTION_TYPE_REMOVE_ATTRIBUTE, nodeId, pageNode.addDict(name)]); - } - function pushSetTextAction(pageNode, nodeId, text) { - pageNode.push([ACTION_TYPE_SET_TEXT, nodeId, pageNode.addDict(text)]); - } - function createPageNode(pageId, pageOptions, setup) { - return new UniPageNode(pageId, pageOptions, setup); - } +let pendingNavigator = false; +function setPendingNavigator(path, callback, msg) { + pendingNavigator = { + path, + nvue: getRouteMeta(path).isNVue, + callback, + }; + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('setPendingNavigator', path, msg)); + } +} +function closePage(page, animationType, animationDuration) { + removePage(page); + closeWebview(page.$getAppWebview(), animationType, animationDuration); +} +function navigate(path, callback, isAppLaunch = false) { + if (!isAppLaunch && pendingNavigator) { + return console.error(`Waiting to navigate to: ${pendingNavigator.path}, do not operate continuously: ${path}.`); + } + if (__uniConfig.renderer === 'native') { + // 纯原生无需wait逻辑 + // 如果是首页还未初始化,需要等一等,其他无需等待 + if (getCurrentPages().length === 0) { + return setPendingNavigator(path, callback, 'waitForReady'); + } + return callback(); + } + // 未创建 preloadWebview 或 preloadWebview 已被使用 + const waitPreloadWebview = !preloadWebview$1 || (preloadWebview$1 && preloadWebview$1.__uniapp_route); + // 已创建未 loaded + const waitPreloadWebviewReady = preloadWebview$1 && !preloadWebview$1.loaded; + if (waitPreloadWebview || waitPreloadWebviewReady) { + setPendingNavigator(path, callback, waitPreloadWebview ? 'waitForCreate' : 'waitForReady'); + } + else { + callback(); + } + if (waitPreloadWebviewReady) { + onWebviewReady(preloadWebview$1.id, pendingNavigate); + } +} +function pendingNavigate() { + if (!pendingNavigator) { + return; + } + const { callback } = pendingNavigator; + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('pendingNavigate', pendingNavigator.path)); + } + pendingNavigator = false; + return callback(); +} +function navigateFinish() { + if (__uniConfig.renderer === 'native') { + if (!pendingNavigator) { + return; + } + if (pendingNavigator.nvue) { + return pendingNavigate(); + } + return; + } + // 创建预加载 + const preloadWebview = createPreloadWebview(); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('navigateFinish', 'preloadWebview', preloadWebview.id)); + } + if (!pendingNavigator) { + return; + } + if (pendingNavigator.nvue) { + return pendingNavigate(); + } + preloadWebview.loaded + ? pendingNavigator.callback() + : onWebviewReady(preloadWebview.id, pendingNavigate); +} - function setupPage(component) { - const oldSetup = component.setup; - component.inheritAttrs = false; // 禁止继承 __pageId 等属性,避免告警 - component.setup = (_, ctx) => { - const { attrs: { __pageId, __pagePath, __pageQuery, __pageInstance }, } = ctx; - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog(__pagePath, 'setup')); - } - const instance = vue.getCurrentInstance(); - const pageVm = instance.proxy; - initPageVm(pageVm, __pageInstance); - addCurrentPage(initScope(__pageId, pageVm, __pageInstance)); - vue.onMounted(() => { - vue.nextTick(() => { - // onShow被延迟,故onReady也同时延迟 - invokeHook(pageVm, ON_READY); - }); - // TODO preloadSubPackages - }); - vue.onBeforeUnmount(() => { - invokeHook(pageVm, ON_UNLOAD); - }); - if (oldSetup) { - return oldSetup(__pageQuery, ctx); - } - }; - return component; - } - function initScope(pageId, vm, pageInstance) { - const $getAppWebview = () => { - return plus.webview.getWebviewById(pageId + ''); - }; - vm.$getAppWebview = $getAppWebview; - vm.$.ctx.$scope = { - $getAppWebview, - }; - vm.getOpenerEventChannel = () => { - if (!pageInstance.eventChannel) { - pageInstance.eventChannel = new EventChannel(pageId); - } - return pageInstance.eventChannel; - }; - return vm; - } +class UniPageNode extends UniNode { + constructor(pageId, options, setup = false) { + super(NODE_TYPE_PAGE, '#page', null); + this._id = 1; + this._created = false; + this._updating = false; + this._createActionMap = new Map(); + this.updateActions = []; + this.dicts = []; + this.nodeId = 0; + this.pageId = pageId; + this.pageNode = this; + this.options = options; + this.isUnmounted = false; + this.createAction = [ACTION_TYPE_PAGE_CREATE, options]; + this.createdAction = [ACTION_TYPE_PAGE_CREATED]; + this.normalizeDict = this._normalizeDict.bind(this); + this._update = this.update.bind(this); + setup && this.setup(); + } + _normalizeDict(value, normalizeValue = true) { + if (!isPlainObject(value)) { + return this.addDict(value); + } + const dictArray = []; + Object.keys(value).forEach((n) => { + const dict = [this.addDict(n)]; + const v = value[n]; + if (normalizeValue) { + dict.push(this.addDict(v)); + } + else { + dict.push(v); + } + dictArray.push(dict); + }); + return dictArray; + } + addDict(value) { + const { dicts } = this; + const index = dicts.indexOf(value); + if (index > -1) { + return index; + } + return dicts.push(value) - 1; + } + onInjectHook(hook) { + if ((hook === ON_PAGE_SCROLL || hook === ON_REACH_BOTTOM) && + !this.scrollAction) { + this.scrollAction = [ + ACTION_TYPE_PAGE_SCROLL, + this.options.onReachBottomDistance, + ]; + this.push(this.scrollAction); + } + } + onCreate(thisNode, nodeName) { + pushCreateAction(this, thisNode.nodeId, nodeName); + return thisNode; + } + onInsertBefore(thisNode, newChild, refChild) { + pushInsertAction(this, newChild, thisNode.nodeId, (refChild && refChild.nodeId) || -1); + return newChild; + } + onRemoveChild(oldChild) { + pushRemoveAction(this, oldChild.nodeId); + return oldChild; + } + onAddEvent(thisNode, name, flag) { + if (thisNode.parentNode) { + pushAddEventAction(this, thisNode.nodeId, name, flag); + } + } + onAddWxsEvent(thisNode, name, wxsEvent, flag) { + if (thisNode.parentNode) { + pushAddWxsEventAction(this, thisNode.nodeId, name, wxsEvent, flag); + } + } + onRemoveEvent(thisNode, name) { + if (thisNode.parentNode) { + pushRemoveEventAction(this, thisNode.nodeId, name); + } + } + onSetAttribute(thisNode, qualifiedName, value) { + if (thisNode.parentNode) { + pushSetAttributeAction(this, thisNode.nodeId, qualifiedName, value); + } + } + onRemoveAttribute(thisNode, qualifiedName) { + if (thisNode.parentNode) { + pushRemoveAttributeAction(this, thisNode.nodeId, qualifiedName); + } + } + onTextContent(thisNode, text) { + if (thisNode.parentNode) { + pushSetTextAction(this, thisNode.nodeId, text); + } + } + onNodeValue(thisNode, val) { + if (thisNode.parentNode) { + pushSetTextAction(this, thisNode.nodeId, val); + } + } + genId() { + return this._id++; + } + push(action, extras) { + if (this.isUnmounted) { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('PageNode', 'push.prevent', action)); + } + return; + } + switch (action[0]) { + case ACTION_TYPE_CREATE: + this._createActionMap.set(action[1], action); + break; + case ACTION_TYPE_INSERT: + const createAction = this._createActionMap.get(action[1]); + if (createAction) { + createAction[3] = action[2]; // parentNodeId + createAction[4] = action[3]; // anchorId + if (extras) { + createAction[5] = extras; + } + } + else { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog(`Insert`, action, 'not found createAction')); + } + } + break; + } + // insert 被合并进 create + if (action[0] !== ACTION_TYPE_INSERT) { + this.updateActions.push(action); + } + if (!this._updating) { + this._updating = true; + queuePostFlushCb(this._update); + } + } + restore() { + this.clear(); + this.push(this.createAction); + if (this.scrollAction) { + this.push(this.scrollAction); + } + const restoreNode = (node) => { + this.onCreate(node, node.nodeName); + this.onInsertBefore(node.parentNode, node, null); + node.childNodes.forEach((childNode) => { + restoreNode(childNode); + }); + }; + this.childNodes.forEach((childNode) => restoreNode(childNode)); + this.push(this.createdAction); + } + setup() { + this.send([this.createAction]); + } + update() { + const { dicts, updateActions, _createActionMap } = this; + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('PageNode', 'update', updateActions.length, _createActionMap.size)); + } + // 首次 + if (!this._created) { + this._created = true; + updateActions.push(this.createdAction); + } + if (updateActions.length) { + if (dicts.length) { + updateActions.unshift([ACTION_TYPE_DICT, dicts]); + } + this.send(updateActions); + } + this.clear(); + } + clear() { + this.dicts.length = 0; + this.updateActions.length = 0; + this._updating = false; + this._createActionMap.clear(); + } + send(action) { + UniServiceJSBridge.publishHandler(VD_SYNC, action, this.pageId); + } + fireEvent(id, evt) { + const node = findNodeById(id, this); + if (node) { + node.dispatchEvent(evt); + } + else if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('PageNode', 'fireEvent', id, 'not found', evt)); + } + } +} +function getPageNode(pageId) { + const page = getPageById(pageId); + if (!page) + return null; + return page.__page_container__; +} +function findNode(name, value, uniNode) { + if (typeof uniNode === 'number') { + uniNode = getPageNode(uniNode); + } + if (uniNode[name] === value) { + return uniNode; + } + const { childNodes } = uniNode; + for (let i = 0; i < childNodes.length; i++) { + const uniNode = findNode(name, value, childNodes[i]); + if (uniNode) { + return uniNode; + } + } + return null; +} +function findNodeById(nodeId, uniNode) { + return findNode('nodeId', nodeId, uniNode); +} +function findNodeByTagName(tagName, uniNode) { + return findNode('nodeName', tagName.toUpperCase(), uniNode); +} +function pushCreateAction(pageNode, nodeId, nodeName) { + pageNode.push([ + ACTION_TYPE_CREATE, + nodeId, + pageNode.addDict(nodeName), + -1, + -1, + ]); +} +function pushInsertAction(pageNode, newChild, parentNodeId, refChildId) { + const nodeJson = newChild.toJSON({ + attr: true, + normalize: pageNode.normalizeDict, + }); + pageNode.push([ACTION_TYPE_INSERT, newChild.nodeId, parentNodeId, refChildId], Object.keys(nodeJson).length ? nodeJson : undefined); +} +function pushRemoveAction(pageNode, nodeId) { + pageNode.push([ACTION_TYPE_REMOVE, nodeId]); +} +function pushAddEventAction(pageNode, nodeId, name, value) { + pageNode.push([ACTION_TYPE_ADD_EVENT, nodeId, pageNode.addDict(name), value]); +} +function pushAddWxsEventAction(pageNode, nodeId, name, wxsEvent, value) { + pageNode.push([ + ACTION_TYPE_ADD_WXS_EVENT, + nodeId, + pageNode.addDict(name), + pageNode.addDict(wxsEvent), + value, + ]); +} +function pushRemoveEventAction(pageNode, nodeId, name) { + pageNode.push([ACTION_TYPE_REMOVE_EVENT, nodeId, pageNode.addDict(name)]); +} +function normalizeAttrValue(pageNode, name, value) { + return name === 'style' && isPlainObject(value) + ? pageNode.normalizeDict(value) + : pageNode.addDict(value); +} +function pushSetAttributeAction(pageNode, nodeId, name, value) { + pageNode.push([ + ACTION_TYPE_SET_ATTRIBUTE, + nodeId, + pageNode.addDict(name), + normalizeAttrValue(pageNode, name, value), + ]); +} +function pushRemoveAttributeAction(pageNode, nodeId, name) { + pageNode.push([ACTION_TYPE_REMOVE_ATTRIBUTE, nodeId, pageNode.addDict(name)]); +} +function pushSetTextAction(pageNode, nodeId, text) { + pageNode.push([ACTION_TYPE_SET_TEXT, nodeId, pageNode.addDict(text)]); +} +function createPageNode(pageId, pageOptions, setup) { + return new UniPageNode(pageId, pageOptions, setup); +} - function isVuePageAsyncComponent(component) { - return shared.isFunction(component); - } - const pagesMap = new Map(); - function definePage(pagePath, asyncComponent) { - pagesMap.set(pagePath, once(createFactory(asyncComponent))); - } - function createPage(__pageId, __pagePath, __pageQuery, __pageInstance, pageOptions) { - const pageNode = createPageNode(__pageId, pageOptions, true); - const app = getVueApp(); - const component = pagesMap.get(__pagePath)(); - const mountPage = (component) => app.mountPage(component, { - __pageId, - __pagePath, - __pageQuery, - __pageInstance, - }, pageNode); - if (shared.isPromise(component)) { - return component.then((component) => mountPage(component)); - } - return mountPage(component); - } - function createFactory(component) { - return () => { - if (isVuePageAsyncComponent(component)) { - return component().then((component) => setupPage(component)); - } - return setupPage(component); - }; - } +function setupPage(component) { + const oldSetup = component.setup; + component.inheritAttrs = false; // 禁止继承 __pageId 等属性,避免告警 + component.setup = (_, ctx) => { + const { attrs: { __pageId, __pagePath, __pageQuery, __pageInstance }, } = ctx; + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog(__pagePath, 'setup')); + } + const instance = getCurrentInstance(); + const pageVm = instance.proxy; + initPageVm(pageVm, __pageInstance); + addCurrentPage(initScope(__pageId, pageVm, __pageInstance)); + onMounted(() => { + nextTick(() => { + // onShow被延迟,故onReady也同时延迟 + invokeHook(pageVm, ON_READY); + }); + // TODO preloadSubPackages + }); + onBeforeUnmount(() => { + invokeHook(pageVm, ON_UNLOAD); + }); + if (oldSetup) { + return oldSetup(__pageQuery, ctx); + } + }; + return component; +} +function initScope(pageId, vm, pageInstance) { + const $getAppWebview = () => { + return plus.webview.getWebviewById(pageId + ''); + }; + vm.$getAppWebview = $getAppWebview; + vm.$.ctx.$scope = { + $getAppWebview, + }; + vm.getOpenerEventChannel = () => { + if (!pageInstance.eventChannel) { + pageInstance.eventChannel = new EventChannel(pageId); + } + return pageInstance.eventChannel; + }; + return vm; +} - function initRouteOptions(path, openType) { - // 需要序列化一遍 - const routeOptions = JSON.parse(JSON.stringify(getRouteOptions(path))); - routeOptions.meta = initRouteMeta(routeOptions.meta); - if (!__uniConfig.realEntryPagePath && - (openType === 'reLaunch' || getCurrentPages().length === 0) // redirectTo - ) { - routeOptions.meta.isQuit = true; - } - else if (!routeOptions.meta.isTabBar) { - routeOptions.meta.isQuit = false; - } - // TODO - // if (routeOptions.meta.isTabBar) { - // routeOptions.meta.visible = true - // } - return routeOptions; - } +function isVuePageAsyncComponent(component) { + return isFunction(component); +} +const pagesMap = new Map(); +function definePage(pagePath, asyncComponent) { + pagesMap.set(pagePath, once(createFactory(asyncComponent))); +} +function createPage(__pageId, __pagePath, __pageQuery, __pageInstance, pageOptions) { + const pageNode = createPageNode(__pageId, pageOptions, true); + const app = getVueApp(); + const component = pagesMap.get(__pagePath)(); + const mountPage = (component) => app.mountPage(component, { + __pageId, + __pagePath, + __pageQuery, + __pageInstance, + }, pageNode); + if (isPromise(component)) { + return component.then((component) => mountPage(component)); + } + return mountPage(component); +} +function createFactory(component) { + return () => { + if (isVuePageAsyncComponent(component)) { + return component().then((component) => setupPage(component)); + } + return setupPage(component); + }; +} - const preloadWebviews = {}; - function removePreloadWebview(webview) { - const url = Object.keys(preloadWebviews).find((url) => preloadWebviews[url].id === webview.id); - if (url) { - if (process.env.NODE_ENV !== 'production') { - console.log(`[uni-app] removePreloadWebview(${webview.id})`); - } - delete preloadWebviews[url]; - } - } - function closePreloadWebview({ url }) { - const webview = preloadWebviews[url]; - if (webview) { - if (webview.__page__) { - if (!getCurrentPages().find((page) => page === webview.__page__)) { - // 未使用 - webview.close('none'); - } - else { - // 被使用 - webview.__preload__ = false; - } - } - else { - // 未使用 - webview.close('none'); - } - delete preloadWebviews[url]; - } - return webview; - } - function preloadWebview({ url, path, query, }) { - if (!preloadWebviews[url]) { - const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find((route) => route.path === path))); - preloadWebviews[url] = createWebview({ - path, - routeOptions, - query, - webviewStyle: { - __preload__: true, - __query__: JSON.stringify(query), - }, - }); - } - return preloadWebviews[url]; - } +function initRouteOptions(path, openType) { + // 需要序列化一遍 + const routeOptions = JSON.parse(JSON.stringify(getRouteOptions(path))); + routeOptions.meta = initRouteMeta(routeOptions.meta); + if (!__uniConfig.realEntryPagePath && + (openType === 'reLaunch' || getCurrentPages().length === 0) // redirectTo + ) { + routeOptions.meta.isQuit = true; + } + else if (!routeOptions.meta.isTabBar) { + routeOptions.meta.isQuit = false; + } + // TODO + // if (routeOptions.meta.isTabBar) { + // routeOptions.meta.visible = true + // } + return routeOptions; +} - function registerPage({ url, path, query, openType, webview, eventChannel, }) { - // fast 模式,nvue 首页时,会在nvue中主动调用registerPage并传入首页webview,此时初始化一下首页(因为此时可能还未调用registerApp) - if (webview) { - initEntry(); - } - if (preloadWebviews[url]) { - webview = preloadWebviews[url]; - const _webview = webview; - if (_webview.__page__) { - // 该预载页面已处于显示状态,不再使用该预加载页面,直接新开 - if (getCurrentPages().find((page) => page === _webview.__page__)) { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('uni-app', `preloadWebview(${path},${_webview.id}) already in use`)); - } - webview = undefined; - } - else { - if (eventChannel) { - _webview.__page__.$page.eventChannel = eventChannel; - } - addCurrentPage(_webview.__page__); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('uni-app', `reuse preloadWebview(${path},${_webview.id})`)); - } - return _webview; - } - } - } - const routeOptions = initRouteOptions(path, openType); - if (!webview) { - webview = createWebview({ path, routeOptions, query }); - } - else { - webview = plus.webview.getWebviewById(webview.id); - webview.nvue = routeOptions.meta.isNVue; - } - routeOptions.meta.id = parseInt(webview.id); - const isTabBar = !!routeOptions.meta.isTabBar; - if (isTabBar) { - tabBar$1.append(webview); - } - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('registerPage', path, webview.id)); - } - initWebview(webview, path, query, routeOptions.meta); - const route = path.substr(1); - webview.__uniapp_route = route; - const pageInstance = initPageInternalInstance(openType, url, query, routeOptions.meta, eventChannel); - initNVueEntryPage(webview); - if (webview.nvue) { - // nvue 时,先启用一个占位 vm - const fakeNVueVm = createNVueVm(parseInt(webview.id), webview, pageInstance); - initPageVm(fakeNVueVm, pageInstance); - addCurrentPage(fakeNVueVm); - } - else { - createPage(parseInt(webview.id), route, query, pageInstance, initPageOptions(routeOptions)); - } - return webview; - } - function initPageOptions({ meta }) { - const statusbarHeight = getStatusbarHeight(); - const { platform, pixelRatio, windowWidth } = getBaseSystemInfo(); - return { - css: true, - route: meta.route, - version: 1, - locale: '', - platform, - pixelRatio, - windowWidth, - disableScroll: meta.disableScroll === true, - onPageScroll: false, - onPageReachBottom: false, - onReachBottomDistance: shared.hasOwn(meta, 'onReachBottomDistance') - ? meta.onReachBottomDistance - : ON_REACH_BOTTOM_DISTANCE, - statusbarHeight, - windowTop: meta.navigationBar.type === 'float' ? statusbarHeight + NAVBAR_HEIGHT : 0, - windowBottom: tabBar$1.indexOf(meta.route) >= 0 && tabBar$1.cover ? tabBar$1.height : 0, - }; - } - function initNVueEntryPage(webview) { - const isLaunchNVuePage = webview.id === '1' && webview.nvue; - // 首页是 nvue 时,在 registerPage 时,执行路由堆栈 - if (isLaunchNVuePage) { - if (__uniConfig.splashscreen && - __uniConfig.splashscreen.autoclose && - !__uniConfig.splashscreen.alwaysShowBeforeRender) { - plus.navigator.closeSplashscreen(); - } - __uniConfig.onReady(function () { - navigateFinish(); - }); - } - } - function createNVueVm(pageId, webview, pageInstance) { - return { - $: {}, - onNVuePageCreated(vm, curNVuePage) { - vm.$ = {}; // 补充一个 nvue 的 $ 对象,模拟 vue3 的,不然有部分地方访问了 $ - vm.$getAppWebview = () => webview; - vm.getOpenerEventChannel = curNVuePage.getOpenerEventChannel; - // 替换真实的 nvue 的 vm - initPageVm(vm, pageInstance); - const pages = getAllPages(); - const index = pages.findIndex((p) => p === curNVuePage); - if (index > -1) { - pages.splice(index, 1, vm); - } - if (webview.__preload__) { - webview.__page__ = vm; - } - }, - $getAppWebview() { - return webview; - }, - getOpenerEventChannel() { - if (!pageInstance.eventChannel) { - pageInstance.eventChannel = new EventChannel(pageId); - } - return pageInstance.eventChannel; - }, - }; - } +const preloadWebviews = {}; +function removePreloadWebview(webview) { + const url = Object.keys(preloadWebviews).find((url) => preloadWebviews[url].id === webview.id); + if (url) { + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] removePreloadWebview(${webview.id})`); + } + delete preloadWebviews[url]; + } +} +function closePreloadWebview({ url }) { + const webview = preloadWebviews[url]; + if (webview) { + if (webview.__page__) { + if (!getCurrentPages().find((page) => page === webview.__page__)) { + // 未使用 + webview.close('none'); + } + else { + // 被使用 + webview.__preload__ = false; + } + } + else { + // 未使用 + webview.close('none'); + } + delete preloadWebviews[url]; + } + return webview; +} +function preloadWebview({ url, path, query, }) { + if (!preloadWebviews[url]) { + const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find((route) => route.path === path))); + preloadWebviews[url] = createWebview({ + path, + routeOptions, + query, + webviewStyle: { + __preload__: true, + __query__: JSON.stringify(query), + }, + }); + } + return preloadWebviews[url]; +} - const $navigateTo = (args, { resolve, reject }) => { - const { url, events, animationType, animationDuration } = args; - const { path, query } = parseUrl(url); - const [aniType, aniDuration] = initAnimation(path, animationType, animationDuration); - navigate(path, () => { - _navigateTo({ - url, - path, - query, - events, - aniType, - aniDuration, - }) - .then(resolve) - .catch(reject); - }, args.openType === 'appLaunch'); - }; - const navigateTo = defineAsyncApi(API_NAVIGATE_TO, $navigateTo, NavigateToProtocol, NavigateToOptions); - function _navigateTo({ url, path, query, events, aniType, aniDuration, }) { - // 当前页面触发 onHide - invokeHook(ON_HIDE); - const eventChannel = new EventChannel(getWebviewId() + 1, events); - return new Promise((resolve) => { - showWebview(registerPage({ url, path, query, openType: 'navigateTo', eventChannel }), aniType, aniDuration, () => { - resolve({ eventChannel }); - }); - setStatusBarStyle(); - }); - } - function initAnimation(path, animationType, animationDuration) { - const { globalStyle } = __uniConfig; - const meta = getRouteMeta(path); - return [ - animationType || - meta.animationType || - globalStyle.animationType || - ANI_SHOW, - animationDuration || - meta.animationDuration || - globalStyle.animationDuration || - ANI_DURATION, - ]; - } +function registerPage({ url, path, query, openType, webview, eventChannel, }) { + // fast 模式,nvue 首页时,会在nvue中主动调用registerPage并传入首页webview,此时初始化一下首页(因为此时可能还未调用registerApp) + if (webview) { + initEntry(); + } + if (preloadWebviews[url]) { + webview = preloadWebviews[url]; + const _webview = webview; + if (_webview.__page__) { + // 该预载页面已处于显示状态,不再使用该预加载页面,直接新开 + if (getCurrentPages().find((page) => page === _webview.__page__)) { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('uni-app', `preloadWebview(${path},${_webview.id}) already in use`)); + } + webview = undefined; + } + else { + if (eventChannel) { + _webview.__page__.$page.eventChannel = eventChannel; + } + addCurrentPage(_webview.__page__); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('uni-app', `reuse preloadWebview(${path},${_webview.id})`)); + } + return _webview; + } + } + } + const routeOptions = initRouteOptions(path, openType); + if (!webview) { + webview = createWebview({ path, routeOptions, query }); + } + else { + webview = plus.webview.getWebviewById(webview.id); + webview.nvue = routeOptions.meta.isNVue; + } + routeOptions.meta.id = parseInt(webview.id); + const isTabBar = !!routeOptions.meta.isTabBar; + if (isTabBar) { + tabBar$1.append(webview); + } + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('registerPage', path, webview.id)); + } + initWebview(webview, path, query, routeOptions.meta); + const route = path.substr(1); + webview.__uniapp_route = route; + const pageInstance = initPageInternalInstance(openType, url, query, routeOptions.meta, eventChannel); + initNVueEntryPage(webview); + if (webview.nvue) { + // nvue 时,先启用一个占位 vm + const fakeNVueVm = createNVueVm(parseInt(webview.id), webview, pageInstance); + initPageVm(fakeNVueVm, pageInstance); + addCurrentPage(fakeNVueVm); + } + else { + createPage(parseInt(webview.id), route, query, pageInstance, initPageOptions(routeOptions)); + } + return webview; +} +function initPageOptions({ meta }) { + const statusbarHeight = getStatusbarHeight(); + const { platform, pixelRatio, windowWidth } = getBaseSystemInfo(); + return { + css: true, + route: meta.route, + version: 1, + locale: '', + platform, + pixelRatio, + windowWidth, + disableScroll: meta.disableScroll === true, + onPageScroll: false, + onPageReachBottom: false, + onReachBottomDistance: hasOwn$1(meta, 'onReachBottomDistance') + ? meta.onReachBottomDistance + : ON_REACH_BOTTOM_DISTANCE, + statusbarHeight, + windowTop: meta.navigationBar.type === 'float' ? statusbarHeight + NAVBAR_HEIGHT : 0, + windowBottom: tabBar$1.indexOf(meta.route) >= 0 && tabBar$1.cover ? tabBar$1.height : 0, + }; +} +function initNVueEntryPage(webview) { + const isLaunchNVuePage = webview.id === '1' && webview.nvue; + // 首页是 nvue 时,在 registerPage 时,执行路由堆栈 + if (isLaunchNVuePage) { + if (__uniConfig.splashscreen && + __uniConfig.splashscreen.autoclose && + !__uniConfig.splashscreen.alwaysShowBeforeRender) { + plus.navigator.closeSplashscreen(); + } + __uniConfig.onReady(function () { + navigateFinish(); + }); + } +} +function createNVueVm(pageId, webview, pageInstance) { + return { + $: {}, + onNVuePageCreated(vm, curNVuePage) { + vm.$ = {}; // 补充一个 nvue 的 $ 对象,模拟 vue3 的,不然有部分地方访问了 $ + vm.$getAppWebview = () => webview; + vm.getOpenerEventChannel = curNVuePage.getOpenerEventChannel; + // 替换真实的 nvue 的 vm + initPageVm(vm, pageInstance); + const pages = getAllPages(); + const index = pages.findIndex((p) => p === curNVuePage); + if (index > -1) { + pages.splice(index, 1, vm); + } + if (webview.__preload__) { + webview.__page__ = vm; + } + }, + $getAppWebview() { + return webview; + }, + getOpenerEventChannel() { + if (!pageInstance.eventChannel) { + pageInstance.eventChannel = new EventChannel(pageId); + } + return pageInstance.eventChannel; + }, + }; +} - const $switchTab = (args, { resolve, reject }) => { - const { url } = args; - const { path, query } = parseUrl(url); - navigate(path, () => { - _switchTab({ - url, - path, - query, - }) - .then(resolve) - .catch(reject); - }, args.openType === 'appLaunch'); - }; - const switchTab = defineAsyncApi(API_SWITCH_TAB, $switchTab, SwitchTabProtocol, SwitchTabOptions); - function _switchTab({ url, path, query, }) { - tabBar$1.switchTab(path.slice(1)); - const pages = getCurrentPages(); - const len = pages.length; - let callOnHide = false; - let callOnShow = false; - let currentPage; - if (len >= 1) { - // 前一个页面是非 tabBar 页面 - currentPage = pages[len - 1]; - if (currentPage && !currentPage.$.__isTabBar) { - // 前一个页面为非 tabBar 页面时,目标tabBar需要强制触发onShow - // 该情况下目标页tabBarPage的visible是不对的 - // 除非每次路由跳转都处理一遍tabBarPage的visible,目前仅switchTab会处理 - // 简单起见,暂时直接判断该情况,执行onShow - callOnShow = true; - pages.reverse().forEach((page) => { - if (!page.$.__isTabBar && page !== currentPage) { - closePage(page, 'none'); - } - }); - removePage(currentPage); - // 延迟执行避免iOS应用退出 - setTimeout(() => { - if (currentPage.$page.openType === 'redirectTo') { - closeWebview(currentPage.$getAppWebview(), ANI_CLOSE, ANI_DURATION); - } - else { - closeWebview(currentPage.$getAppWebview(), 'auto'); - } - }, 100); - } - else { - callOnHide = true; - } - } - let tabBarPage; - // 查找当前 tabBarPage,且设置 visible - getAllPages().forEach((page) => { - if (addLeadingSlash(page.route) === path) { - if (!page.$.__isActive) { - // 之前未显示 - callOnShow = true; - } - page.$.__isActive = true; - tabBarPage = page; - } - else { - if (page.$.__isTabBar) { - page.$.__isActive = false; - } - } - }); - // 相同tabBar页面 - if (currentPage === tabBarPage) { - callOnHide = false; - } - if (currentPage && callOnHide) { - invokeHook(currentPage, ON_HIDE); - } - return new Promise((resolve) => { - if (tabBarPage) { - const webview = tabBarPage.$getAppWebview(); - webview.show('none'); - // 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确 - if (callOnShow && !webview.__preload__) { - invokeHook(tabBarPage, ON_SHOW); - } - setStatusBarStyle(); - resolve(undefined); - } - else { - showWebview(registerPage({ - url, - path, - query, - openType: 'switchTab', - }), 'none', 0, () => { - setStatusBarStyle(); - resolve(undefined); - }, 70); - } - }); - } +const $navigateTo = (args, { resolve, reject }) => { + const { url, events, animationType, animationDuration } = args; + const { path, query } = parseUrl(url); + const [aniType, aniDuration] = initAnimation(path, animationType, animationDuration); + navigate(path, () => { + _navigateTo({ + url, + path, + query, + events, + aniType, + aniDuration, + }) + .then(resolve) + .catch(reject); + }, args.openType === 'appLaunch'); +}; +const navigateTo = defineAsyncApi(API_NAVIGATE_TO, $navigateTo, NavigateToProtocol, NavigateToOptions); +function _navigateTo({ url, path, query, events, aniType, aniDuration, }) { + // 当前页面触发 onHide + invokeHook(ON_HIDE); + const eventChannel = new EventChannel(getWebviewId() + 1, events); + return new Promise((resolve) => { + showWebview(registerPage({ url, path, query, openType: 'navigateTo', eventChannel }), aniType, aniDuration, () => { + resolve({ eventChannel }); + }); + setStatusBarStyle(); + }); +} +function initAnimation(path, animationType, animationDuration) { + const { globalStyle } = __uniConfig; + const meta = getRouteMeta(path); + return [ + animationType || + meta.animationType || + globalStyle.animationType || + ANI_SHOW, + animationDuration || + meta.animationDuration || + globalStyle.animationDuration || + ANI_DURATION, + ]; +} - let isLaunchWebviewReady = false; // 目前首页双向确定 ready,可能会导致触发两次 onWebviewReady(主要是 Android) - function subscribeWebviewReady(_data, pageId) { - const isLaunchWebview = pageId === '1'; - if (isLaunchWebview && isLaunchWebviewReady) { - if ((process.env.NODE_ENV !== 'production')) { - console.log('[uni-app] onLaunchWebviewReady.prevent'); - } - return; - } - if (isLaunchWebview) { - // 首页 - isLaunchWebviewReady = true; - setPreloadWebview(plus.webview.getLaunchWebview()); - } - else if (!preloadWebview$1) { - // preloadWebview 不存在,重新加载一下 - setPreloadWebview(plus.webview.getWebviewById(pageId)); - } - if (preloadWebview$1.id !== pageId) { - return console.error(`webviewReady[${preloadWebview$1.id}][${pageId}] not match`); - } - preloadWebview$1.loaded = true; // 标记已 ready - UniServiceJSBridge.emit(ON_WEBVIEW_READY + '.' + pageId); - isLaunchWebview && onLaunchWebviewReady(); - } - function onLaunchWebviewReady() { - const { autoclose, alwaysShowBeforeRender } = __uniConfig.splashscreen; - if (autoclose && !alwaysShowBeforeRender) { - plus.navigator.closeSplashscreen(); - } - const entryPagePath = addLeadingSlash(__uniConfig.entryPagePath); - const routeOptions = getRouteOptions(entryPagePath); - if (!routeOptions.meta.isNVue) { - // 非 nvue 首页,需要主动跳转 - const args = { - url: entryPagePath + (__uniConfig.entryPageQuery || ''), - openType: 'appLaunch', - }; - const handler = { resolve() { }, reject() { } }; - if (routeOptions.meta.isTabBar) { - return $switchTab(args, handler); - } - return $navigateTo(args, handler); - } - } +const $switchTab = (args, { resolve, reject }) => { + const { url } = args; + const { path, query } = parseUrl(url); + navigate(path, () => { + _switchTab({ + url, + path, + query, + }) + .then(resolve) + .catch(reject); + }, args.openType === 'appLaunch'); +}; +const switchTab = defineAsyncApi(API_SWITCH_TAB, $switchTab, SwitchTabProtocol, SwitchTabOptions); +function _switchTab({ url, path, query, }) { + tabBar$1.switchTab(path.slice(1)); + const pages = getCurrentPages(); + const len = pages.length; + let callOnHide = false; + let callOnShow = false; + let currentPage; + if (len >= 1) { + // 前一个页面是非 tabBar 页面 + currentPage = pages[len - 1]; + if (currentPage && !currentPage.$.__isTabBar) { + // 前一个页面为非 tabBar 页面时,目标tabBar需要强制触发onShow + // 该情况下目标页tabBarPage的visible是不对的 + // 除非每次路由跳转都处理一遍tabBarPage的visible,目前仅switchTab会处理 + // 简单起见,暂时直接判断该情况,执行onShow + callOnShow = true; + pages.reverse().forEach((page) => { + if (!page.$.__isTabBar && page !== currentPage) { + closePage(page, 'none'); + } + }); + removePage(currentPage); + // 延迟执行避免iOS应用退出 + setTimeout(() => { + if (currentPage.$page.openType === 'redirectTo') { + closeWebview(currentPage.$getAppWebview(), ANI_CLOSE, ANI_DURATION); + } + else { + closeWebview(currentPage.$getAppWebview(), 'auto'); + } + }, 100); + } + else { + callOnHide = true; + } + } + let tabBarPage; + // 查找当前 tabBarPage,且设置 visible + getAllPages().forEach((page) => { + if (addLeadingSlash(page.route) === path) { + if (!page.$.__isActive) { + // 之前未显示 + callOnShow = true; + } + page.$.__isActive = true; + tabBarPage = page; + } + else { + if (page.$.__isTabBar) { + page.$.__isActive = false; + } + } + }); + // 相同tabBar页面 + if (currentPage === tabBarPage) { + callOnHide = false; + } + if (currentPage && callOnHide) { + invokeHook(currentPage, ON_HIDE); + } + return new Promise((resolve) => { + if (tabBarPage) { + const webview = tabBarPage.$getAppWebview(); + webview.show('none'); + // 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确 + if (callOnShow && !webview.__preload__) { + invokeHook(tabBarPage, ON_SHOW); + } + setStatusBarStyle(); + resolve(undefined); + } + else { + showWebview(registerPage({ + url, + path, + query, + openType: 'switchTab', + }), 'none', 0, () => { + setStatusBarStyle(); + resolve(undefined); + }, 70); + } + }); +} - function onWebviewInserted(_, pageId) { - const page = getPageById(parseInt(pageId)); - page && (page.__uniapp_webview = true); - } - function onWebviewRemoved(_, pageId) { - const page = getPageById(parseInt(pageId)); - page && delete page.__uniapp_webview; - } +let isLaunchWebviewReady = false; // 目前首页双向确定 ready,可能会导致触发两次 onWebviewReady(主要是 Android) +function subscribeWebviewReady(_data, pageId) { + const isLaunchWebview = pageId === '1'; + if (isLaunchWebview && isLaunchWebviewReady) { + if ((process.env.NODE_ENV !== 'production')) { + console.log('[uni-app] onLaunchWebviewReady.prevent'); + } + return; + } + if (isLaunchWebview) { + // 首页 + isLaunchWebviewReady = true; + setPreloadWebview(plus.webview.getLaunchWebview()); + } + else if (!preloadWebview$1) { + // preloadWebview 不存在,重新加载一下 + setPreloadWebview(plus.webview.getWebviewById(pageId)); + } + if (preloadWebview$1.id !== pageId) { + return console.error(`webviewReady[${preloadWebview$1.id}][${pageId}] not match`); + } + preloadWebview$1.loaded = true; // 标记已 ready + UniServiceJSBridge.emit(ON_WEBVIEW_READY + '.' + pageId); + isLaunchWebview && onLaunchWebviewReady(); +} +function onLaunchWebviewReady() { + const { autoclose, alwaysShowBeforeRender } = __uniConfig.splashscreen; + if (autoclose && !alwaysShowBeforeRender) { + plus.navigator.closeSplashscreen(); + } + const entryPagePath = addLeadingSlash(__uniConfig.entryPagePath); + const routeOptions = getRouteOptions(entryPagePath); + if (!routeOptions.meta.isNVue) { + // 非 nvue 首页,需要主动跳转 + const args = { + url: entryPagePath + (__uniConfig.entryPageQuery || ''), + openType: 'appLaunch', + }; + const handler = { resolve() { }, reject() { } }; + if (routeOptions.meta.isTabBar) { + return $switchTab(args, handler); + } + return $navigateTo(args, handler); + } +} - const onWebInvokeAppService = ({ name, arg }, pageIds) => { - if (name === 'postMessage') { - onMessage(pageIds[0], arg); - } - else { - uni[name](shared.extend(arg, { - fail(res) { - console.error(res.errMsg); - }, - })); - } - }; - function onMessage(pageId, arg) { - const uniNode = findNodeByTagName('web-view', parseInt(pageId)); - uniNode && - uniNode.dispatchEvent(createUniEvent({ - type: 'onMessage', - target: Object.create(null), - currentTarget: Object.create(null), - detail: { - data: [arg], - }, - })); - } +function onWebviewInserted(_, pageId) { + const page = getPageById(parseInt(pageId)); + page && (page.__uniapp_webview = true); +} +function onWebviewRemoved(_, pageId) { + const page = getPageById(parseInt(pageId)); + page && delete page.__uniapp_webview; +} - function onWxsInvokeCallMethod({ nodeId, ownerId, method, args, }, pageId) { - const node = findNodeById(nodeId, parseInt(pageId)); - if (!node) { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('Wxs', 'CallMethod', nodeId, 'not found')); - } - return; - } - const vm = resolveOwnerVm(ownerId, node.__vueParentComponent); - if (!vm) { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('Wxs', 'CallMethod', 'vm not found')); - } - return; - } - if (!vm[method]) { - if ((process.env.NODE_ENV !== 'production')) { - console.error(formatLog('Wxs', 'CallMethod', method, ' not found')); - } - return; - } - vm[method](args); - } - function resolveOwnerVm(ownerId, vm) { - if (!vm) { - return null; - } - if (vm.uid === ownerId) { - return vm.proxy; - } - let parent = vm.parent; - while (parent) { - if (parent.uid === ownerId) { - return parent.proxy; - } - parent = parent.parent; - } - return vm.proxy; - } +const onWebInvokeAppService = ({ name, arg }, pageIds) => { + if (name === 'postMessage') { + onMessage(pageIds[0], arg); + } + else { + uni[name](extend(arg, { + fail(res) { + console.error(res.errMsg); + }, + })); + } +}; +function onMessage(pageId, arg) { + const uniNode = findNodeByTagName('web-view', parseInt(pageId)); + uniNode && + uniNode.dispatchEvent(createUniEvent({ + type: 'onMessage', + target: Object.create(null), + currentTarget: Object.create(null), + detail: { + data: [arg], + }, + })); +} - function initSubscribeHandlers() { - const { subscribe, subscribeHandler, publishHandler } = UniServiceJSBridge; - onPlusMessage('subscribeHandler', ({ type, data, pageId }) => { - subscribeHandler(type, data, pageId); - }); - onPlusMessage(WEB_INVOKE_APPSERVICE, ({ data, webviewIds }) => { - onWebInvokeAppService(data, webviewIds); - }); - if (__uniConfig.renderer !== 'native') { - // 非纯原生 - subscribe(ON_WEBVIEW_READY, subscribeWebviewReady); - subscribe(VD_SYNC, onVdSync); - subscribeServiceMethod(); - subscribeAd(); - subscribeNavigator(); - subscribe(WEBVIEW_INSERTED, onWebviewInserted); - subscribe(WEBVIEW_REMOVED, onWebviewRemoved); - subscribe(ON_WXS_INVOKE_CALL_METHOD, onWxsInvokeCallMethod); - const routeOptions = getRouteOptions(addLeadingSlash(__uniConfig.entryPagePath)); - if (routeOptions && !routeOptions.meta.isNVue) { - // 防止首页 webview 初始化过早, service 还未开始监听 - publishHandler(ON_WEBVIEW_READY, {}, 1); - } - } - } +function onWxsInvokeCallMethod({ nodeId, ownerId, method, args, }, pageId) { + const node = findNodeById(nodeId, parseInt(pageId)); + if (!node) { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('Wxs', 'CallMethod', nodeId, 'not found')); + } + return; + } + const vm = resolveOwnerVm(ownerId, node.__vueParentComponent); + if (!vm) { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('Wxs', 'CallMethod', 'vm not found')); + } + return; + } + if (!vm[method]) { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('Wxs', 'CallMethod', method, ' not found')); + } + return; + } + vm[method](args); +} +function resolveOwnerVm(ownerId, vm) { + if (!vm) { + return null; + } + if (vm.uid === ownerId) { + return vm.proxy; + } + let parent = vm.parent; + while (parent) { + if (parent.uid === ownerId) { + return parent.proxy; + } + parent = parent.parent; + } + return vm.proxy; +} - let appCtx; - const defaultApp = { - globalData: {}, - }; - function getApp$1({ allowDefault = false } = {}) { - if (appCtx) { - // 真实的 App 已初始化 - return appCtx; - } - if (allowDefault) { - // 返回默认实现 - return defaultApp; - } - console.error('[warn]: getApp() failed. Learn more: https://uniapp.dcloud.io/collocation/frame/window?id=getapp.'); - } - function registerApp(appVm) { - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('registerApp')); - } - initVueApp(appVm); - appCtx = appVm; - initAppVm(appCtx); - shared.extend(appCtx, defaultApp); // 拷贝默认实现 - defineGlobalData(appCtx, defaultApp.globalData); - initService(); - initEntry(); - initTabBar(); - initGlobalEvent(); - initSubscribeHandlers(); - initAppLaunch(appVm); - // 10s后清理临时文件 - setTimeout(clearTempFile, 10000); - __uniConfig.ready = true; - } +function initSubscribeHandlers() { + const { subscribe, subscribeHandler, publishHandler } = UniServiceJSBridge; + onPlusMessage('subscribeHandler', ({ type, data, pageId }) => { + subscribeHandler(type, data, pageId); + }); + onPlusMessage(WEB_INVOKE_APPSERVICE, ({ data, webviewIds }) => { + onWebInvokeAppService(data, webviewIds); + }); + if (__uniConfig.renderer !== 'native') { + // 非纯原生 + subscribe(ON_WEBVIEW_READY, subscribeWebviewReady); + subscribe(VD_SYNC, onVdSync); + subscribeServiceMethod(); + subscribeAd(); + subscribeNavigator(); + subscribe(WEBVIEW_INSERTED, onWebviewInserted); + subscribe(WEBVIEW_REMOVED, onWebviewRemoved); + subscribe(ON_WXS_INVOKE_CALL_METHOD, onWxsInvokeCallMethod); + const routeOptions = getRouteOptions(addLeadingSlash(__uniConfig.entryPagePath)); + if (routeOptions && !routeOptions.meta.isNVue) { + // 防止首页 webview 初始化过早, service 还未开始监听 + publishHandler(ON_WEBVIEW_READY, {}, 1); + } + } +} - var index$1 = { - install(app) { - initMount(app); - initApp(app); - initServicePlugin(app); - }, - }; - function initMount(app) { - const oldMount = app.mount; - app.mount = (rootContainer) => { - const instance = oldMount.call(app, rootContainer); - if (rootContainer === '#app') { - registerApp(instance); - } - return instance; - }; - } +let appCtx; +const defaultApp = { + globalData: {}, +}; +function getApp$1({ allowDefault = false } = {}) { + if (appCtx) { + // 真实的 App 已初始化 + return appCtx; + } + if (allowDefault) { + // 返回默认实现 + return defaultApp; + } + console.error('[warn]: getApp() failed. Learn more: https://uniapp.dcloud.io/collocation/frame/window?id=getapp.'); +} +function registerApp(appVm) { + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('registerApp')); + } + initVueApp(appVm); + appCtx = appVm; + initAppVm(appCtx); + extend(appCtx, defaultApp); // 拷贝默认实现 + defineGlobalData(appCtx, defaultApp.globalData); + initService(); + initEntry(); + initTabBar(); + initGlobalEvent(); + initSubscribeHandlers(); + initAppLaunch(appVm); + // 10s后清理临时文件 + setTimeout(clearTempFile, 10000); + __uniConfig.ready = true; +} - const EventType = { - load: 'load', - close: 'close', - error: 'error', - adClicked: 'adClicked', - }; - class AdEventHandler { - constructor() { - this._callbacks = {}; - } - onLoad(callback) { - this._addEventListener(EventType.load, callback); - } - onClose(callback) { - this._addEventListener(EventType.close, callback); - } - onError(callback) { - this._addEventListener(EventType.error, callback); - } - offLoad(callback) { - this._removeEventListener(EventType.load, callback); - } - offClose(callback) { - this._removeEventListener(EventType.close, callback); - } - offError(callback) { - this._removeEventListener(EventType.error, callback); - } - _addEventListener(type, callback) { - if (typeof callback !== 'function') { - return; - } - if (!this._callbacks[type]) { - this._callbacks[type] = []; - } - this._callbacks[type].push(callback); - } - _removeEventListener(type, callback) { - const arrayFunction = this._callbacks[type]; - const index = arrayFunction.indexOf(callback); - if (index > -1) { - arrayFunction.splice(index, 1); - } - } - _dispatchEvent(name, data) { - this._callbacks[name].forEach((callback) => { - callback(data || {}); - }); - } - } - class AdBase extends AdEventHandler { - constructor(adInstance, options) { - super(); - this.preload = true; - this._isLoaded = false; - this._isLoading = false; - this._loadPromiseResolve = null; - this._loadPromiseReject = null; - this._showPromiseResolve = null; - this._showPromiseReject = null; - this.preload = options.preload !== undefined ? options.preload : false; - const ad = (this._adInstance = adInstance); - ad.onLoad(() => { - this._isLoaded = true; - this._isLoading = false; - if (this._loadPromiseResolve != null) { - this._loadPromiseResolve(); - this._loadPromiseResolve = null; - } - if (this._showPromiseResolve != null) { - this._showPromiseResolve(); - this._showPromiseResolve = null; - this._showAd(); - } - this._dispatchEvent(EventType.load, {}); - }); - ad.onClose((e) => { - this._isLoaded = false; - this._isLoading = false; - this._dispatchEvent(EventType.close, e); - if (this.preload === true) { - this._loadAd(); - } - }); - ad.onError((e) => { - this._isLoading = false; - const data = { - code: e.code, - errMsg: e.message, - }; - this._dispatchEvent(EventType.error, data); - const error = new Error(JSON.stringify(data)); - if (this._loadPromiseReject != null) { - this._loadPromiseReject(error); - this._loadPromiseReject = null; - } - if (this._showPromiseReject != null) { - this._showPromiseReject(error); - this._showPromiseReject = null; - } - }); - ad.onAdClicked && - ad.onAdClicked(() => { - this._dispatchEvent(EventType.adClicked, {}); - }); - } - getProvider() { - return this._adInstance.getProvider(); - } - load() { - return new Promise((resolve, reject) => { - this._loadPromiseResolve = resolve; - this._loadPromiseReject = reject; - if (this._isLoading) { - return; - } - if (this._isLoaded) { - resolve(''); - } - else { - this._loadAd(); - } - }); - } - show() { - return new Promise((resolve, reject) => { - this._showPromiseResolve = resolve; - this._showPromiseReject = reject; - if (this._isLoading) { - return; - } - if (this._isLoaded) { - this._showAd(); - resolve(''); - } - else { - this._loadAd(); - } - }); - } - destroy() { - this._adInstance.destroy(); - } - _loadAd() { - this._isLoaded = false; - this._isLoading = true; - this._adInstance.load(); - } - _showAd() { - this._adInstance.show(); - } - } +var index$1 = { + install(app) { + initMount(app); + initApp(app); + initServicePlugin(app); + }, +}; +function initMount(app) { + const oldMount = app.mount; + app.mount = (rootContainer) => { + const instance = oldMount.call(app, rootContainer); + if (rootContainer === '#app') { + registerApp(instance); + } + return instance; + }; +} - class RewardedVideoAd extends AdBase { - constructor(options) { - super(plus.ad.createRewardedVideoAd(options), options); - this._loadAd(); - } - } - const createRewardedVideoAd = (defineSyncApi(API_CREATE_REWARDED_VIDEO_AD, (options) => { - return new RewardedVideoAd(options); - }, CreateRewardedVideoAdProtocol, CreateRewardedVideoAdOptions)); - - class FullScreenVideoAd extends AdBase { - constructor(options) { - super(plus.ad.createFullScreenVideoAd(options), options); - this.preload = false; - } - } - const createFullScreenVideoAd = (defineSyncApi(API_CREATE_FULL_SCREEN_VIDEO_AD, (options) => { - return new FullScreenVideoAd(options); - }, CreateFullScreenVideoAdProtocol, CreateFullScreenVideoAdOptions)); - - class InterstitialAd extends AdBase { - constructor(options) { - super(plus.ad.createInterstitialAd(options), options); - this.preload = false; - this._loadAd(); - } - } - const createInterstitialAd = (defineSyncApi(API_CREATE_INTERSTITIAL_AD, (options) => { - return new InterstitialAd(options); - }, CreateInterstitialAdProtocol, CreateInterstitialAdOptions)); - - const sdkCache = {}; - const sdkQueue = {}; - function initSDK(options) { - const provider = options.provider; - if (!sdkCache[provider]) { - sdkCache[provider] = {}; - } - if (typeof sdkCache[provider].plugin === 'object') { - options.success(sdkCache[provider].plugin); - return; - } - if (!sdkQueue[provider]) { - sdkQueue[provider] = []; - } - sdkQueue[provider].push(options); - if (sdkCache[provider].status === true) { - options.__plugin = sdkCache[provider].plugin; - return; - } - sdkCache[provider].status = true; - const plugin = requireNativePlugin(provider); - if (!plugin || !plugin.initSDK) { - sdkQueue[provider].forEach((item) => { - item.fail({ - code: -1, - message: 'provider [' + provider + '] invalid', - }); - }); - sdkQueue[provider].length = 0; - sdkCache[provider].status = false; - return; - } - // TODO - sdkCache[provider].plugin = plugin; - options.__plugin = plugin; - plugin.initSDK((res) => { - const isSuccess = res.code === 1 || res.code === '1'; - if (isSuccess) { - sdkCache[provider].plugin = plugin; - } - else { - sdkCache[provider].status = false; - } - sdkQueue[provider].forEach((item) => { - if (isSuccess) { - item.success(item.__plugin); - } - else { - item.fail(res); - } - }); - sdkQueue[provider].length = 0; - }); - } - class InteractiveAd extends AdEventHandler { - constructor(options) { - super(); - this._adpid = ''; - this._provider = ''; - this._userData = null; - this._isLoaded = false; - this._isLoading = false; - this._loadPromiseResolve = null; - this._loadPromiseReject = null; - this._showPromiseResolve = null; - this._showPromiseReject = null; - this._adInstance = null; - this._adError = ''; - this._adpid = options.adpid; - this._provider = options.provider; - this._userData = options.userData; - setTimeout(() => { - this._init(); - }); - } - _init() { - this._adError = ''; - initSDK({ - provider: this._provider, - success: (res) => { - this._adInstance = res; - if (this._userData) { - this.bindUserData(this._userData); - } - this._loadAd(); - }, - fail: (err) => { - this._adError = err; - if (this._loadPromiseReject != null) { - this._loadPromiseReject(this._createError(err)); - this._loadPromiseReject = null; - } - this._dispatchEvent(EventType.error, err); - }, - }); - } - getProvider() { - return this._provider; - } - load() { - return new Promise((resolve, reject) => { - this._loadPromiseResolve = resolve; - this._loadPromiseReject = reject; - if (this._isLoading) { - return; - } - if (this._adError) { - this._init(); - return; - } - if (this._isLoaded) { - resolve(''); - } - else { - this._loadAd(); - } - }); - } - show() { - return new Promise((resolve, reject) => { - this._showPromiseResolve = resolve; - this._showPromiseReject = reject; - if (this._isLoading) { - return; - } - if (this._adError) { - this._init(); - return; - } - if (this._isLoaded) { - this._showAd(); - resolve(''); - } - else { - this._loadAd(); - } - }); - } - reportExposure() { - if (this._adInstance !== null) { - this._adInstance.reportExposure(); - } - } - bindUserData(data) { - if (this._adInstance !== null) { - this._adInstance.bindUserData(data); - } - } - destroy() { - if (this._adInstance !== null && this._adInstance.destroy) { - this._adInstance.destroy({ - adpid: this._adpid, - }); - } - } - _loadAd() { - if (this._adInstance !== null) { - if (this._isLoading === true) { - return; - } - this._isLoading = true; - this._adInstance.loadData({ - adpid: this._adpid, - }, (res) => { - this._isLoaded = true; - this._isLoading = false; - if (this._loadPromiseResolve != null) { - this._loadPromiseResolve(); - this._loadPromiseResolve = null; - } - if (this._showPromiseResolve != null) { - this._showPromiseResolve(); - this._showPromiseResolve = null; - this._showAd(); - } - this._dispatchEvent(EventType.load, res); - }, (err) => { - this._isLoading = false; - if (this._showPromiseReject != null) { - this._showPromiseReject(this._createError(err)); - this._showPromiseReject = null; - } - this._dispatchEvent(EventType.error, err); - }); - } - } - _showAd() { - if (this._adInstance !== null && this._isLoaded === true) { - this._adInstance.show({ - adpid: this._adpid, - }, () => { - this._isLoaded = false; - }, (err) => { - this._isLoaded = false; - if (this._showPromiseReject != null) { - this._showPromiseReject(this._createError(err)); - this._showPromiseReject = null; - } - this._dispatchEvent(EventType.error, err); - }); - } - } - _createError(err) { - return new Error(JSON.stringify(err)); - } - } - const createInteractiveAd = (defineSyncApi(API_CREATE_INTERACTIVE_AD, (options) => { - return new InteractiveAd(options); - }, CreateInteractiveAdProtocol, CreateInteractiveAdOptions)); - - const navigateBack = defineAsyncApi(API_NAVIGATE_BACK, (args, { resolve, reject }) => { - const page = getCurrentPage(); - if (!page) { - return reject(`getCurrentPages is empty`); - } - if (invokeHook(page, ON_BACK_PRESS, { - from: args.from, - })) { - return resolve(); - } - uni.hideToast(); - uni.hideLoading(); - if (page.$page.meta.isQuit) { - quit(); - } - else if (isDirectPage(page)) { - reLaunchEntryPage(); - } - else { - const { delta, animationType, animationDuration } = args; - back(delta, animationType, animationDuration); - } - return resolve(); - }, NavigateBackProtocol, NavigateBackOptions); - let firstBackTime = 0; - function quit() { - initI18nAppMsgsOnce(); - if (!firstBackTime) { - firstBackTime = Date.now(); - plus.nativeUI.toast(useI18n().t('uni.app.quit')); - setTimeout(() => { - firstBackTime = 0; - }, 2000); - } - else if (Date.now() - firstBackTime < 2000) { - plus.runtime.quit(); - } - } - function back(delta, animationType, animationDuration) { - const pages = getCurrentPages(); - const len = pages.length; - const currentPage = pages[len - 1]; - if (delta > 1) { - // 中间页隐藏 - pages - .slice(len - delta, len - 1) - .reverse() - .forEach((deltaPage) => { - closeWebview(plus.webview.getWebviewById(deltaPage.$page.id + ''), 'none', 0); - }); - } - const backPage = function (webview) { - if (animationType) { - closeWebview(webview, animationType, animationDuration || ANI_DURATION); - } - else { - if (currentPage.$page.openType === 'redirectTo') { - // 如果是 redirectTo 跳转的,需要指定 back 动画 - closeWebview(webview, ANI_CLOSE, ANI_DURATION); - } - else { - closeWebview(webview, 'auto'); - } - } - pages - .slice(len - delta, len) - .forEach((page) => removePage(page)); - setStatusBarStyle(); - // 前一个页面触发 onShow - invokeHook(ON_SHOW); - }; - const webview = plus.webview.getWebviewById(currentPage.$page.id + ''); - if (!currentPage.__uniapp_webview) { - return backPage(webview); - } - backWebview(webview, () => { - backPage(webview); - }); - } +const EventType = { + load: 'load', + close: 'close', + error: 'error', + adClicked: 'adClicked', +}; +class AdEventHandler { + constructor() { + this._callbacks = {}; + } + onLoad(callback) { + this._addEventListener(EventType.load, callback); + } + onClose(callback) { + this._addEventListener(EventType.close, callback); + } + onError(callback) { + this._addEventListener(EventType.error, callback); + } + offLoad(callback) { + this._removeEventListener(EventType.load, callback); + } + offClose(callback) { + this._removeEventListener(EventType.close, callback); + } + offError(callback) { + this._removeEventListener(EventType.error, callback); + } + _addEventListener(type, callback) { + if (typeof callback !== 'function') { + return; + } + if (!this._callbacks[type]) { + this._callbacks[type] = []; + } + this._callbacks[type].push(callback); + } + _removeEventListener(type, callback) { + const arrayFunction = this._callbacks[type]; + const index = arrayFunction.indexOf(callback); + if (index > -1) { + arrayFunction.splice(index, 1); + } + } + _dispatchEvent(name, data) { + this._callbacks[name].forEach((callback) => { + callback(data || {}); + }); + } +} +class AdBase extends AdEventHandler { + constructor(adInstance, options) { + super(); + this.preload = true; + this._isLoaded = false; + this._isLoading = false; + this._loadPromiseResolve = null; + this._loadPromiseReject = null; + this._showPromiseResolve = null; + this._showPromiseReject = null; + this.preload = options.preload !== undefined ? options.preload : false; + const ad = (this._adInstance = adInstance); + ad.onLoad(() => { + this._isLoaded = true; + this._isLoading = false; + if (this._loadPromiseResolve != null) { + this._loadPromiseResolve(); + this._loadPromiseResolve = null; + } + if (this._showPromiseResolve != null) { + this._showPromiseResolve(); + this._showPromiseResolve = null; + this._showAd(); + } + this._dispatchEvent(EventType.load, {}); + }); + ad.onClose((e) => { + this._isLoaded = false; + this._isLoading = false; + this._dispatchEvent(EventType.close, e); + if (this.preload === true) { + this._loadAd(); + } + }); + ad.onError((e) => { + this._isLoading = false; + const data = { + code: e.code, + errMsg: e.message, + }; + this._dispatchEvent(EventType.error, data); + const error = new Error(JSON.stringify(data)); + if (this._loadPromiseReject != null) { + this._loadPromiseReject(error); + this._loadPromiseReject = null; + } + if (this._showPromiseReject != null) { + this._showPromiseReject(error); + this._showPromiseReject = null; + } + }); + ad.onAdClicked && + ad.onAdClicked(() => { + this._dispatchEvent(EventType.adClicked, {}); + }); + } + getProvider() { + return this._adInstance.getProvider(); + } + load() { + return new Promise((resolve, reject) => { + this._loadPromiseResolve = resolve; + this._loadPromiseReject = reject; + if (this._isLoading) { + return; + } + if (this._isLoaded) { + resolve(''); + } + else { + this._loadAd(); + } + }); + } + show() { + return new Promise((resolve, reject) => { + this._showPromiseResolve = resolve; + this._showPromiseReject = reject; + if (this._isLoading) { + return; + } + if (this._isLoaded) { + this._showAd(); + resolve(''); + } + else { + this._loadAd(); + } + }); + } + destroy() { + this._adInstance.destroy(); + } + _loadAd() { + this._isLoaded = false; + this._isLoading = true; + this._adInstance.load(); + } + _showAd() { + this._adInstance.show(); + } +} - const redirectTo = defineAsyncApi(API_REDIRECT_TO, ({ url }, { resolve, reject }) => { - const { path, query } = parseUrl(url); - navigate(path, () => { - _redirectTo({ - url, - path, - query, - }) - .then(resolve) - .catch(reject); - }); - }, RedirectToProtocol, RedirectToOptions); - function _redirectTo({ url, path, query, }) { - // TODO exists - // if (exists === 'back') { - // const existsPageIndex = findExistsPageIndex(url) - // if (existsPageIndex !== -1) { - // const delta = len - existsPageIndex - // if (delta > 0) { - // navigateBack({ - // delta, - // }) - // invoke(callbackId, { - // errMsg: 'redirectTo:ok', - // }) - // return - // } - // } - // } - const lastPage = getCurrentPage(); - lastPage && removePage(lastPage); - return new Promise((resolve) => { - showWebview(registerPage({ - url, - path, - query, - openType: 'redirectTo', - }), 'none', 0, () => { - if (lastPage) { - const webview = lastPage - .$getAppWebview(); - if (webview.__preload__) { - removePreloadWebview(webview); - } - webview.close('none'); - } - resolve(undefined); - }); - setStatusBarStyle(); - }); - } +class RewardedVideoAd extends AdBase { + constructor(options) { + super(plus.ad.createRewardedVideoAd(options), options); + this._loadAd(); + } +} +const createRewardedVideoAd = (defineSyncApi(API_CREATE_REWARDED_VIDEO_AD, (options) => { + return new RewardedVideoAd(options); +}, CreateRewardedVideoAdProtocol, CreateRewardedVideoAdOptions)); + +class FullScreenVideoAd extends AdBase { + constructor(options) { + super(plus.ad.createFullScreenVideoAd(options), options); + this.preload = false; + } +} +const createFullScreenVideoAd = (defineSyncApi(API_CREATE_FULL_SCREEN_VIDEO_AD, (options) => { + return new FullScreenVideoAd(options); +}, CreateFullScreenVideoAdProtocol, CreateFullScreenVideoAdOptions)); + +class InterstitialAd extends AdBase { + constructor(options) { + super(plus.ad.createInterstitialAd(options), options); + this.preload = false; + this._loadAd(); + } +} +const createInterstitialAd = (defineSyncApi(API_CREATE_INTERSTITIAL_AD, (options) => { + return new InterstitialAd(options); +}, CreateInterstitialAdProtocol, CreateInterstitialAdOptions)); + +const sdkCache = {}; +const sdkQueue = {}; +function initSDK(options) { + const provider = options.provider; + if (!sdkCache[provider]) { + sdkCache[provider] = {}; + } + if (typeof sdkCache[provider].plugin === 'object') { + options.success(sdkCache[provider].plugin); + return; + } + if (!sdkQueue[provider]) { + sdkQueue[provider] = []; + } + sdkQueue[provider].push(options); + if (sdkCache[provider].status === true) { + options.__plugin = sdkCache[provider].plugin; + return; + } + sdkCache[provider].status = true; + const plugin = requireNativePlugin(provider); + if (!plugin || !plugin.initSDK) { + sdkQueue[provider].forEach((item) => { + item.fail({ + code: -1, + message: 'provider [' + provider + '] invalid', + }); + }); + sdkQueue[provider].length = 0; + sdkCache[provider].status = false; + return; + } + // TODO + sdkCache[provider].plugin = plugin; + options.__plugin = plugin; + plugin.initSDK((res) => { + const isSuccess = res.code === 1 || res.code === '1'; + if (isSuccess) { + sdkCache[provider].plugin = plugin; + } + else { + sdkCache[provider].status = false; + } + sdkQueue[provider].forEach((item) => { + if (isSuccess) { + item.success(item.__plugin); + } + else { + item.fail(res); + } + }); + sdkQueue[provider].length = 0; + }); +} +class InteractiveAd extends AdEventHandler { + constructor(options) { + super(); + this._adpid = ''; + this._provider = ''; + this._userData = null; + this._isLoaded = false; + this._isLoading = false; + this._loadPromiseResolve = null; + this._loadPromiseReject = null; + this._showPromiseResolve = null; + this._showPromiseReject = null; + this._adInstance = null; + this._adError = ''; + this._adpid = options.adpid; + this._provider = options.provider; + this._userData = options.userData; + setTimeout(() => { + this._init(); + }); + } + _init() { + this._adError = ''; + initSDK({ + provider: this._provider, + success: (res) => { + this._adInstance = res; + if (this._userData) { + this.bindUserData(this._userData); + } + this._loadAd(); + }, + fail: (err) => { + this._adError = err; + if (this._loadPromiseReject != null) { + this._loadPromiseReject(this._createError(err)); + this._loadPromiseReject = null; + } + this._dispatchEvent(EventType.error, err); + }, + }); + } + getProvider() { + return this._provider; + } + load() { + return new Promise((resolve, reject) => { + this._loadPromiseResolve = resolve; + this._loadPromiseReject = reject; + if (this._isLoading) { + return; + } + if (this._adError) { + this._init(); + return; + } + if (this._isLoaded) { + resolve(''); + } + else { + this._loadAd(); + } + }); + } + show() { + return new Promise((resolve, reject) => { + this._showPromiseResolve = resolve; + this._showPromiseReject = reject; + if (this._isLoading) { + return; + } + if (this._adError) { + this._init(); + return; + } + if (this._isLoaded) { + this._showAd(); + resolve(''); + } + else { + this._loadAd(); + } + }); + } + reportExposure() { + if (this._adInstance !== null) { + this._adInstance.reportExposure(); + } + } + bindUserData(data) { + if (this._adInstance !== null) { + this._adInstance.bindUserData(data); + } + } + destroy() { + if (this._adInstance !== null && this._adInstance.destroy) { + this._adInstance.destroy({ + adpid: this._adpid, + }); + } + } + _loadAd() { + if (this._adInstance !== null) { + if (this._isLoading === true) { + return; + } + this._isLoading = true; + this._adInstance.loadData({ + adpid: this._adpid, + }, (res) => { + this._isLoaded = true; + this._isLoading = false; + if (this._loadPromiseResolve != null) { + this._loadPromiseResolve(); + this._loadPromiseResolve = null; + } + if (this._showPromiseResolve != null) { + this._showPromiseResolve(); + this._showPromiseResolve = null; + this._showAd(); + } + this._dispatchEvent(EventType.load, res); + }, (err) => { + this._isLoading = false; + if (this._showPromiseReject != null) { + this._showPromiseReject(this._createError(err)); + this._showPromiseReject = null; + } + this._dispatchEvent(EventType.error, err); + }); + } + } + _showAd() { + if (this._adInstance !== null && this._isLoaded === true) { + this._adInstance.show({ + adpid: this._adpid, + }, () => { + this._isLoaded = false; + }, (err) => { + this._isLoaded = false; + if (this._showPromiseReject != null) { + this._showPromiseReject(this._createError(err)); + this._showPromiseReject = null; + } + this._dispatchEvent(EventType.error, err); + }); + } + } + _createError(err) { + return new Error(JSON.stringify(err)); + } +} +const createInteractiveAd = (defineSyncApi(API_CREATE_INTERACTIVE_AD, (options) => { + return new InteractiveAd(options); +}, CreateInteractiveAdProtocol, CreateInteractiveAdOptions)); + +const navigateBack = defineAsyncApi(API_NAVIGATE_BACK, (args, { resolve, reject }) => { + const page = getCurrentPage(); + if (!page) { + return reject(`getCurrentPages is empty`); + } + if (invokeHook(page, ON_BACK_PRESS, { + from: args.from, + })) { + return resolve(); + } + uni.hideToast(); + uni.hideLoading(); + if (page.$page.meta.isQuit) { + quit(); + } + else if (isDirectPage(page)) { + reLaunchEntryPage(); + } + else { + const { delta, animationType, animationDuration } = args; + back(delta, animationType, animationDuration); + } + return resolve(); +}, NavigateBackProtocol, NavigateBackOptions); +let firstBackTime = 0; +function quit() { + initI18nAppMsgsOnce(); + if (!firstBackTime) { + firstBackTime = Date.now(); + plus.nativeUI.toast(useI18n().t('uni.app.quit')); + setTimeout(() => { + firstBackTime = 0; + }, 2000); + } + else if (Date.now() - firstBackTime < 2000) { + plus.runtime.quit(); + } +} +function back(delta, animationType, animationDuration) { + const pages = getCurrentPages(); + const len = pages.length; + const currentPage = pages[len - 1]; + if (delta > 1) { + // 中间页隐藏 + pages + .slice(len - delta, len - 1) + .reverse() + .forEach((deltaPage) => { + closeWebview(plus.webview.getWebviewById(deltaPage.$page.id + ''), 'none', 0); + }); + } + const backPage = function (webview) { + if (animationType) { + closeWebview(webview, animationType, animationDuration || ANI_DURATION); + } + else { + if (currentPage.$page.openType === 'redirectTo') { + // 如果是 redirectTo 跳转的,需要指定 back 动画 + closeWebview(webview, ANI_CLOSE, ANI_DURATION); + } + else { + closeWebview(webview, 'auto'); + } + } + pages + .slice(len - delta, len) + .forEach((page) => removePage(page)); + setStatusBarStyle(); + // 前一个页面触发 onShow + invokeHook(ON_SHOW); + }; + const webview = plus.webview.getWebviewById(currentPage.$page.id + ''); + if (!currentPage.__uniapp_webview) { + return backPage(webview); + } + backWebview(webview, () => { + backPage(webview); + }); +} - const $reLaunch = ({ url }, { resolve, reject }) => { - const { path, query } = parseUrl(url); - navigate(path, () => { - _reLaunch({ - url, - path, - query, - }) - .then(resolve) - .catch(reject); - }); - }; - function _reLaunch({ url, path, query }) { - return new Promise((resolve) => { - // 获取目前所有页面 - const pages = getAllPages().slice(0); - const routeOptions = __uniRoutes.find((route) => route.path === path); - if (routeOptions.meta.isTabBar) { - tabBar$1.switchTab(path.slice(1)); - } - showWebview(registerPage({ - url, - path, - query, - openType: 'reLaunch', - }), 'none', 0, () => { - pages.forEach((page) => closePage(page, 'none')); - resolve(undefined); - }); - setStatusBarStyle(); - }); - } +const redirectTo = defineAsyncApi(API_REDIRECT_TO, ({ url }, { resolve, reject }) => { + const { path, query } = parseUrl(url); + navigate(path, () => { + _redirectTo({ + url, + path, + query, + }) + .then(resolve) + .catch(reject); + }); +}, RedirectToProtocol, RedirectToOptions); +function _redirectTo({ url, path, query, }) { + // TODO exists + // if (exists === 'back') { + // const existsPageIndex = findExistsPageIndex(url) + // if (existsPageIndex !== -1) { + // const delta = len - existsPageIndex + // if (delta > 0) { + // navigateBack({ + // delta, + // }) + // invoke(callbackId, { + // errMsg: 'redirectTo:ok', + // }) + // return + // } + // } + // } + const lastPage = getCurrentPage(); + lastPage && removePage(lastPage); + return new Promise((resolve) => { + showWebview(registerPage({ + url, + path, + query, + openType: 'redirectTo', + }), 'none', 0, () => { + if (lastPage) { + const webview = lastPage + .$getAppWebview(); + if (webview.__preload__) { + removePreloadWebview(webview); + } + webview.close('none'); + } + resolve(undefined); + }); + setStatusBarStyle(); + }); +} - const reLaunch = defineAsyncApi(API_RE_LAUNCH, $reLaunch, ReLaunchProtocol, ReLaunchOptions); - - const unPreloadPage = defineSyncApi(API_UN_PRELOAD_PAGE, ({ url }) => { - const webview = closePreloadWebview({ - url, - }); - if (webview) { - return { - id: webview.id, - url, - errMsg: 'unPreloadPage:ok', - }; - } - return { - url, - errMsg: 'unPreloadPage:fail not found', - }; - }, UnPreloadPageProtocol); - const preloadPage = defineAsyncApi(API_PRELOAD_PAGE, ({ url }, { resolve, reject }) => { - const urls = url.split('?'); - const path = urls[0]; - const query = parseQuery(urls[1] || ''); - const webview = preloadWebview({ - url, - path, - query, - }); - resolve({ - id: webview.id, - url, - errMsg: 'preloadPage:ok', - }); - }, PreloadPageProtocol); - - var uni$1 = { - __proto__: null, - sendHostEvent: sendHostEvent, - navigateToMiniProgram: navigateToMiniProgram, - onHostEventReceive: onHostEventReceive, - onNativeEventReceive: onNativeEventReceive, - navigateTo: navigateTo, - reLaunch: reLaunch, - switchTab: switchTab, - upx2px: upx2px, - addInterceptor: addInterceptor, - removeInterceptor: removeInterceptor, - interceptors: interceptors, - arrayBufferToBase64: arrayBufferToBase64, - base64ToArrayBuffer: base64ToArrayBuffer, - createIntersectionObserver: createIntersectionObserver, - createMediaQueryObserver: createMediaQueryObserver, - createSelectorQuery: createSelectorQuery, - createVideoContext: createVideoContext, - createMapContext: createMapContext, - createAnimation: createAnimation, - onWindowResize: onWindowResize, - offWindowResize: offWindowResize, - onTabBarMidButtonTap: onTabBarMidButtonTap, - createCanvasContext: createCanvasContext, - canvasGetImageData: canvasGetImageData, - canvasPutImageData: canvasPutImageData, - canvasToTempFilePath: canvasToTempFilePath, - getSelectedTextRange: getSelectedTextRange, - getLocale: getLocale, - setLocale: setLocale, - $on: $on, - $off: $off, - $once: $once, - $emit: $emit, - onAppLaunch: onAppLaunch, - onLocaleChange: onLocaleChange, - setPageMeta: setPageMeta, - getEnterOptionsSync: getEnterOptionsSync, - getLaunchOptionsSync: getLaunchOptionsSync, - getPushCid: getPushCid, - onPushMessage: onPushMessage, - offPushMessage: offPushMessage, - invokePushCallback: invokePushCallback, - setStorageSync: setStorageSync, - setStorage: setStorage, - getStorageSync: getStorageSync, - getStorage: getStorage, - removeStorageSync: removeStorageSync, - removeStorage: removeStorage, - clearStorageSync: clearStorageSync, - clearStorage: clearStorage, - getStorageInfoSync: getStorageInfoSync, - getStorageInfo: getStorageInfo, - getFileInfo: getFileInfo$1, - openDocument: openDocument, - saveFile: saveFile, - getSystemInfoSync: getSystemInfoSync, - getSystemInfo: getSystemInfo, - onCompassChange: onCompassChange, - offCompassChange: offCompassChange, - startCompass: startCompass, - stopCompass: stopCompass, - vibrateShort: vibrateShort, - vibrateLong: vibrateLong, - onAccelerometerChange: onAccelerometerChange, - offAccelerometerChange: offAccelerometerChange, - startAccelerometer: startAccelerometer, - stopAccelerometer: stopAccelerometer, - onBluetoothDeviceFound: onBluetoothDeviceFound, - onBluetoothAdapterStateChange: onBluetoothAdapterStateChange, - onBLEConnectionStateChange: onBLEConnectionStateChange, - onBLECharacteristicValueChange: onBLECharacteristicValueChange, - openBluetoothAdapter: openBluetoothAdapter, - closeBluetoothAdapter: closeBluetoothAdapter, - getBluetoothAdapterState: getBluetoothAdapterState, - startBluetoothDevicesDiscovery: startBluetoothDevicesDiscovery, - stopBluetoothDevicesDiscovery: stopBluetoothDevicesDiscovery, - getBluetoothDevices: getBluetoothDevices, - getConnectedBluetoothDevices: getConnectedBluetoothDevices, - createBLEConnection: createBLEConnection, - closeBLEConnection: closeBLEConnection, - getBLEDeviceServices: getBLEDeviceServices, - getBLEDeviceCharacteristics: getBLEDeviceCharacteristics, - notifyBLECharacteristicValueChange: notifyBLECharacteristicValueChange, - readBLECharacteristicValue: readBLECharacteristicValue, - writeBLECharacteristicValue: writeBLECharacteristicValue, - setBLEMTU: setBLEMTU, - getBLEDeviceRSSI: getBLEDeviceRSSI, - onBeaconUpdate: onBeaconUpdate, - onBeaconServiceChange: onBeaconServiceChange, - getBeacons: getBeacons, - startBeaconDiscovery: startBeaconDiscovery, - stopBeaconDiscovery: stopBeaconDiscovery, - makePhoneCall: makePhoneCall, - addPhoneContact: addPhoneContact, - getClipboardData: getClipboardData, - setClipboardData: setClipboardData, - onNetworkStatusChange: onNetworkStatusChange, - offNetworkStatusChange: offNetworkStatusChange, - getNetworkType: getNetworkType, - checkIsSupportSoterAuthentication: checkIsSupportSoterAuthentication, - checkIsSoterEnrolledInDevice: checkIsSoterEnrolledInDevice, - startSoterAuthentication: startSoterAuthentication, - scanCode: scanCode, - onThemeChange: onThemeChange, - getScreenBrightness: getScreenBrightness, - setScreenBrightness: setScreenBrightness, - setKeepScreenOn: setKeepScreenOn, - getImageInfo: getImageInfo, - getVideoInfo: getVideoInfo, - previewImage: previewImage, - closePreviewImage: closePreviewImage, - getRecorderManager: getRecorderManager, - saveVideoToPhotosAlbum: saveVideoToPhotosAlbum, - saveImageToPhotosAlbum: saveImageToPhotosAlbum, - compressImage: compressImage, - compressVideo: compressVideo, - chooseImage: chooseImage, - chooseVideo: chooseVideo, - showKeyboard: showKeyboard, - hideKeyboard: hideKeyboard, - onKeyboardHeightChange: onKeyboardHeightChange, - offKeyboardHeightChange: offKeyboardHeightChange, - downloadFile: downloadFile, - request: request, - configMTLS: configMTLS, - connectSocket: connectSocket, - sendSocketMessage: sendSocketMessage, - closeSocket: closeSocket, - onSocketOpen: onSocketOpen, - onSocketError: onSocketError, - onSocketMessage: onSocketMessage, - onSocketClose: onSocketClose, - uploadFile: uploadFile, - createInnerAudioContext: createInnerAudioContext, - getBackgroundAudioManager: getBackgroundAudioManager, - createLivePusherContext: createLivePusherContext, - getLocation: getLocation, - chooseLocation: chooseLocation, - openLocation: openLocation, - showModal: showModal, - showActionSheet: showActionSheet, - showLoading: showLoading, - showToast: showToast, - hideToast: hideToast, - hideLoading: hideLoading, - startPullDownRefresh: startPullDownRefresh, - stopPullDownRefresh: stopPullDownRefresh, - loadFontFace: loadFontFace, - pageScrollTo: pageScrollTo, - setNavigationBarTitle: setNavigationBarTitle, - showNavigationBarLoading: showNavigationBarLoading, - hideNavigationBarLoading: hideNavigationBarLoading, - setNavigationBarColor: setNavigationBarColor, - setTabBarBadge: setTabBarBadge, - setTabBarItem: setTabBarItem, - setTabBarStyle: setTabBarStyle, - hideTabBar: hideTabBar, - showTabBar: showTabBar, - showTabBarRedDot: showTabBarRedDot, - removeTabBarBadge: removeTabBarBadge, - hideTabBarRedDot: hideTabBarRedDot, - getSubNVueById: getSubNVueById, - restoreGlobal: restoreGlobal, - getProvider: getProvider, - login: login, - getUserInfo: getUserInfo, - getUserProfile: getUserProfile, - preLogin: preLogin, - closeAuthView: closeAuthView, - getCheckBoxState: getCheckBoxState, - getUniverifyManager: getUniverifyManager, - registerRuntime: registerRuntime, - share: share, - shareWithSystem: shareWithSystem, - requestPayment: requestPayment, - requireNativePlugin: requireNativePlugin, - sendNativeEvent: sendNativeEvent, - __vuePlugin: index$1, - createRewardedVideoAd: createRewardedVideoAd, - createFullScreenVideoAd: createFullScreenVideoAd, - createInterstitialAd: createInterstitialAd, - createInteractiveAd: createInteractiveAd, - navigateBack: navigateBack, - redirectTo: redirectTo, - unPreloadPage: unPreloadPage, - preloadPage: preloadPage - }; - - const UniServiceJSBridge$1 = /*#__PURE__*/ shared.extend(ServiceJSBridge, { - publishHandler, - }); - function publishHandler(event, args, pageIds) { - args = JSON.stringify(args); - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('publishHandler', event, args, pageIds)); - } - if (!shared.isArray(pageIds)) { - pageIds = [pageIds]; - } - const evalJSCode = `typeof UniViewJSBridge !== 'undefined' && UniViewJSBridge.subscribeHandler("${event}",${args},__PAGE_ID__)`; - if ((process.env.NODE_ENV !== 'production')) { - console.log(formatLog('publishHandler', 'size', evalJSCode.length)); - } - pageIds.forEach((id) => { - const idStr = String(id); - const webview = plus.webview.getWebviewById(idStr); - webview && webview.evalJS(evalJSCode.replace('__PAGE_ID__', idStr)); - }); - } +const $reLaunch = ({ url }, { resolve, reject }) => { + const { path, query } = parseUrl(url); + navigate(path, () => { + _reLaunch({ + url, + path, + query, + }) + .then(resolve) + .catch(reject); + }); +}; +function _reLaunch({ url, path, query }) { + return new Promise((resolve) => { + // 获取目前所有页面 + const pages = getAllPages().slice(0); + const routeOptions = __uniRoutes.find((route) => route.path === path); + if (routeOptions.meta.isTabBar) { + tabBar$1.switchTab(path.slice(1)); + } + showWebview(registerPage({ + url, + path, + query, + openType: 'reLaunch', + }), 'none', 0, () => { + pages.forEach((page) => closePage(page, 'none')); + resolve(undefined); + }); + setStatusBarStyle(); + }); +} - var index = { - uni: uni$1, - getApp: getApp$1, - getCurrentPages: getCurrentPages$1, - __definePage: definePage, - __registerApp: registerApp, - __registerPage: registerPage, - UniServiceJSBridge: UniServiceJSBridge$1, - }; - - return index; - -})(VueShared, Vue); -const uni = serviceContext.uni; -const getApp = serviceContext.getApp; -const getCurrentPages = serviceContext.getCurrentPages; -const UniServiceJSBridge = serviceContext.UniServiceJSBridge; -return serviceContext; +const reLaunch = defineAsyncApi(API_RE_LAUNCH, $reLaunch, ReLaunchProtocol, ReLaunchOptions); + +const unPreloadPage = defineSyncApi(API_UN_PRELOAD_PAGE, ({ url }) => { + const webview = closePreloadWebview({ + url, + }); + if (webview) { + return { + id: webview.id, + url, + errMsg: 'unPreloadPage:ok', + }; + } + return { + url, + errMsg: 'unPreloadPage:fail not found', + }; +}, UnPreloadPageProtocol); +const preloadPage = defineAsyncApi(API_PRELOAD_PAGE, ({ url }, { resolve, reject }) => { + const urls = url.split('?'); + const path = urls[0]; + const query = parseQuery(urls[1] || ''); + const webview = preloadWebview({ + url, + path, + query, + }); + resolve({ + id: webview.id, + url, + errMsg: 'preloadPage:ok', + }); +}, PreloadPageProtocol); + +var uni$1 = { + __proto__: null, + sendHostEvent: sendHostEvent, + navigateToMiniProgram: navigateToMiniProgram, + onHostEventReceive: onHostEventReceive, + onNativeEventReceive: onNativeEventReceive, + navigateTo: navigateTo, + reLaunch: reLaunch, + switchTab: switchTab, + upx2px: upx2px, + addInterceptor: addInterceptor, + removeInterceptor: removeInterceptor, + interceptors: interceptors, + arrayBufferToBase64: arrayBufferToBase64, + base64ToArrayBuffer: base64ToArrayBuffer, + createIntersectionObserver: createIntersectionObserver, + createMediaQueryObserver: createMediaQueryObserver, + createSelectorQuery: createSelectorQuery, + createVideoContext: createVideoContext, + createMapContext: createMapContext, + createAnimation: createAnimation, + onWindowResize: onWindowResize, + offWindowResize: offWindowResize, + onTabBarMidButtonTap: onTabBarMidButtonTap, + createCanvasContext: createCanvasContext, + canvasGetImageData: canvasGetImageData, + canvasPutImageData: canvasPutImageData, + canvasToTempFilePath: canvasToTempFilePath, + getSelectedTextRange: getSelectedTextRange, + getLocale: getLocale, + setLocale: setLocale, + $on: $on, + $off: $off, + $once: $once, + $emit: $emit, + onAppLaunch: onAppLaunch, + onLocaleChange: onLocaleChange, + setPageMeta: setPageMeta, + getEnterOptionsSync: getEnterOptionsSync, + getLaunchOptionsSync: getLaunchOptionsSync, + getPushCid: getPushCid, + onPushMessage: onPushMessage, + offPushMessage: offPushMessage, + invokePushCallback: invokePushCallback, + setStorageSync: setStorageSync, + setStorage: setStorage, + getStorageSync: getStorageSync, + getStorage: getStorage, + removeStorageSync: removeStorageSync, + removeStorage: removeStorage, + clearStorageSync: clearStorageSync, + clearStorage: clearStorage, + getStorageInfoSync: getStorageInfoSync, + getStorageInfo: getStorageInfo, + getFileInfo: getFileInfo$1, + openDocument: openDocument, + saveFile: saveFile, + getSystemInfoSync: getSystemInfoSync, + getSystemInfo: getSystemInfo, + onCompassChange: onCompassChange, + offCompassChange: offCompassChange, + startCompass: startCompass, + stopCompass: stopCompass, + vibrateShort: vibrateShort, + vibrateLong: vibrateLong, + onAccelerometerChange: onAccelerometerChange, + offAccelerometerChange: offAccelerometerChange, + startAccelerometer: startAccelerometer, + stopAccelerometer: stopAccelerometer, + onBluetoothDeviceFound: onBluetoothDeviceFound, + onBluetoothAdapterStateChange: onBluetoothAdapterStateChange, + onBLEConnectionStateChange: onBLEConnectionStateChange, + onBLECharacteristicValueChange: onBLECharacteristicValueChange, + openBluetoothAdapter: openBluetoothAdapter, + closeBluetoothAdapter: closeBluetoothAdapter, + getBluetoothAdapterState: getBluetoothAdapterState, + startBluetoothDevicesDiscovery: startBluetoothDevicesDiscovery, + stopBluetoothDevicesDiscovery: stopBluetoothDevicesDiscovery, + getBluetoothDevices: getBluetoothDevices, + getConnectedBluetoothDevices: getConnectedBluetoothDevices, + createBLEConnection: createBLEConnection, + closeBLEConnection: closeBLEConnection, + getBLEDeviceServices: getBLEDeviceServices, + getBLEDeviceCharacteristics: getBLEDeviceCharacteristics, + notifyBLECharacteristicValueChange: notifyBLECharacteristicValueChange, + readBLECharacteristicValue: readBLECharacteristicValue, + writeBLECharacteristicValue: writeBLECharacteristicValue, + setBLEMTU: setBLEMTU, + getBLEDeviceRSSI: getBLEDeviceRSSI, + onBeaconUpdate: onBeaconUpdate, + onBeaconServiceChange: onBeaconServiceChange, + getBeacons: getBeacons, + startBeaconDiscovery: startBeaconDiscovery, + stopBeaconDiscovery: stopBeaconDiscovery, + makePhoneCall: makePhoneCall, + addPhoneContact: addPhoneContact, + getClipboardData: getClipboardData, + setClipboardData: setClipboardData, + onNetworkStatusChange: onNetworkStatusChange, + offNetworkStatusChange: offNetworkStatusChange, + getNetworkType: getNetworkType, + checkIsSupportSoterAuthentication: checkIsSupportSoterAuthentication, + checkIsSoterEnrolledInDevice: checkIsSoterEnrolledInDevice, + startSoterAuthentication: startSoterAuthentication, + scanCode: scanCode, + onThemeChange: onThemeChange, + getScreenBrightness: getScreenBrightness, + setScreenBrightness: setScreenBrightness, + setKeepScreenOn: setKeepScreenOn, + getImageInfo: getImageInfo, + getVideoInfo: getVideoInfo, + previewImage: previewImage, + closePreviewImage: closePreviewImage, + getRecorderManager: getRecorderManager, + saveVideoToPhotosAlbum: saveVideoToPhotosAlbum, + saveImageToPhotosAlbum: saveImageToPhotosAlbum, + compressImage: compressImage, + compressVideo: compressVideo, + chooseImage: chooseImage, + chooseVideo: chooseVideo, + showKeyboard: showKeyboard, + hideKeyboard: hideKeyboard, + onKeyboardHeightChange: onKeyboardHeightChange, + offKeyboardHeightChange: offKeyboardHeightChange, + downloadFile: downloadFile, + request: request, + configMTLS: configMTLS, + connectSocket: connectSocket, + sendSocketMessage: sendSocketMessage, + closeSocket: closeSocket, + onSocketOpen: onSocketOpen, + onSocketError: onSocketError, + onSocketMessage: onSocketMessage, + onSocketClose: onSocketClose, + uploadFile: uploadFile, + createInnerAudioContext: createInnerAudioContext, + getBackgroundAudioManager: getBackgroundAudioManager, + createLivePusherContext: createLivePusherContext, + getLocation: getLocation, + chooseLocation: chooseLocation, + openLocation: openLocation, + showModal: showModal, + showActionSheet: showActionSheet, + showLoading: showLoading, + showToast: showToast, + hideToast: hideToast, + hideLoading: hideLoading, + startPullDownRefresh: startPullDownRefresh, + stopPullDownRefresh: stopPullDownRefresh, + loadFontFace: loadFontFace, + pageScrollTo: pageScrollTo, + setNavigationBarTitle: setNavigationBarTitle, + showNavigationBarLoading: showNavigationBarLoading, + hideNavigationBarLoading: hideNavigationBarLoading, + setNavigationBarColor: setNavigationBarColor, + setTabBarBadge: setTabBarBadge, + setTabBarItem: setTabBarItem, + setTabBarStyle: setTabBarStyle, + hideTabBar: hideTabBar, + showTabBar: showTabBar, + showTabBarRedDot: showTabBarRedDot, + removeTabBarBadge: removeTabBarBadge, + hideTabBarRedDot: hideTabBarRedDot, + getSubNVueById: getSubNVueById, + restoreGlobal: restoreGlobal, + getProvider: getProvider, + login: login, + getUserInfo: getUserInfo, + getUserProfile: getUserProfile, + preLogin: preLogin, + closeAuthView: closeAuthView, + getCheckBoxState: getCheckBoxState, + getUniverifyManager: getUniverifyManager, + registerRuntime: registerRuntime, + share: share, + shareWithSystem: shareWithSystem, + requestPayment: requestPayment, + requireNativePlugin: requireNativePlugin, + sendNativeEvent: sendNativeEvent, + __vuePlugin: index$1, + createRewardedVideoAd: createRewardedVideoAd, + createFullScreenVideoAd: createFullScreenVideoAd, + createInterstitialAd: createInterstitialAd, + createInteractiveAd: createInteractiveAd, + navigateBack: navigateBack, + redirectTo: redirectTo, + unPreloadPage: unPreloadPage, + preloadPage: preloadPage +}; + +const UniServiceJSBridge$1 = /*#__PURE__*/ extend(ServiceJSBridge, { + publishHandler, +}); +function publishHandler(event, args, pageIds) { + args = JSON.stringify(args); + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('publishHandler', event, args, pageIds)); + } + if (!isArray$1(pageIds)) { + pageIds = [pageIds]; + } + const evalJSCode = `typeof UniViewJSBridge !== 'undefined' && UniViewJSBridge.subscribeHandler("${event}",${args},__PAGE_ID__)`; + if ((process.env.NODE_ENV !== 'production')) { + console.log(formatLog('publishHandler', 'size', evalJSCode.length)); + } + pageIds.forEach((id) => { + const idStr = String(id); + const webview = plus.webview.getWebviewById(idStr); + webview && webview.evalJS(evalJSCode.replace('__PAGE_ID__', idStr)); + }); } + +var index = { + uni: uni$1, + getApp: getApp$1, + getCurrentPages: getCurrentPages$1, + __definePage: definePage, + __registerApp: registerApp, + __registerPage: registerPage, + UniServiceJSBridge: UniServiceJSBridge$1, +}; + +export { index as default }; diff --git a/packages/uni-app-plus/dist/uni.vue.js b/packages/uni-app-plus/dist/uni.vue.js new file mode 100644 index 0000000000000000000000000000000000000000..b67c9fa85d059ed9535b34223a2881539d11c895 --- /dev/null +++ b/packages/uni-app-plus/dist/uni.vue.js @@ -0,0 +1,269 @@ +import { isString, isArray, isFunction } from '@vue/shared'; +import { invokeArrayFns, ON_LOAD, LINEFEED, ON_SHOW, RENDERJS_MODULES, WXS_PROTOCOL, formatLog, WXS_MODULES, UniLifecycleHooks, ON_ERROR } from '@dcloudio/uni-shared'; +import { nextTick, injectHook } from 'vue'; + +function getCurrentPage() { + const pages = getCurrentPages(); + const len = pages.length; + if (len) { + return pages[len - 1]; + } +} +function getCurrentPageVm() { + const page = getCurrentPage(); + if (page) { + return page.$vm; + } +} + +function invokeHook(vm, name, args) { + if (isString(vm)) { + args = name; + name = vm; + vm = getCurrentPageVm(); + } + else if (typeof vm === 'number') { + const page = getCurrentPages().find((page) => page.$page.id === vm); + if (page) { + vm = page.$vm; + } + else { + vm = getCurrentPageVm(); + } + } + if (!vm) { + return; + } + // 兼容 nvue + { + if (vm.__call_hook) { + return vm.__call_hook(name, args); + } + } + const hooks = vm.$[name]; + return hooks && invokeArrayFns(hooks, args); +} + +function injectLifecycleHook(name, hook, publicThis, instance) { + if (isFunction(hook)) { + injectHook(name, hook.bind(publicThis), instance); + } +} +function initHooks(options, instance, publicThis) { + const mpType = options.mpType || publicThis.$mpType; + // 为了组件也可以监听部分生命周期,故不再判断mpType,统一添加on开头的生命周期 + Object.keys(options).forEach((name) => { + if (name.indexOf('on') === 0) { + const hooks = options[name]; + if (isArray(hooks)) { + hooks.forEach((hook) => injectLifecycleHook(name, hook, publicThis, instance)); + } + else { + injectLifecycleHook(name, hooks, publicThis, instance); + } + } + }); + if (mpType === 'page') { + instance.__isVisible = true; + try { + invokeHook(publicThis, ON_LOAD, instance.attrs.__pageQuery); + delete instance.attrs.__pageQuery; + } + catch (e) { + console.error(e.message + LINEFEED + e.stack); + } + nextTick(() => { + // 延迟onShow,保证组件的onShow也可以监听到 + invokeHook(publicThis, ON_SHOW); + }); + } +} + +function initRenderjs(options, instance) { + initModules(instance, options.$renderjs, options['$' + RENDERJS_MODULES]); +} +function initModules(instance, modules, moduleIds = {}) { + if (!isArray(modules)) { + return; + } + const ownerId = instance.uid; + // 在vue的定制内核中,通过$wxsModules来判断事件函数源码中是否包含该模块调用 + // !$wxsModules.find(module => invokerSourceCode.indexOf('.' + module + '.') > -1) + const $wxsModules = (instance.$wxsModules || + (instance.$wxsModules = [])); + const ctx = instance.ctx; + modules.forEach((module) => { + if (moduleIds[module]) { + ctx[module] = proxyModule(ownerId, moduleIds[module], module); + $wxsModules.push(module); + } + else { + if ((process.env.NODE_ENV !== 'production')) { + console.error(formatLog('initModules', modules, moduleIds)); + } + } + }); +} +function proxyModule(ownerId, moduleId, module) { + const target = {}; + return new Proxy(target, { + get(_, p) { + return (target[p] || + (target[p] = createModuleFunction(ownerId, moduleId, module, p))); + }, + }); +} +function createModuleFunction(ownerId, moduleId, module, name) { + const target = () => { }; + const toJSON = () => WXS_PROTOCOL + JSON.stringify([ownerId, moduleId, module + '.' + name]); + return new Proxy(target, { + get(_, p) { + if (p === 'toJSON') { + return toJSON; + } + return (target[p] || + (target[p] = createModuleFunction(ownerId, moduleId, module + '.' + name, p))); + }, + apply(_target, _thisArg, args) { + return (WXS_PROTOCOL + + JSON.stringify([ownerId, moduleId, module + '.' + name, [...args]])); + }, + }); +} + +function initWxs(options, instance) { + initModules(instance, options.$wxs, options['$' + WXS_MODULES]); +} + +function applyOptions(options, instance, publicThis) { + { + initWxs(options, instance); + initRenderjs(options, instance); + } + initHooks(options, instance, publicThis); +} + +function set(target, key, val) { + return (target[key] = val); +} + +function errorHandler(err, instance, info) { + if (!instance) { + throw err; + } + const app = getApp(); + if (!app || !app.$vm) { + throw err; + } + { + invokeHook(app.$vm, ON_ERROR, err); + } +} +function mergeAsArray(to, from) { + return to ? [...new Set([].concat(to, from))] : from; +} +function initOptionMergeStrategies(optionMergeStrategies) { + UniLifecycleHooks.forEach((name) => { + optionMergeStrategies[name] = mergeAsArray; + }); +} + +let realAtob; +const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; +if (typeof atob !== 'function') { + realAtob = function (str) { + str = String(str).replace(/[\t\n\f\r ]+/g, ''); + if (!b64re.test(str)) { + throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."); + } + // Adding the padding if missing, for semplicity + str += '=='.slice(2 - (str.length & 3)); + var bitmap; + var result = ''; + var r1; + var r2; + var i = 0; + for (; i < str.length;) { + bitmap = + (b64.indexOf(str.charAt(i++)) << 18) | + (b64.indexOf(str.charAt(i++)) << 12) | + ((r1 = b64.indexOf(str.charAt(i++))) << 6) | + (r2 = b64.indexOf(str.charAt(i++))); + result += + r1 === 64 + ? String.fromCharCode((bitmap >> 16) & 255) + : r2 === 64 + ? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255) + : String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255); + } + return result; + }; +} +else { + // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法 + realAtob = atob; +} +function b64DecodeUnicode(str) { + return decodeURIComponent(realAtob(str) + .split('') + .map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join('')); +} +function getCurrentUserInfo() { + const token = uni.getStorageSync('uni_id_token') || ''; + const tokenArr = token.split('.'); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0, + }; + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } + catch (error) { + throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message); + } + userInfo.tokenExpired = userInfo.exp * 1000; + delete userInfo.exp; + delete userInfo.iat; + return userInfo; +} +function uniIdMixin(globalProperties) { + globalProperties.uniIDHasRole = function (roleId) { + const { role } = getCurrentUserInfo(); + return role.indexOf(roleId) > -1; + }; + globalProperties.uniIDHasPermission = function (permissionId) { + const { permission } = getCurrentUserInfo(); + return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1; + }; + globalProperties.uniIDTokenValid = function () { + const { tokenExpired } = getCurrentUserInfo(); + return tokenExpired > Date.now(); + }; +} + +function initApp(app) { + const appConfig = app._context.config; + if (isFunction(app._component.onError)) { + appConfig.errorHandler = errorHandler; + } + initOptionMergeStrategies(appConfig.optionMergeStrategies); + const globalProperties = appConfig.globalProperties; + { + uniIdMixin(globalProperties); + } + { + globalProperties.$set = set; + globalProperties.$applyOptions = applyOptions; + } +} + +export { initApp }; diff --git a/packages/uni-app-plus/src/service/vue.ts b/packages/uni-app-plus/src/service/vue.ts new file mode 100644 index 0000000000000000000000000000000000000000..6563bee9ab71b4a12391a905f29130a17fe4c232 --- /dev/null +++ b/packages/uni-app-plus/src/service/vue.ts @@ -0,0 +1 @@ +export { initApp } from '@dcloudio/uni-vue' diff --git a/packages/uni-app-plus/vite.config.ts b/packages/uni-app-plus/vite.config.ts index 9f358262ba59aa625dcfdfa2edefae3769fa3d85..b10838b0e6dca54ca6c55ef694163a4b038747ce 100644 --- a/packages/uni-app-plus/vite.config.ts +++ b/packages/uni-app-plus/vite.config.ts @@ -57,7 +57,6 @@ export default defineConfig({ define: { global: 'window', __DEV__: false, - __NVUE__: false, __TEST__: false, __PLATFORM__: JSON.stringify('app'), __NODE_JS__: false, diff --git a/packages/uni-app-vue/build.json b/packages/uni-app-vue/build.json index 37fef3a5185c6780101a12edf9efd60f0ff4fa96..16b1b95c8f0a31697aed32434e8c1f2c416fe9b6 100644 --- a/packages/uni-app-vue/build.json +++ b/packages/uni-app-vue/build.json @@ -4,21 +4,14 @@ "src/service/index.ts": ["dist/service.runtime.esm.dev.js"] }, "output": { - "freeze": false, - "banner": "function vueFactory (exports) {\n", - "footer": "}", - "format": "iife", - "globals": { - "@vue/shared": "exports.VueShared", - "@vue/reactivity": "exports.VueReactivity" - } + "freeze": false }, "replacements": { "__VUE_OPTIONS_API__": "true", "__VUE_PROD_DEVTOOLS__": "false", "process.env.NODE_ENV": "\"development\"" }, - "external": ["@vue/shared", "@vue/reactivity"], + "external": ["@vue/shared", "@vue/reactivity", "@dcloudio/uni-shared"], "babel": true }, { @@ -26,21 +19,14 @@ "src/service/index.ts": ["dist/service.runtime.esm.prod.js"] }, "output": { - "freeze": false, - "banner": "function vueFactory (exports) {\n", - "footer": "}", - "format": "iife", - "globals": { - "@vue/shared": "exports.VueShared", - "@vue/reactivity": "exports.VueReactivity" - } + "freeze": false }, "replacements": { "__VUE_OPTIONS_API__": "true", "__VUE_PROD_DEVTOOLS__": "false", "process.env.NODE_ENV": "\"production\"" }, - "external": ["@vue/shared", "@vue/reactivity"], + "external": ["@vue/shared", "@vue/reactivity", "@dcloudio/uni-shared"], "babel": true }, { @@ -58,21 +44,14 @@ "src/nvue/index.ts": ["dist/nvue.runtime.esm.dev.js"] }, "output": { - "freeze": false, - "banner": "function nvueFactory (exports, document) {\n", - "footer": "}", - "format": "iife", - "globals": { - "@vue/shared": "exports.VueShared", - "@vue/reactivity": "exports.VueReactivity" - } + "freeze": false }, "replacements": { "__VUE_OPTIONS_API__": "true", "__VUE_PROD_DEVTOOLS__": "false", "process.env.NODE_ENV": "\"development\"" }, - "external": ["@vue/shared", "@vue/reactivity"], + "external": ["@vue/shared", "@vue/reactivity", "@dcloudio/uni-shared"], "babel": true }, { @@ -80,21 +59,14 @@ "src/nvue/index.ts": ["dist/nvue.runtime.esm.prod.js"] }, "output": { - "freeze": false, - "banner": "function nvueFactory (exports, document) {\n", - "footer": "}", - "format": "iife", - "globals": { - "@vue/shared": "exports.VueShared", - "@vue/reactivity": "exports.VueReactivity" - } + "freeze": false }, "replacements": { "__VUE_OPTIONS_API__": "true", "__VUE_PROD_DEVTOOLS__": "false", "process.env.NODE_ENV": "\"production\"" }, - "external": ["@vue/shared", "@vue/reactivity"], + "external": ["@vue/shared", "@vue/reactivity", "@dcloudio/uni-shared"], "babel": true } ] diff --git a/packages/uni-app-vue/dist/nvue.runtime.esm.dev.js b/packages/uni-app-vue/dist/nvue.runtime.esm.dev.js index 6b07822707d69a547c3243d8e712411d4fc12743..a7865412bdd4c4d0a6f23011eeb3926b0f886d10 100644 --- a/packages/uni-app-vue/dist/nvue.runtime.esm.dev.js +++ b/packages/uni-app-vue/dist/nvue.runtime.esm.dev.js @@ -1,9859 +1,9855 @@ -"use strict"; +import { isString, isFunction, isPromise, getGlobalThis, extend, EMPTY_OBJ, isArray, NOOP, remove, isObject, toHandlerKey, camelize, capitalize, normalizeClass, normalizeStyle, isOn, NO, hasOwn, toNumber, hasChanged, isSet, isMap, isPlainObject, invokeArrayFns, isBuiltInDirective, isReservedProp, EMPTY_ARR, makeMap, isModelListener, hyphenate, def, toRawType, parseStringStyle, isGloballyWhitelisted, normalizeProps, toDisplayString } from '@vue/shared'; +import { pauseTracking, resetTracking, isRef, toRaw, isShallow as isShallow$1, isReactive, ReactiveEffect, ref, isProxy, shallowReadonly, proxyRefs, markRaw, computed as computed$1, EffectScope, track, isReadonly, reactive, shallowReactive, trigger, customRef, effect, effectScope, getCurrentScope, onScopeDispose, readonly, shallowRef, stop, toRef, toRefs, triggerRef, unref } from '@vue/reactivity'; +var stack = []; -function nvueFactory(exports, document) { - (function (shared, reactivity) { - 'use strict'; - - var stack = []; - - function pushWarningContext(vnode) { - stack.push(vnode); - } - - function popWarningContext() { - stack.pop(); - } - - function warn(msg) { - // avoid props formatting or warn handler tracking deps that might be mutated - // during patch, leading to infinite recursion. - reactivity.pauseTracking(); - var instance = stack.length ? stack[stack.length - 1].component : null; - var appWarnHandler = instance && instance.appContext.config.warnHandler; - var trace = getComponentTrace(); - - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - if (appWarnHandler) { - callWithErrorHandling(appWarnHandler, instance, 11 - /* APP_WARN_HANDLER */ - , [msg + args.join(''), instance && instance.proxy, trace.map(_ref => { - var { - vnode - } = _ref; - return "at <".concat(formatComponentName(instance, vnode.type), ">"); - }).join('\n'), trace]); - } else { - var warnArgs = ["[Vue warn]: ".concat(msg), ...args]; - /* istanbul ignore if */ +function pushWarningContext(vnode) { + stack.push(vnode); +} - if (trace.length && // avoid spamming console during tests - !false) { - warnArgs.push("\n", ...formatTrace(trace)); - } +function popWarningContext() { + stack.pop(); +} - console.warn(...warnArgs); - } +function warn(msg) { + // avoid props formatting or warn handler tracking deps that might be mutated + // during patch, leading to infinite recursion. + pauseTracking(); + var instance = stack.length ? stack[stack.length - 1].component : null; + var appWarnHandler = instance && instance.appContext.config.warnHandler; + var trace = getComponentTrace(); + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (appWarnHandler) { + callWithErrorHandling(appWarnHandler, instance, 11 + /* APP_WARN_HANDLER */ + , [msg + args.join(''), instance && instance.proxy, trace.map(_ref => { + var { + vnode + } = _ref; + return "at <".concat(formatComponentName(instance, vnode.type), ">"); + }).join('\n'), trace]); + } else { + var warnArgs = ["[Vue warn]: ".concat(msg), ...args]; + /* istanbul ignore if */ - reactivity.resetTracking(); + if (trace.length && // avoid spamming console during tests + !false) { + warnArgs.push("\n", ...formatTrace(trace)); } - function getComponentTrace() { - var 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. + console.warn(...warnArgs); + } + resetTracking(); +} - var normalizedStack = []; - - while (currentVNode) { - var last = normalizedStack[0]; +function getComponentTrace() { + var currentVNode = stack[stack.length - 1]; - if (last && last.vnode === currentVNode) { - last.recurseCount++; - } else { - normalizedStack.push({ - vnode: currentVNode, - recurseCount: 0 - }); - } + 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. - var parentInstance = currentVNode.component && currentVNode.component.parent; - currentVNode = parentInstance && parentInstance.vnode; - } - return normalizedStack; - } - /* istanbul ignore next */ + var normalizedStack = []; + while (currentVNode) { + var last = normalizedStack[0]; - function formatTrace(trace) { - var logs = []; - trace.forEach((entry, i) => { - logs.push(...(i === 0 ? [] : ["\n"]), ...formatTraceEntry(entry)); + if (last && last.vnode === currentVNode) { + last.recurseCount++; + } else { + normalizedStack.push({ + vnode: currentVNode, + recurseCount: 0 }); - return logs; } - function formatTraceEntry(_ref2) { - var { - vnode, - recurseCount - } = _ref2; - var postfix = recurseCount > 0 ? "... (".concat(recurseCount, " recursive calls)") : ""; - var isRoot = vnode.component ? vnode.component.parent == null : false; - var open = " at <".concat(formatComponentName(vnode.component, vnode.type, isRoot)); - var close = ">" + postfix; - return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close]; - } - /* istanbul ignore next */ - - - function formatProps(props) { - var res = []; - var 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 */ + var parentInstance = currentVNode.component && currentVNode.component.parent; + currentVNode = parentInstance && parentInstance.vnode; + } + return normalizedStack; +} +/* istanbul ignore next */ - function formatProp(key, value, raw) { - if (shared.isString(value)) { - value = JSON.stringify(value); - return raw ? value : ["".concat(key, "=").concat(value)]; - } else if (typeof value === 'number' || typeof value === 'boolean' || value == null) { - return raw ? value : ["".concat(key, "=").concat(value)]; - } else if (reactivity.isRef(value)) { - value = formatProp(key, reactivity.toRaw(value.value), true); - return raw ? value : ["".concat(key, "=Ref<"), value, ">"]; - } else if (shared.isFunction(value)) { - return ["".concat(key, "=fn").concat(value.name ? "<".concat(value.name, ">") : "")]; - } else { - value = reactivity.toRaw(value); - return raw ? value : ["".concat(key, "="), value]; - } - } - - var ErrorTypeStrings = { - ["sp" - /* SERVER_PREFETCH */ - ]: 'serverPrefetch hook', - ["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/core' - }; - function callWithErrorHandling(fn, instance, type, args) { - var res; +function formatTrace(trace) { + var logs = []; + trace.forEach((entry, i) => { + logs.push(...(i === 0 ? [] : ["\n"]), ...formatTraceEntry(entry)); + }); + return logs; +} - try { - res = args ? fn(...args) : fn(); - } catch (err) { - handleError(err, instance, type); - } +function formatTraceEntry(_ref2) { + var { + vnode, + recurseCount + } = _ref2; + var postfix = recurseCount > 0 ? "... (".concat(recurseCount, " recursive calls)") : ""; + var isRoot = vnode.component ? vnode.component.parent == null : false; + var open = " at <".concat(formatComponentName(vnode.component, vnode.type, isRoot)); + var close = ">" + postfix; + return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close]; +} +/* istanbul ignore next */ - return res; - } - function callWithAsyncErrorHandling(fn, instance, type, args) { - if (shared.isFunction(fn)) { - var res = callWithErrorHandling(fn, instance, type, args); +function formatProps(props) { + var res = []; + var keys = Object.keys(props); + keys.slice(0, 3).forEach(key => { + res.push(...formatProp(key, props[key])); + }); - if (res && shared.isPromise(res)) { - res.catch(err => { - handleError(err, instance, type); - }); - } + if (keys.length > 3) { + res.push(" ..."); + } - return res; - } + return res; +} +/* istanbul ignore next */ + + +function formatProp(key, value, raw) { + if (isString(value)) { + value = JSON.stringify(value); + return raw ? value : ["".concat(key, "=").concat(value)]; + } else if (typeof value === 'number' || typeof value === 'boolean' || value == null) { + return raw ? value : ["".concat(key, "=").concat(value)]; + } else if (isRef(value)) { + value = formatProp(key, toRaw(value.value), true); + return raw ? value : ["".concat(key, "=Ref<"), value, ">"]; + } else if (isFunction(value)) { + return ["".concat(key, "=fn").concat(value.name ? "<".concat(value.name, ">") : "")]; + } else { + value = toRaw(value); + return raw ? value : ["".concat(key, "="), value]; + } +} - var values = []; +var ErrorTypeStrings = { + ["sp" + /* SERVER_PREFETCH */ + ]: 'serverPrefetch hook', + ["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/core' +}; + +function callWithErrorHandling(fn, instance, type, args) { + var res; + + try { + res = args ? fn(...args) : fn(); + } catch (err) { + handleError(err, instance, type); + } + + return res; +} - for (var i = 0; i < fn.length; i++) { - values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); - } +function callWithAsyncErrorHandling(fn, instance, type, args) { + if (isFunction(fn)) { + var res = callWithErrorHandling(fn, instance, type, args); - return values; + if (res && isPromise(res)) { + res.catch(err => { + handleError(err, instance, type); + }); } - function handleError(err, instance, type) { - var throwInDev = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; - var contextVNode = instance ? instance.vnode : null; + return res; + } - if (instance) { - var cur = instance.parent; // the exposed instance is the render proxy to keep it consistent with 2.x + var values = []; - var exposedInstance = instance.proxy; // in production the hook receives only the error code - // fixed by xxxxxx + for (var i = 0; i < fn.length; i++) { + values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); + } - var errorInfo = ErrorTypeStrings[type] || type; + return values; +} - while (cur) { - var errorCapturedHooks = cur.ec; +function handleError(err, instance, type) { + var throwInDev = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var contextVNode = instance ? instance.vnode : null; - if (errorCapturedHooks) { - for (var i = 0; i < errorCapturedHooks.length; i++) { - if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { - return; - } - } - } + if (instance) { + var cur = instance.parent; // the exposed instance is the render proxy to keep it consistent with 2.x - cur = cur.parent; - } // app-level handling + var exposedInstance = instance.proxy; // in production the hook receives only the error code + // fixed by xxxxxx + var errorInfo = ErrorTypeStrings[type] || type; - var appErrorHandler = instance.appContext.config.errorHandler; + while (cur) { + var errorCapturedHooks = cur.ec; - if (appErrorHandler) { - callWithErrorHandling(appErrorHandler, null, 10 - /* APP_ERROR_HANDLER */ - , [err, exposedInstance, errorInfo]); - return; + if (errorCapturedHooks) { + for (var i = 0; i < errorCapturedHooks.length; i++) { + if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) { + return; + } } } - logError(err, type, contextVNode, throwInDev); - } - - function logError(err, type, contextVNode) { - var throwInDev = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; - { - var info = ErrorTypeStrings[type] || type; // fixed by xxxxxx - - if (contextVNode) { - pushWarningContext(contextVNode); - } - - warn("Unhandled error".concat(info ? " during execution of ".concat(info) : "")); - - if (contextVNode) { - popWarningContext(); - } // crash in dev by default so it's more noticeable + cur = cur.parent; + } // app-level handling - if (throwInDev) { - throw err; - } else { - console.error(err); - } - } - } - - var isFlushing = false; - var isFlushPending = false; - var queue = []; - var flushIndex = 0; - var pendingPreFlushCbs = []; - var activePreFlushCbs = null; - var preFlushIndex = 0; - var pendingPostFlushCbs = []; - var activePostFlushCbs = null; - var postFlushIndex = 0; - var resolvedPromise = Promise.resolve(); - var currentFlushPromise = null; - var currentPreFlushParentJob = null; - var RECURSION_LIMIT = 100; - - function nextTick(fn) { - var 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(id) { - // the start index should be `flushIndex + 1` - var start = flushIndex + 1; - var end = queue.length; - - while (start < end) { - var middle = start + end >>> 1; - var middleJobId = getId(queue[middle]); - middleJobId < id ? 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) { - if (job.id == null) { - queue.push(job); - } else { - queue.splice(findInsertionIndex(job.id), 0, job); - } + var appErrorHandler = instance.appContext.config.errorHandler; - queueFlush(); - } + if (appErrorHandler) { + callWithErrorHandling(appErrorHandler, null, 10 + /* APP_ERROR_HANDLER */ + , [err, exposedInstance, errorInfo]); + return; } + } - function queueFlush() { - if (!isFlushing && !isFlushPending) { - isFlushPending = true; - currentFlushPromise = resolvedPromise.then(flushJobs); - } - } + logError(err, type, contextVNode, throwInDev); +} - function invalidateJob(job) { - var i = queue.indexOf(job); +function logError(err, type, contextVNode) { + var throwInDev = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + { + var info = ErrorTypeStrings[type] || type; // fixed by xxxxxx - if (i > flushIndex) { - queue.splice(i, 1); - } + if (contextVNode) { + pushWarningContext(contextVNode); } - function queueCb(cb, activeQueue, pendingQueue, index) { - if (!shared.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); - } + warn("Unhandled error".concat(info ? " during execution of ".concat(info) : "")); - queueFlush(); - } + if (contextVNode) { + popWarningContext(); + } // crash in dev by default so it's more noticeable - function queuePreFlushCb(cb) { - queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex); - } - function queuePostFlushCb(cb) { - queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex); + if (throwInDev) { + throw err; + } else { + console.error(err); } + } +} - function flushPreFlushCbs(seen) { - var parentJob = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; +var isFlushing = false; +var isFlushPending = false; +var queue = []; +var flushIndex = 0; +var pendingPreFlushCbs = []; +var activePreFlushCbs = null; +var preFlushIndex = 0; +var pendingPostFlushCbs = []; +var activePostFlushCbs = null; +var postFlushIndex = 0; +var resolvedPromise = Promise.resolve(); +var currentFlushPromise = null; +var currentPreFlushParentJob = null; +var RECURSION_LIMIT = 100; + +function nextTick(fn) { + var 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(id) { + // the start index should be `flushIndex + 1` + var start = flushIndex + 1; + var end = queue.length; + + while (start < end) { + var middle = start + end >>> 1; + var middleJobId = getId(queue[middle]); + middleJobId < id ? start = middle + 1 : end = middle; + } + + return start; +} - if (pendingPreFlushCbs.length) { - currentPreFlushParentJob = parentJob; - activePreFlushCbs = [...new Set(pendingPreFlushCbs)]; - pendingPreFlushCbs.length = 0; - { - seen = seen || new Map(); - } +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) { + if (job.id == null) { + queue.push(job); + } else { + queue.splice(findInsertionIndex(job.id), 0, job); + } + + queueFlush(); + } +} - for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) { - if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) { - continue; - } +function queueFlush() { + if (!isFlushing && !isFlushPending) { + isFlushPending = true; + currentFlushPromise = resolvedPromise.then(flushJobs); + } +} - activePreFlushCbs[preFlushIndex](); - } +function invalidateJob(job) { + var i = queue.indexOf(job); - activePreFlushCbs = null; - preFlushIndex = 0; - currentPreFlushParentJob = null; // recursively flush until it drains + if (i > flushIndex) { + queue.splice(i, 1); + } +} - flushPreFlushCbs(seen, parentJob); - } +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); + } - function flushPostFlushCbs(seen) { - if (pendingPostFlushCbs.length) { - var deduped = [...new Set(pendingPostFlushCbs)]; - pendingPostFlushCbs.length = 0; // #1947 already has active queue, nested flushPostFlushCbs call - - if (activePostFlushCbs) { - activePostFlushCbs.push(...deduped); - return; - } + queueFlush(); +} - activePostFlushCbs = deduped; - { - seen = seen || new Map(); - } - activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); +function queuePreFlushCb(cb) { + queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex); +} - for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { - if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) { - continue; - } +function queuePostFlushCb(cb) { + queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex); +} - activePostFlushCbs[postFlushIndex](); - } +function flushPreFlushCbs(seen) { + var parentJob = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - activePostFlushCbs = null; - postFlushIndex = 0; - } + if (pendingPreFlushCbs.length) { + currentPreFlushParentJob = parentJob; + activePreFlushCbs = [...new Set(pendingPreFlushCbs)]; + pendingPreFlushCbs.length = 0; + { + seen = seen || new Map(); } - var getId = job => job.id == null ? Infinity : job.id; - - function flushJobs(seen) { - isFlushPending = false; - isFlushing = true; - { - seen = seen || new Map(); + for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) { + if (checkRecursiveUpdates(seen, activePreFlushCbs[preFlushIndex])) { + continue; } - 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)); // conditional usage of checkRecursiveUpdate must be determined out of - // try ... catch block since Rollup by default de-optimizes treeshaking - // inside try-catch. This can leave all warning code unshaked. Although - // they would get eventually shaken by a minifier like terser, some minifiers - // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610) - var check = job => checkRecursiveUpdates(seen, job); - - try { - for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { - var job = queue[flushIndex]; + activePreFlushCbs[preFlushIndex](); + } - if (job && job.active !== false) { - if ("development" !== 'production' && check(job)) { - continue; - } // console.log(`running:`, job.id) + activePreFlushCbs = null; + preFlushIndex = 0; + currentPreFlushParentJob = null; // recursively flush until it drains + flushPreFlushCbs(seen, parentJob); + } +} - 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. +function flushPostFlushCbs(seen) { + if (pendingPostFlushCbs.length) { + var deduped = [...new Set(pendingPostFlushCbs)]; + pendingPostFlushCbs.length = 0; // #1947 already has active queue, nested flushPostFlushCbs call - if (queue.length || pendingPreFlushCbs.length || pendingPostFlushCbs.length) { - flushJobs(seen); - } - } + if (activePostFlushCbs) { + activePostFlushCbs.push(...deduped); + return; } - function checkRecursiveUpdates(seen, fn) { - if (!seen.has(fn)) { - seen.set(fn, 1); - } else { - var count = seen.get(fn); - - if (count > RECURSION_LIMIT) { - var instance = fn.ownerInstance; - var componentName = instance && getComponentName(instance.type); - warn("Maximum recursive updates exceeded".concat(componentName ? " in component <".concat(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); - } - } + activePostFlushCbs = deduped; + { + seen = seen || new Map(); } - /* eslint-disable no-restricted-globals */ - + activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); - var isHmrUpdating = false; - var 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. + for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { + if (checkRecursiveUpdates(seen, activePostFlushCbs[postFlushIndex])) { + continue; + } - { - shared.getGlobalThis().__VUE_HMR_RUNTIME__ = { - createRecord: tryWrap(createRecord), - rerender: tryWrap(rerender), - reload: tryWrap(reload) - }; + activePostFlushCbs[postFlushIndex](); } - var map = new Map(); - function registerHMR(instance) { - var id = instance.type.__hmrId; - var record = map.get(id); + activePostFlushCbs = null; + postFlushIndex = 0; + } +} - if (!record) { - createRecord(id, instance.type); - record = map.get(id); +var 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)); // conditional usage of checkRecursiveUpdate must be determined out of + // try ... catch block since Rollup by default de-optimizes treeshaking + // inside try-catch. This can leave all warning code unshaked. Although + // they would get eventually shaken by a minifier like terser, some minifiers + // would fail to do that (e.g. https://github.com/evanw/esbuild/issues/1610) + + var check = job => checkRecursiveUpdates(seen, job); + + try { + for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { + var job = queue[flushIndex]; + + if (job && job.active !== false) { + if ("development" !== 'production' && check(job)) { + continue; + } // console.log(`running:`, job.id) + + + callWithErrorHandling(job, null, 14 + /* SCHEDULER */ + ); } - - record.instances.add(instance); } + } finally { + flushIndex = 0; + queue.length = 0; + flushPostFlushCbs(seen); + isFlushing = false; + currentFlushPromise = null; // some postFlushCb queued jobs! + // keep flushing until it drains. - function unregisterHMR(instance) { - map.get(instance.type.__hmrId).instances.delete(instance); + if (queue.length || pendingPreFlushCbs.length || pendingPostFlushCbs.length) { + flushJobs(seen); } + } +} - function createRecord(id, initialDef) { - if (map.has(id)) { - return false; - } +function checkRecursiveUpdates(seen, fn) { + if (!seen.has(fn)) { + seen.set(fn, 1); + } else { + var count = seen.get(fn); - map.set(id, { - initialDef: normalizeClassComponent(initialDef), - instances: new Set() - }); + if (count > RECURSION_LIMIT) { + var instance = fn.ownerInstance; + var componentName = instance && getComponentName(instance.type); + warn("Maximum recursive updates exceeded".concat(componentName ? " in component <".concat(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 */ + + +var isHmrUpdating = false; +var 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. + +{ + getGlobalThis().__VUE_HMR_RUNTIME__ = { + createRecord: tryWrap(createRecord), + rerender: tryWrap(rerender), + reload: tryWrap(reload) + }; +} +var map = new Map(); - function normalizeClassComponent(component) { - return isClassComponent(component) ? component.__vccOpts : component; - } - - function rerender(id, newRender) { - var record = map.get(id); - - if (!record) { - return; - } // update initial record (for not-yet-rendered component) +function registerHMR(instance) { + var id = instance.type.__hmrId; + var record = map.get(id); + if (!record) { + createRecord(id, instance.type); + record = map.get(id); + } - record.initialDef.render = newRender; - [...record.instances].forEach(instance => { - if (newRender) { - instance.render = newRender; - normalizeClassComponent(instance.type).render = newRender; - } + record.instances.add(instance); +} - instance.renderCache = []; // this flag forces child components with slot content to update +function unregisterHMR(instance) { + map.get(instance.type.__hmrId).instances.delete(instance); +} - isHmrUpdating = true; - instance.update(); - isHmrUpdating = false; - }); - } +function createRecord(id, initialDef) { + if (map.has(id)) { + return false; + } - function reload(id, newComp) { - var record = map.get(id); - if (!record) return; - newComp = normalizeClassComponent(newComp); // update initial def (for not-yet-rendered components) + map.set(id, { + initialDef: normalizeClassComponent(initialDef), + instances: new Set() + }); + return true; +} - updateComponentDef(record.initialDef, newComp); // create a snapshot which avoids the set being mutated during updates +function normalizeClassComponent(component) { + return isClassComponent(component) ? component.__vccOpts : component; +} - var instances = [...record.instances]; +function rerender(id, newRender) { + var record = map.get(id); - for (var instance of instances) { - var oldComp = normalizeClassComponent(instance.type); + if (!record) { + return; + } // update initial record (for not-yet-rendered component) - if (!hmrDirtyComponents.has(oldComp)) { - // 1. Update existing comp definition to match new one - if (oldComp !== record.initialDef) { - updateComponentDef(oldComp, newComp); - } // 2. mark definition dirty. This forces the renderer to replace the - // component on patch. + record.initialDef.render = newRender; + [...record.instances].forEach(instance => { + if (newRender) { + instance.render = newRender; + normalizeClassComponent(instance.type).render = newRender; + } - hmrDirtyComponents.add(oldComp); - } // 3. invalidate options resolution cache + instance.renderCache = []; // this flag forces child components with slot content to update + isHmrUpdating = true; + instance.update(); + isHmrUpdating = false; + }); +} - instance.appContext.optionsCache.delete(instance.type); // 4. actually update +function reload(id, newComp) { + var record = map.get(id); + if (!record) return; + newComp = normalizeClassComponent(newComp); // update initial def (for not-yet-rendered components) - if (instance.ceReload) { - // custom element - hmrDirtyComponents.add(oldComp); - instance.ceReload(newComp.styles); - hmrDirtyComponents.delete(oldComp); - } else 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); // instance is the inner component of an async custom element - // invoke to reset styles + updateComponentDef(record.initialDef, newComp); // create a snapshot which avoids the set being mutated during updates - if (instance.parent.type.__asyncLoader && instance.parent.ceReload) { - instance.parent.ceReload(newComp.styles); - } - } 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.'); - } - } // 5. make sure to cleanup dirty hmr components after update + var instances = [...record.instances]; + for (var instance of instances) { + var oldComp = normalizeClassComponent(instance.type); - queuePostFlushCb(() => { - for (var _instance of instances) { - hmrDirtyComponents.delete(normalizeClassComponent(_instance.type)); - } - }); - } + if (!hmrDirtyComponents.has(oldComp)) { + // 1. Update existing comp definition to match new one + if (oldComp !== record.initialDef) { + updateComponentDef(oldComp, newComp); + } // 2. mark definition dirty. This forces the renderer to replace the + // component on patch. - function updateComponentDef(oldComp, newComp) { - shared.extend(oldComp, newComp); - for (var key in oldComp) { - if (key !== '__file' && !(key in newComp)) { - delete oldComp[key]; - } - } - } + hmrDirtyComponents.add(oldComp); + } // 3. invalidate options resolution cache - 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."); - } - }; - } - var devtools; - var buffer = []; - var devtoolsNotInstalled = false; + instance.appContext.optionsCache.delete(instance.type); // 4. actually update - function emit(event) { - for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { - args[_key2 - 1] = arguments[_key2]; - } + if (instance.ceReload) { + // custom element + hmrDirtyComponents.add(oldComp); + instance.ceReload(newComp.styles); + hmrDirtyComponents.delete(oldComp); + } else 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); // instance is the inner component of an async custom element + // invoke to reset styles - if (devtools) { - devtools.emit(event, ...args); - } else if (!devtoolsNotInstalled) { - buffer.push({ - event, - args - }); + if (instance.parent.type.__asyncLoader && instance.parent.ceReload) { + instance.parent.ceReload(newComp.styles); } + } 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.'); } + } // 5. make sure to cleanup dirty hmr components after update - function setDevtoolsHook(hook, target) { - var _a, _b; - - devtools = hook; - if (devtools) { - devtools.enabled = true; - buffer.forEach(_ref3 => { - var { - event, - args - } = _ref3; - return devtools.emit(event, ...args); - }); - buffer = []; - } else if ( // handle late devtools injection - only do this if we are in an actual - // browser environment to avoid the timer handle stalling test runner exit - // (#4815) - // eslint-disable-next-line no-restricted-globals - typeof window !== 'undefined' && // some envs mock window but not fully - window.HTMLElement && // also exclude jsdom - !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) { - var replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []; - replay.push(newHook => { - setDevtoolsHook(newHook, target); - }); // clear buffer after 3s - the user probably doesn't have devtools installed - // at all, and keeping the buffer will cause memory leaks (#4738) - - setTimeout(() => { - if (!devtools) { - target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null; - devtoolsNotInstalled = true; - buffer = []; - } - }, 3000); - } else { - // non-browser env, assume not installed - devtoolsNotInstalled = true; - buffer = []; - } + queuePostFlushCb(() => { + for (var _instance of instances) { + hmrDirtyComponents.delete(normalizeClassComponent(_instance.type)); } + }); +} - function devtoolsInitApp(app, version) { - emit("app:init" - /* APP_INIT */ - , app, version, { - Fragment, - Text, - Comment, - Static - }); - } +function updateComponentDef(oldComp, newComp) { + extend(oldComp, newComp); - function devtoolsUnmountApp(app) { - emit("app:unmount" - /* APP_UNMOUNT */ - , app); + for (var key in oldComp) { + if (key !== '__file' && !(key in newComp)) { + delete oldComp[key]; } + } +} - var devtoolsComponentAdded = /*#__PURE__*/createDevtoolsComponentHook("component:added" - /* COMPONENT_ADDED */ - ); - var devtoolsComponentUpdated = /*#__PURE__*/createDevtoolsComponentHook("component:updated" - /* COMPONENT_UPDATED */ - ); - var devtoolsComponentRemoved = /*#__PURE__*/createDevtoolsComponentHook("component:removed" - /* COMPONENT_REMOVED */ - ); - - function createDevtoolsComponentHook(hook) { - return component => { - emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component); - }; +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."); } + }; +} - var devtoolsPerfStart = /*#__PURE__*/createDevtoolsPerformanceHook("perf:start" - /* PERFORMANCE_START */ - ); - var devtoolsPerfEnd = /*#__PURE__*/createDevtoolsPerformanceHook("perf:end" - /* PERFORMANCE_END */ - ); - - function createDevtoolsPerformanceHook(hook) { - return (component, type, time) => { - emit(hook, component.appContext.app, component.uid, component, type, time); - }; - } +var devtools; +var buffer = []; +var devtoolsNotInstalled = false; + +function emit(event) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + if (devtools) { + devtools.emit(event, ...args); + } else if (!devtoolsNotInstalled) { + buffer.push({ + event, + args + }); + } +} - function devtoolsComponentEmit(component, event, params) { - emit("component:emit" - /* COMPONENT_EMIT */ - , component.appContext.app, component, event, params); - } +function setDevtoolsHook(hook, target) { + var _a, _b; - function emit$1(instance, event) { - var props = instance.vnode.props || shared.EMPTY_OBJ; + devtools = hook; - for (var _len3 = arguments.length, rawArgs = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) { - rawArgs[_key3 - 2] = arguments[_key3]; + if (devtools) { + devtools.enabled = true; + buffer.forEach(_ref3 => { + var { + event, + args + } = _ref3; + return devtools.emit(event, ...args); + }); + buffer = []; + } else if ( // handle late devtools injection - only do this if we are in an actual + // browser environment to avoid the timer handle stalling test runner exit + // (#4815) + // eslint-disable-next-line no-restricted-globals + typeof window !== 'undefined' && // some envs mock window but not fully + window.HTMLElement && // also exclude jsdom + !((_b = (_a = window.navigator) === null || _a === void 0 ? void 0 : _a.userAgent) === null || _b === void 0 ? void 0 : _b.includes('jsdom'))) { + var replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || []; + replay.push(newHook => { + setDevtoolsHook(newHook, target); + }); // clear buffer after 3s - the user probably doesn't have devtools installed + // at all, and keeping the buffer will cause memory leaks (#4738) + + setTimeout(() => { + if (!devtools) { + target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null; + devtoolsNotInstalled = true; + buffer = []; } + }, 3000); + } else { + // non-browser env, assume not installed + devtoolsNotInstalled = true; + buffer = []; + } +} - { - var { - emitsOptions, - propsOptions: [propsOptions] - } = instance; +function devtoolsInitApp(app, version) { + emit("app:init" + /* APP_INIT */ + , app, version, { + Fragment, + Text, + Comment, + Static + }); +} - if (emitsOptions) { - if (!(event in emitsOptions) && !false) { - if (!propsOptions || !(shared.toHandlerKey(event) in propsOptions)) { - warn("Component emitted event \"".concat(event, "\" but it is neither declared in ") + "the emits option nor as an \"".concat(shared.toHandlerKey(event), "\" prop.")); - } - } else { - var validator = emitsOptions[event]; +function devtoolsUnmountApp(app) { + emit("app:unmount" + /* APP_UNMOUNT */ + , app); +} - if (shared.isFunction(validator)) { - var isValid = validator(...rawArgs); +var devtoolsComponentAdded = /*#__PURE__*/createDevtoolsComponentHook("component:added" +/* COMPONENT_ADDED */ +); +var devtoolsComponentUpdated = /*#__PURE__*/createDevtoolsComponentHook("component:updated" +/* COMPONENT_UPDATED */ +); +var devtoolsComponentRemoved = /*#__PURE__*/createDevtoolsComponentHook("component:removed" +/* COMPONENT_REMOVED */ +); + +function createDevtoolsComponentHook(hook) { + return component => { + emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined, component); + }; +} - if (!isValid) { - warn("Invalid event arguments: event validation failed for event \"".concat(event, "\".")); - } - } - } - } - } - var args = rawArgs; - var isModelListener = event.startsWith('update:'); // for v-model update:xxx events, apply modifiers on args +var devtoolsPerfStart = /*#__PURE__*/createDevtoolsPerformanceHook("perf:start" +/* PERFORMANCE_START */ +); +var devtoolsPerfEnd = /*#__PURE__*/createDevtoolsPerformanceHook("perf:end" +/* PERFORMANCE_END */ +); + +function createDevtoolsPerformanceHook(hook) { + return (component, type, time) => { + emit(hook, component.appContext.app, component.uid, component, type, time); + }; +} - var modelArg = isModelListener && event.slice(7); +function devtoolsComponentEmit(component, event, params) { + emit("component:emit" + /* COMPONENT_EMIT */ + , component.appContext.app, component, event, params); +} - if (modelArg && modelArg in props) { - var modifiersKey = "".concat(modelArg === 'modelValue' ? 'model' : modelArg, "Modifiers"); - var { - number, - trim - } = props[modifiersKey] || shared.EMPTY_OBJ; +function emit$1(instance, event) { + var props = instance.vnode.props || EMPTY_OBJ; - if (trim) { - args = rawArgs.map(a => a.trim()); - } else if (number) { - args = rawArgs.map(shared.toNumber); - } - } + for (var _len3 = arguments.length, rawArgs = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) { + rawArgs[_key3 - 2] = arguments[_key3]; + } - { - devtoolsComponentEmit(instance, event, args); - } - { - var lowerCaseEvent = event.toLowerCase(); + { + var { + emitsOptions, + propsOptions: [propsOptions] + } = instance; - if (lowerCaseEvent !== event && props[shared.toHandlerKey(lowerCaseEvent)]) { - warn("Event \"".concat(lowerCaseEvent, "\" is emitted in component ") + "".concat(formatComponentName(instance, instance.type), " but the handler is registered for \"").concat(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 \"".concat(shared.hyphenate(event), "\" instead of \"").concat(event, "\".")); + if (emitsOptions) { + if (!(event in emitsOptions) && !false) { + if (!propsOptions || !(toHandlerKey(event) in propsOptions)) { + warn("Component emitted event \"".concat(event, "\" but it is neither declared in ") + "the emits option nor as an \"".concat(toHandlerKey(event), "\" prop.")); } - } - var handlerName; - var handler = props[handlerName = shared.toHandlerKey(event)] || // also try camelCase event handler (#2249) - props[handlerName = shared.toHandlerKey(shared.camelize(event))]; // for v-model update:xxx events, also trigger kebab-case equivalent - // for props passed via kebab-case + } else { + var validator = emitsOptions[event]; - if (!handler && isModelListener) { - handler = props[handlerName = shared.toHandlerKey(shared.hyphenate(event))]; - } + if (isFunction(validator)) { + var isValid = validator(...rawArgs); - if (handler) { - callWithAsyncErrorHandling(handler, instance, 6 - /* COMPONENT_EVENT_HANDLER */ - , args); + if (!isValid) { + warn("Invalid event arguments: event validation failed for event \"".concat(event, "\".")); + } + } } + } + } + var args = rawArgs; + var isModelListener = event.startsWith('update:'); // for v-model update:xxx events, apply modifiers on args - var onceHandler = props[handlerName + "Once"]; + var modelArg = isModelListener && event.slice(7); - if (onceHandler) { - if (!instance.emitted) { - instance.emitted = {}; - } else if (instance.emitted[handlerName]) { - return; - } + if (modelArg && modelArg in props) { + var modifiersKey = "".concat(modelArg === 'modelValue' ? 'model' : modelArg, "Modifiers"); + var { + number, + trim + } = props[modifiersKey] || EMPTY_OBJ; - instance.emitted[handlerName] = true; - callWithAsyncErrorHandling(onceHandler, instance, 6 - /* COMPONENT_EVENT_HANDLER */ - , args); - } + if (trim) { + args = rawArgs.map(a => a.trim()); + } else if (number) { + args = rawArgs.map(toNumber); } + } - function normalizeEmitsOptions(comp, appContext) { - var asMixin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var cache = appContext.emitsCache; - var cached = cache.get(comp); - - if (cached !== undefined) { - return cached; - } + { + devtoolsComponentEmit(instance, event, args); + } + { + var lowerCaseEvent = event.toLowerCase(); - var raw = comp.emits; - var normalized = {}; // apply mixin/extends props + if (lowerCaseEvent !== event && props[toHandlerKey(lowerCaseEvent)]) { + warn("Event \"".concat(lowerCaseEvent, "\" is emitted in component ") + "".concat(formatComponentName(instance, instance.type), " but the handler is registered for \"").concat(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 \"".concat(hyphenate(event), "\" instead of \"").concat(event, "\".")); + } + } + var handlerName; + var 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 - var hasExtends = false; + if (!handler && isModelListener) { + handler = props[handlerName = toHandlerKey(hyphenate(event))]; + } - if (!shared.isFunction(comp)) { - var extendEmits = raw => { - var normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true); + if (handler) { + callWithAsyncErrorHandling(handler, instance, 6 + /* COMPONENT_EVENT_HANDLER */ + , args); + } - if (normalizedFromExtend) { - hasExtends = true; - shared.extend(normalized, normalizedFromExtend); - } - }; + var onceHandler = props[handlerName + "Once"]; - if (!asMixin && appContext.mixins.length) { - appContext.mixins.forEach(extendEmits); - } + if (onceHandler) { + if (!instance.emitted) { + instance.emitted = {}; + } else if (instance.emitted[handlerName]) { + return; + } - if (comp.extends) { - extendEmits(comp.extends); - } + instance.emitted[handlerName] = true; + callWithAsyncErrorHandling(onceHandler, instance, 6 + /* COMPONENT_EVENT_HANDLER */ + , args); + } +} - if (comp.mixins) { - comp.mixins.forEach(extendEmits); - } - } +function normalizeEmitsOptions(comp, appContext) { + var asMixin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var cache = appContext.emitsCache; + var cached = cache.get(comp); - if (!raw && !hasExtends) { - cache.set(comp, null); - return null; - } + if (cached !== undefined) { + return cached; + } - if (shared.isArray(raw)) { - raw.forEach(key => normalized[key] = null); - } else { - shared.extend(normalized, raw); - } + var raw = comp.emits; + var normalized = {}; // apply mixin/extends props - cache.set(comp, normalized); - return 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. + var hasExtends = false; + if (!isFunction(comp)) { + var extendEmits = raw => { + var normalizedFromExtend = normalizeEmitsOptions(raw, appContext, true); - function isEmitListener(options, key) { - if (!options || !shared.isOn(key)) { - return false; + if (normalizedFromExtend) { + hasExtends = true; + extend(normalized, normalizedFromExtend); } + }; - key = key.slice(2).replace(/Once$/, ''); - return shared.hasOwn(options, key[0].toLowerCase() + key.slice(1)) || shared.hasOwn(options, shared.hyphenate(key)) || shared.hasOwn(options, key); + if (!asMixin && appContext.mixins.length) { + appContext.mixins.forEach(extendEmits); } - /** - * mark the current rendering instance for asset resolution (e.g. - * resolveComponent, resolveDirective) during render - */ - - - var currentRenderingInstance = null; - var 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) { - var prev = currentRenderingInstance; - currentRenderingInstance = instance; - currentScopeId = instance && instance.type.__scopeId || null; - return prev; + if (comp.extends) { + extendEmits(comp.extends); } - /** - * Set scope id when creating hoisted vnodes. - * @private compiler helper - */ - - function pushScopeId(id) { - currentScopeId = id; + if (comp.mixins) { + comp.mixins.forEach(extendEmits); } - /** - * 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 - */ + } + if (!raw && !hasExtends) { + cache.set(comp, null); + return null; + } - function popScopeId() { - currentScopeId = null; - } - /** - * Only for backwards compat - * @private - */ + if (isArray(raw)) { + raw.forEach(key => normalized[key] = null); + } else { + extend(normalized, raw); + } + cache.set(comp, normalized); + return 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. - var withScopeId = _id => withCtx; - /** - * Wrap a slot function to memoize current rendering instance - * @private compiler helper - */ +function isEmitListener(options, key) { + if (!options || !isOn(key)) { + return false; + } + + key = key.slice(2).replace(/Once$/, ''); + return hasOwn(options, key[0].toLowerCase() + key.slice(1)) || hasOwn(options, hyphenate(key)) || hasOwn(options, key); +} +/** + * mark the current rendering instance for asset resolution (e.g. + * resolveComponent, resolveDirective) during render + */ + + +var currentRenderingInstance = null; +var 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) { + var prev = currentRenderingInstance; + currentRenderingInstance = instance; + currentScopeId = instance && instance.type.__scopeId || null; + return prev; +} +/** + * Set scope id when creating hoisted vnodes. + * @private compiler helper + */ - function withCtx(fn) { - var ctx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : currentRenderingInstance; - var isNonScopedSlot // false only - = arguments.length > 2 ? arguments[2] : undefined; - if (!ctx) return fn; // already normalized - if (fn._n) { - return fn; - } +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 + */ - var renderFnWithContext = function () { - // If a user calls a compiled slot inside a template expression (#1745), it - // can mess up block tracking, so by default we disable block tracking and - // force bail out when invoking a compiled slot (indicated by the ._d flag). - // This isn't necessary if rendering a compiled ``, so we flip the - // ._d flag off when invoking the wrapped fn inside `renderSlot`. - if (renderFnWithContext._d) { - setBlockTracking(-1); - } - var prevInstance = setCurrentRenderingInstance(ctx); - var res = fn(...arguments); - setCurrentRenderingInstance(prevInstance); +function popScopeId() { + currentScopeId = null; +} +/** + * Only for backwards compat + * @private + */ - if (renderFnWithContext._d) { - setBlockTracking(1); - } - { - devtoolsComponentUpdated(ctx); - } - return res; - }; // mark normalized to avoid duplicated wrapping +var withScopeId = _id => withCtx; +/** + * Wrap a slot function to memoize current rendering instance + * @private compiler helper + */ - renderFnWithContext._n = true; // mark this as compiled by default - // this is used in vnode.ts -> normalizeChildren() to set the slot - // rendering flag. +function withCtx(fn) { + var ctx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : currentRenderingInstance; + var isNonScopedSlot // false only + = arguments.length > 2 ? arguments[2] : undefined; + if (!ctx) return fn; // already normalized - renderFnWithContext._c = true; // disable block tracking by default + if (fn._n) { + return fn; + } - renderFnWithContext._d = true; - return renderFnWithContext; + var renderFnWithContext = function () { + // If a user calls a compiled slot inside a template expression (#1745), it + // can mess up block tracking, so by default we disable block tracking and + // force bail out when invoking a compiled slot (indicated by the ._d flag). + // This isn't necessary if rendering a compiled ``, so we flip the + // ._d flag off when invoking the wrapped fn inside `renderSlot`. + if (renderFnWithContext._d) { + setBlockTracking(-1); } - /** - * 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. - */ + var prevInstance = setCurrentRenderingInstance(ctx); + var res = fn(...arguments); + setCurrentRenderingInstance(prevInstance); - var accessedAttrs = false; + if (renderFnWithContext._d) { + setBlockTracking(1); + } - function markAttrsAccessed() { - accessedAttrs = true; + { + devtoolsComponentUpdated(ctx); } + return res; + }; // mark normalized to avoid duplicated wrapping - function renderComponentRoot(instance) { - var { - type: Component, - vnode, - proxy, - withProxy, - props, - propsOptions: [propsOptions], - slots, - attrs, - emit, - render, - renderCache, - data, - setupState, - ctx, - inheritAttrs - } = instance; - var result; - var fallthroughAttrs; - var prev = setCurrentRenderingInstance(instance); - { - accessedAttrs = false; - } - try { - if (vnode.shapeFlag & 4 - /* STATEFUL_COMPONENT */ - ) { - // withProxy is a proxy with a different `has` trap only for - // runtime-compiled render functions using `with` block. - var proxyToUse = withProxy || proxy; - result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx)); - fallthroughAttrs = attrs; - } else { - // functional - var _render = Component; // in dev, mark attrs accessed if optional props (attrs === props) + renderFnWithContext._n = true; // mark this as compiled by default + // this is used in vnode.ts -> normalizeChildren() to set the slot + // rendering flag. - if ("development" !== 'production' && attrs === props) { - markAttrsAccessed(); - } + renderFnWithContext._c = true; // disable block tracking by default - result = normalizeVNode(_render.length > 1 ? _render(props, "development" !== 'production' ? { - 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); - } - } catch (err) { - blockStack.length = 0; - handleError(err, instance, 1 - /* RENDER_FUNCTION */ - ); - result = createVNode(Comment); - } // 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 + renderFnWithContext._d = 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. + */ - var root = result; - var setRoot = undefined; +var accessedAttrs = false; - if (result.patchFlag > 0 && result.patchFlag & 2048 - /* DEV_ROOT_FRAGMENT */ - ) { - [root, setRoot] = getChildRoot(result); +function markAttrsAccessed() { + accessedAttrs = true; +} + +function renderComponentRoot(instance) { + var { + type: Component, + vnode, + proxy, + withProxy, + props, + propsOptions: [propsOptions], + slots, + attrs, + emit, + render, + renderCache, + data, + setupState, + ctx, + inheritAttrs + } = instance; + var result; + var fallthroughAttrs; + var prev = setCurrentRenderingInstance(instance); + { + accessedAttrs = false; + } + + try { + if (vnode.shapeFlag & 4 + /* STATEFUL_COMPONENT */ + ) { + // withProxy is a proxy with a different `has` trap only for + // runtime-compiled render functions using `with` block. + var proxyToUse = withProxy || proxy; + result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx)); + fallthroughAttrs = attrs; + } else { + // functional + var _render = Component; // in dev, mark attrs accessed if optional props (attrs === props) + + if ("development" !== 'production' && attrs === props) { + markAttrsAccessed(); } - if (fallthroughAttrs && inheritAttrs !== false) { - var keys = Object.keys(fallthroughAttrs); - var { - shapeFlag - } = root; + result = normalizeVNode(_render.length > 1 ? _render(props, "development" !== 'production' ? { + get attrs() { + markAttrsAccessed(); + return attrs; + }, - if (keys.length) { - if (shapeFlag & (1 - /* ELEMENT */ - | 6 - /* COMPONENT */ - )) { - if (propsOptions && keys.some(shared.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); - } + slots, + emit + } : { + attrs, + slots, + emit + }) : _render(props, null + /* we know it doesn't need it */ + )); + fallthroughAttrs = Component.props ? attrs : getFunctionalFallthrough(attrs); + } + } catch (err) { + blockStack.length = 0; + handleError(err, instance, 1 + /* RENDER_FUNCTION */ + ); + result = createVNode(Comment); + } // 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 - root = cloneVNode(root, fallthroughAttrs); - } else if (!accessedAttrs && root.type !== Comment) { - var allAttrs = Object.keys(attrs); - var eventAttrs = []; - var extraAttrs = []; - - for (var i = 0, l = allAttrs.length; i < l; i++) { - var key = allAttrs[i]; - - if (shared.isOn(key)) { - // ignore v-model handlers when they fail to fallthrough - if (!shared.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 (" + "".concat(extraAttrs.join(', '), ") ") + "were passed to component but could not be automatically inherited " + "because component renders fragment or text root nodes."); - } + var root = result; + var setRoot = undefined; + + if (result.patchFlag > 0 && result.patchFlag & 2048 + /* DEV_ROOT_FRAGMENT */ + ) { + [root, setRoot] = getChildRoot(result); + } - if (eventAttrs.length) { - warn("Extraneous non-emits event listeners (" + "".concat(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 (fallthroughAttrs && inheritAttrs !== false) { + var keys = Object.keys(fallthroughAttrs); + var { + shapeFlag + } = root; + + if (keys.length) { + if (shapeFlag & (1 + /* ELEMENT */ + | 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 (!accessedAttrs && root.type !== Comment) { + var allAttrs = Object.keys(attrs); + var eventAttrs = []; + var extraAttrs = []; + + for (var i = 0, l = allAttrs.length; i < l; i++) { + var 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); } } - } // inherit directives - - if (vnode.dirs) { - if (!isElementRoot(root)) { - warn("Runtime directive used on component with non-element root node. " + "The directives will not function as intended."); + if (extraAttrs.length) { + warn("Extraneous non-props attributes (" + "".concat(extraAttrs.join(', '), ") ") + "were passed to component but could not be automatically inherited " + "because component renders fragment or text root nodes."); } - root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs; - } // inherit transition data - - - if (vnode.transition) { - if (!isElementRoot(root)) { - warn("Component inside renders non-element root node " + "that cannot be animated."); + if (eventAttrs.length) { + warn("Extraneous non-emits event listeners (" + "".concat(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."); } - - root.transition = vnode.transition; - } - - if (setRoot) { - setRoot(root); - } else { - result = root; } - - 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. - */ - + } // inherit directives - var getChildRoot = vnode => { - var rawChildren = vnode.children; - var dynamicChildren = vnode.dynamicChildren; - var childRoot = filterSingleRoot(rawChildren); - if (!childRoot) { - return [vnode, undefined]; - } + if (vnode.dirs) { + if (!isElementRoot(root)) { + warn("Runtime directive used on component with non-element root node. " + "The directives will not function as intended."); + } - var index = rawChildren.indexOf(childRoot); - var dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; + root.dirs = root.dirs ? root.dirs.concat(vnode.dirs) : vnode.dirs; + } // inherit transition data - var setRoot = updatedRoot => { - rawChildren[index] = updatedRoot; - if (dynamicChildren) { - if (dynamicIndex > -1) { - dynamicChildren[dynamicIndex] = updatedRoot; - } else if (updatedRoot.patchFlag > 0) { - vnode.dynamicChildren = [...dynamicChildren, updatedRoot]; - } - } - }; + if (vnode.transition) { + if (!isElementRoot(root)) { + warn("Component inside renders non-element root node " + "that cannot be animated."); + } - return [normalizeVNode(childRoot), setRoot]; - }; + root.transition = vnode.transition; + } - function filterSingleRoot(children) { - var singleRoot; + if (setRoot) { + setRoot(root); + } else { + result = root; + } - for (var i = 0; i < children.length; i++) { - var 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; - } - } + 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. + */ - return singleRoot; - } - var getFunctionalFallthrough = attrs => { - var res; +var getChildRoot = vnode => { + var rawChildren = vnode.children; + var dynamicChildren = vnode.dynamicChildren; + var childRoot = filterSingleRoot(rawChildren); - for (var key in attrs) { - if (key === 'class' || key === 'style' || shared.isOn(key)) { - (res || (res = {}))[key] = attrs[key]; - } - } + if (!childRoot) { + return [vnode, undefined]; + } - return res; - }; + var index = rawChildren.indexOf(childRoot); + var dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; - var filterModelListeners = (attrs, props) => { - var res = {}; + var setRoot = updatedRoot => { + rawChildren[index] = updatedRoot; - for (var key in attrs) { - if (!shared.isModelListener(key) || !(key.slice(9) in props)) { - res[key] = attrs[key]; - } + if (dynamicChildren) { + if (dynamicIndex > -1) { + dynamicChildren[dynamicIndex] = updatedRoot; + } else if (updatedRoot.patchFlag > 0) { + vnode.dynamicChildren = [...dynamicChildren, updatedRoot]; } + } + }; - return res; - }; - - var isElementRoot = vnode => { - return vnode.shapeFlag & (6 - /* COMPONENT */ - | 1 - /* ELEMENT */ - ) || vnode.type === Comment // potential v-if branch switch - ; - }; - - function shouldUpdateComponent(prevVNode, nextVNode, optimized) { - var { - props: prevProps, - children: prevChildren, - component - } = prevVNode; - var { - props: nextProps, - children: nextChildren, - patchFlag - } = nextVNode; - var 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. + return [normalizeVNode(childRoot), setRoot]; +}; +function filterSingleRoot(children) { + var singleRoot; - if (nextVNode.dirs || nextVNode.transition) { - return true; - } + for (var i = 0; i < children.length; i++) { + var child = children[i]; - 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 (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; + } + } - if (patchFlag & 16 - /* FULL_PROPS */ - ) { - if (!prevProps) { - return !!nextProps; - } // presence of this flag indicates props are always non-null - + return singleRoot; +} - return hasPropsChanged(prevProps, nextProps, emits); - } else if (patchFlag & 8 - /* PROPS */ - ) { - var dynamicProps = nextVNode.dynamicProps; +var getFunctionalFallthrough = attrs => { + var res; + + for (var key in attrs) { + if (key === 'class' || key === 'style' || isOn(key)) { + (res || (res = {}))[key] = attrs[key]; + } + } + + return res; +}; + +var filterModelListeners = (attrs, props) => { + var res = {}; + + for (var key in attrs) { + if (!isModelListener(key) || !(key.slice(9) in props)) { + res[key] = attrs[key]; + } + } + + return res; +}; + +var isElementRoot = vnode => { + return vnode.shapeFlag & (6 + /* COMPONENT */ + | 1 + /* ELEMENT */ + ) || vnode.type === Comment // potential v-if branch switch + ; +}; + +function shouldUpdateComponent(prevVNode, nextVNode, optimized) { + var { + props: prevProps, + children: prevChildren, + component + } = prevVNode; + var { + props: nextProps, + children: nextChildren, + patchFlag + } = nextVNode; + var 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; + } - for (var i = 0; i < dynamicProps.length; i++) { - var key = dynamicProps[i]; + if (patchFlag & 16 + /* FULL_PROPS */ + ) { + if (!prevProps) { + return !!nextProps; + } // presence of this flag indicates props are always non-null - 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; - } + return hasPropsChanged(prevProps, nextProps, emits); + } else if (patchFlag & 8 + /* PROPS */ + ) { + var dynamicProps = nextVNode.dynamicProps; - if (!prevProps) { - return !!nextProps; - } + for (var i = 0; i < dynamicProps.length; i++) { + var key = dynamicProps[i]; - if (!nextProps) { + if (nextProps[key] !== prevProps[key] && !isEmitListener(emits, key)) { return true; } - - return hasPropsChanged(prevProps, nextProps, emits); } - - return false; } - - function hasPropsChanged(prevProps, nextProps, emitsOptions) { - var nextKeys = Object.keys(nextProps); - - if (nextKeys.length !== Object.keys(prevProps).length) { + } 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; } + } - for (var i = 0; i < nextKeys.length; i++) { - var key = nextKeys[i]; - - if (nextProps[key] !== prevProps[key] && !isEmitListener(emitsOptions, key)) { - return true; - } - } - + if (prevProps === nextProps) { return false; } - function updateHOCHostEl(_ref4, el // HostNode - ) { - var { - vnode, - parent - } = _ref4; + if (!prevProps) { + return !!nextProps; + } - while (parent && parent.subTree === vnode) { - (vnode = parent.vnode).el = el; - parent = parent.parent; - } + if (!nextProps) { + return true; } - var 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. + return hasPropsChanged(prevProps, nextProps, emits); + } + return false; +} - var 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, +function hasPropsChanged(prevProps, nextProps, emitsOptions) { + var nextKeys = Object.keys(nextProps); - 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); - } - }, + if (nextKeys.length !== Object.keys(prevProps).length) { + return true; + } - hydrate: hydrateSuspense, - create: createSuspenseBoundary, - normalize: normalizeSuspenseChildren - }; // Force-casted public typing for h and TSX props inference + for (var i = 0; i < nextKeys.length; i++) { + var key = nextKeys[i]; - var Suspense = SuspenseImpl; + if (nextProps[key] !== prevProps[key] && !isEmitListener(emitsOptions, key)) { + return true; + } + } - function triggerEvent(vnode, name) { - var eventListener = vnode.props && vnode.props[name]; + return false; +} - if (shared.isFunction(eventListener)) { - eventListener(); - } - } +function updateHOCHostEl(_ref4, el // HostNode +) { + var { + vnode, + parent + } = _ref4; + + while (parent && parent.subTree === vnode) { + (vnode = parent.vnode).el = el; + parent = parent.parent; + } +} - function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) { - var { - p: patch, - o: { - createElement - } - } = rendererInternals; - var hiddenContainer = createElement('div'); - var suspense = vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals); // start mounting the content subtree in an off-dom container +var 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. - 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 - // invoke @fallback event - triggerEvent(vnode, 'onPending'); - triggerEvent(vnode, 'onFallback'); // mount the fallback tree +var 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, - 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(); - } + 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); } + }, - function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, _ref5) { - var { - p: patch, - um: unmount, - o: { - createElement - } - } = _ref5; - var suspense = n2.suspense = n1.suspense; - suspense.vnode = n2; - n2.el = n1.el; - var newBranch = n2.ssContent; - var newFallback = n2.ssFallback; - var { - activeBranch, - pendingBranch, - isInFallback, - isHydrating - } = suspense; + hydrate: hydrateSuspense, + create: createSuspenseBoundary, + normalize: normalizeSuspenseChildren +}; // Force-casted public typing for h and TSX props inference - if (pendingBranch) { - suspense.pendingBranch = newBranch; +var Suspense = SuspenseImpl; - if (isSameVNodeType(newBranch, pendingBranch)) { - // same root type but content may have changed. - patch(pendingBranch, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); +function triggerEvent(vnode, name) { + var eventListener = vnode.props && vnode.props[name]; - 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 + if (isFunction(eventListener)) { + eventListener(); + } +} +function mountSuspense(vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals) { + var { + p: patch, + o: { + createElement + } + } = rendererInternals; + var hiddenContainer = createElement('div'); + var 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 + // invoke @fallback event + triggerEvent(vnode, 'onPending'); + triggerEvent(vnode, 'onFallback'); // 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(); + } +} - suspense.deps = 0; // discard effects from pending branch +function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, slotScopeIds, optimized, _ref5) { + var { + p: patch, + um: unmount, + o: { + createElement + } + } = _ref5; + var suspense = n2.suspense = n1.suspense; + suspense.vnode = n2; + n2.el = n1.el; + var newBranch = n2.ssContent; + var newFallback = n2.ssFallback; + var { + 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.effects.length = 0; // discard previous container - suspense.hiddenContainer = createElement('div'); + suspense.deps = 0; // discard effects from pending branch - if (isInFallback) { - // already in fallback state - patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); + suspense.effects.length = 0; // discard previous container - 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.hiddenContainer = createElement('div'); - suspense.resolve(true); - } else { - // switched to a 3rd branch - patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); + if (isInFallback) { + // already in fallback state + patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); - if (suspense.deps <= 0) { - suspense.resolve(); - } - } + 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 { - 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 - triggerEvent(n2, 'onPending'); // mount pending branch in off-dom container + // 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 + triggerEvent(n2, 'onPending'); // mount pending branch in off-dom container - suspense.pendingBranch = newBranch; - suspense.pendingId++; - patch(null, newBranch, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, slotScopeIds, optimized); + 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 { - var { - timeout, - pendingId - } = suspense; - - if (timeout > 0) { - setTimeout(() => { - if (suspense.pendingId === pendingId) { - suspense.fallback(newFallback); - } - }, timeout); - } else if (timeout === 0) { + if (suspense.deps <= 0) { + // incoming branch has no async deps, resolve now. + suspense.resolve(); + } else { + var { + timeout, + pendingId + } = suspense; + + if (timeout > 0) { + setTimeout(() => { + if (suspense.pendingId === pendingId) { suspense.fallback(newFallback); } - } + }, timeout); + } else if (timeout === 0) { + suspense.fallback(newFallback); } } } + } +} - var hasWarned = false; - - function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals) { - var isHydrating = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false; - - /* istanbul ignore if */ - if (!hasWarned) { - hasWarned = true; // @ts-ignore `console.info` cannot be null error +var hasWarned = false; + +function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, slotScopeIds, optimized, rendererInternals) { + var isHydrating = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : 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."); + } + + var { + p: patch, + m: move, + um: unmount, + n: next, + o: { + parentNode, + remove + } + } = rendererInternals; + var timeout = toNumber(vnode.props && vnode.props.timeout); + var 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() { + var resume = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + { + if (!resume && !suspense.pendingBranch) { + throw new Error("suspense.resolve() is called without a pending branch."); + } - console[console.info ? 'info' : 'log'](" is an experimental feature and its API will likely change."); + if (suspense.isUnmounted) { + throw new Error("suspense.resolve() is called on an already unmounted suspense boundary."); + } } - var { - p: patch, - m: move, - um: unmount, - n: next, - o: { - parentNode, - remove - } - } = rendererInternals; - var timeout = shared.toNumber(vnode.props && vnode.props.timeout); - var suspense = { vnode, - parent, + activeBranch, + pendingBranch, + pendingId, + effects, 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() { - var resume = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - { - if (!resume && !suspense.pendingBranch) { - throw new Error("suspense.resolve() is called without a pending branch."); - } + container + } = suspense; - if (suspense.isUnmounted) { - throw new Error("suspense.resolve() is called on an already unmounted suspense boundary."); - } - } - var { - vnode, - activeBranch, - pendingBranch, - pendingId, - effects, - parentComponent, - container - } = suspense; - - if (suspense.isHydrating) { - suspense.isHydrating = false; - } else if (!resume) { - var 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 - - - var { - anchor: _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 (suspense.isHydrating) { + suspense.isHydrating = false; + } else if (!resume) { + var delayEnter = activeBranch && pendingBranch.transition && pendingBranch.transition.mode === 'out-in'; - if (!delayEnter) { - // move content from off-dom container to actual container + if (delayEnter) { + activeBranch.transition.afterLeave = () => { + if (pendingId === suspense.pendingId) { move(pendingBranch, container, _anchor, 0 /* ENTER */ ); } - } + }; + } // this is initial anchor on mount - setActiveBranch(suspense, pendingBranch); - suspense.pendingBranch = null; - suspense.isInFallback = false; // flush buffered effects - // check if there is a pending parent suspense - var parent = suspense.parent; - var hasUnresolvedAncestor = false; + var { + anchor: _anchor + } = suspense; // unmount current active tree - while (parent) { - if (parent.pendingBranch) { - // found a pending parent suspense, merge buffered post jobs - // into that parent - parent.effects.push(...effects); - hasUnresolvedAncestor = true; - break; - } + 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); + } - parent = parent.parent; - } // no pending parent suspense, flush all jobs + 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 - if (!hasUnresolvedAncestor) { - queuePostFlushCb(effects); - } + var parent = suspense.parent; + var hasUnresolvedAncestor = false; - suspense.effects = []; // invoke @resolve event + while (parent) { + if (parent.pendingBranch) { + // found a pending parent suspense, merge buffered post jobs + // into that parent + parent.effects.push(...effects); + hasUnresolvedAncestor = true; + break; + } - triggerEvent(vnode, 'onResolve'); - }, + parent = parent.parent; + } // no pending parent suspense, flush all jobs - fallback(fallbackVNode) { - if (!suspense.pendingBranch) { - return; - } - var { - vnode, - activeBranch, - parentComponent, - container, - isSVG - } = suspense; // invoke @fallback event + if (!hasUnresolvedAncestor) { + queuePostFlushCb(effects); + } - triggerEvent(vnode, 'onFallback'); - var anchor = next(activeBranch); + suspense.effects = []; // invoke @resolve event - var mountFallback = () => { - if (!suspense.isInFallback) { - return; - } // mount the fallback tree + triggerEvent(vnode, 'onResolve'); + }, + fallback(fallbackVNode) { + if (!suspense.pendingBranch) { + return; + } - patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context - isSVG, slotScopeIds, optimized); - setActiveBranch(suspense, fallbackVNode); - }; + var { + vnode, + activeBranch, + parentComponent, + container, + isSVG + } = suspense; // invoke @fallback event - var delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in'; + triggerEvent(vnode, 'onFallback'); + var anchor = next(activeBranch); - if (delayEnter) { - activeBranch.transition.afterLeave = mountFallback; - } + var mountFallback = () => { + if (!suspense.isInFallback) { + return; + } // mount the fallback tree - suspense.isInFallback = true; // unmount current active branch - unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now - true // shouldRemove - ); + patch(null, fallbackVNode, container, anchor, parentComponent, null, // fallback tree will not have suspense context + isSVG, slotScopeIds, optimized); + setActiveBranch(suspense, fallbackVNode); + }; - if (!delayEnter) { - mountFallback(); - } - }, + var delayEnter = fallbackVNode.transition && fallbackVNode.transition.mode === 'out-in'; - move(container, anchor, type) { - suspense.activeBranch && move(suspense.activeBranch, container, anchor, type); - suspense.container = container; - }, + if (delayEnter) { + activeBranch.transition.afterLeave = mountFallback; + } - next() { - return suspense.activeBranch && next(suspense.activeBranch); - }, + suspense.isInFallback = true; // unmount current active branch - registerDep(instance, setupRenderEffect) { - var isInPendingSuspense = !!suspense.pendingBranch; + unmount(activeBranch, parentComponent, null, // no suspense so unmount hooks fire now + true // shouldRemove + ); - if (isInPendingSuspense) { - suspense.deps++; - } + if (!delayEnter) { + mountFallback(); + } + }, - var 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; - var { - vnode - } = instance; - { - pushWarningContext(vnode); - } - handleSetupResult(instance, asyncSetupResult, false); + move(container, anchor, type) { + suspense.activeBranch && move(suspense.activeBranch, container, anchor, type); + suspense.container = container; + }, - if (hydratedEl) { - // vnode may have been replaced if an update happened before the - // async dep is resolved. - vnode.el = hydratedEl; - } + next() { + return suspense.activeBranch && next(suspense.activeBranch); + }, - var 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); + registerDep(instance, setupRenderEffect) { + var isInPendingSuspense = !!suspense.pendingBranch; - if (placeholder) { - remove(placeholder); - } + if (isInPendingSuspense) { + suspense.deps++; + } - updateHOCHostEl(instance, vnode.el); - { - popWarningContext(); - } // only decrease deps count if suspense is not already resolved + var 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 - 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); - } + instance.asyncResolved = true; + var { + vnode + } = instance; + { + pushWarningContext(vnode); } + handleSetupResult(instance, asyncSetupResult, false); - }; - return suspense; - } - - function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) { - /* eslint-disable no-restricted-globals */ - var 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 - - var 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) { - var { - shapeFlag, - children - } = vnode; - var isSlotChildren = shapeFlag & 32 - /* SLOTS_CHILDREN */ - ; - vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children); - vnode.ssFallback = isSlotChildren ? normalizeSuspenseSlot(children.fallback) : createVNode(Comment); - } - - function normalizeSuspenseSlot(s) { - var block; + if (hydratedEl) { + // vnode may have been replaced if an update happened before the + // async dep is resolved. + vnode.el = hydratedEl; + } - if (shared.isFunction(s)) { - var trackBlock = isBlockTreeEnabled && s._c; + var 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 (trackBlock) { - // disableTracking: false - // allow block tracking for compiled slots - // (see ./componentRenderContext.ts) - s._d = false; - openBlock(); + if (placeholder) { + remove(placeholder); } - s = s(); + updateHOCHostEl(instance, vnode.el); + { + popWarningContext(); + } // only decrease deps count if suspense is not already resolved - if (trackBlock) { - s._d = true; - block = currentBlock; - closeBlock(); + if (isInPendingSuspense && --suspense.deps === 0) { + suspense.resolve(); } - } + }); + }, - if (shared.isArray(s)) { - var singleChild = filterSingleRoot(s); + unmount(parentSuspense, doRemove) { + suspense.isUnmounted = true; - if (!singleChild) { - warn(" slots expect a single root node."); - } + if (suspense.activeBranch) { + unmount(suspense.activeBranch, parentComponent, parentSuspense, doRemove); + } - s = singleChild; + if (suspense.pendingBranch) { + unmount(suspense.pendingBranch, parentComponent, parentSuspense, doRemove); } + } - s = normalizeVNode(s); + }; + return suspense; +} - if (block && !s.dynamicChildren) { - s.dynamicChildren = block.filter(c => c !== s); - } +function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized, rendererInternals, hydrateNode) { + /* eslint-disable no-restricted-globals */ + var 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 + + var result = hydrateNode(node, suspense.pendingBranch = vnode.ssContent, parentComponent, suspense, slotScopeIds, optimized); + + if (suspense.deps === 0) { + suspense.resolve(); + } + + return result; + /* eslint-enable no-restricted-globals */ +} - return s; - } +function normalizeSuspenseChildren(vnode) { + var { + shapeFlag, + children + } = vnode; + var isSlotChildren = shapeFlag & 32 + /* SLOTS_CHILDREN */ + ; + vnode.ssContent = normalizeSuspenseSlot(isSlotChildren ? children.default : children); + vnode.ssFallback = isSlotChildren ? normalizeSuspenseSlot(children.fallback) : createVNode(Comment); +} - function queueEffectWithSuspense(fn, suspense) { - if (suspense && suspense.pendingBranch) { - if (shared.isArray(fn)) { - suspense.effects.push(...fn); - } else { - suspense.effects.push(fn); - } - } else { - queuePostFlushCb(fn); - } - } +function normalizeSuspenseSlot(s) { + var block; - function setActiveBranch(suspense, branch) { - suspense.activeBranch = branch; - var { - vnode, - parentComponent - } = suspense; - var el = vnode.el = branch.el; // in case suspense is the root node of a component, - // recursively update the HOC el + if (isFunction(s)) { + var trackBlock = isBlockTreeEnabled && s._c; - if (parentComponent && parentComponent.subTree === vnode) { - parentComponent.vnode.el = el; - updateHOCHostEl(parentComponent, el); - } + if (trackBlock) { + // disableTracking: false + // allow block tracking for compiled slots + // (see ./componentRenderContext.ts) + s._d = false; + openBlock(); } - function provide(key, value) { - if (!currentInstance) { - { - warn("provide() can only be used inside setup()."); - } - } else { - var 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. - - var parentProvides = currentInstance.parent && currentInstance.parent.provides; + s = s(); - if (parentProvides === provides) { - provides = currentInstance.provides = Object.create(parentProvides); - } // TS doesn't allow symbol as index type + if (trackBlock) { + s._d = true; + block = currentBlock; + closeBlock(); + } + } + if (isArray(s)) { + var singleChild = filterSingleRoot(s); - provides[key] = value; - } + if (!singleChild) { + warn(" slots expect a single root node."); } - function inject(key, defaultValue) { - var treatDefaultAsFactory = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - // fallback to `currentRenderingInstance` so that this can be called in - // a functional component - var instance = currentInstance || currentRenderingInstance; + s = singleChild; + } - if (instance) { - // #2400 - // to support `app.use` plugins, - // fallback to appContext's `provides` if the instance is at root - var provides = instance.parent == null ? instance.vnode.appContext && instance.vnode.appContext.provides : instance.parent.provides; + s = normalizeVNode(s); - if (provides && key in provides) { - // TS doesn't allow symbol as index type - return provides[key]; - } else if (arguments.length > 1) { - return treatDefaultAsFactory && shared.isFunction(defaultValue) ? defaultValue.call(instance.proxy) : defaultValue; - } else { - warn("injection \"".concat(String(key), "\" not found.")); - } - } else { - warn("inject() can only be used inside setup() or functional components."); - } - } // Simple effect. + if (block && !s.dynamicChildren) { + s.dynamicChildren = block.filter(c => c !== s); + } + return s; +} - function watchEffect(effect, options) { - return doWatch(effect, null, options); +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; + var { + vnode, + parentComponent + } = suspense; + var 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 watchPostEffect(effect, options) { - return doWatch(effect, null, Object.assign(options || {}, { - flush: 'post' - })); +function provide(key, value) { + if (!currentInstance) { + { + warn("provide() can only be used inside setup()."); } + } else { + var 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. - function watchSyncEffect(effect, options) { - return doWatch(effect, null, Object.assign(options || {}, { - flush: 'sync' - })); - } // initial value for watchers to trigger on undefined initial values + var parentProvides = currentInstance.parent && currentInstance.parent.provides; + if (parentProvides === provides) { + provides = currentInstance.provides = Object.create(parentProvides); + } // TS doesn't allow symbol as index type - var INITIAL_WATCHER_VALUE = {}; // implementation - function watch(source, cb, options) { - if (!shared.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."); - } + provides[key] = value; + } +} - return doWatch(source, cb, options); - } +function inject(key, defaultValue) { + var treatDefaultAsFactory = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + // fallback to `currentRenderingInstance` so that this can be called in + // a functional component + var instance = currentInstance || currentRenderingInstance; + + if (instance) { + // #2400 + // to support `app.use` plugins, + // fallback to appContext's `provides` if the instance is at root + var 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.call(instance.proxy) : defaultValue; + } else { + warn("injection \"".concat(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); +} - function doWatch(source, cb) { - var { - immediate, - deep, - flush, - onTrack, - onTrigger - } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : shared.EMPTY_OBJ; +function watchPostEffect(effect, options) { + return doWatch(effect, null, Object.assign(options || {}, { + flush: 'post' + })); +} - if (!cb) { - if (immediate !== undefined) { - warn("watch() \"immediate\" option is only respected when using the " + "watch(source, callback, options?) signature."); - } +function watchSyncEffect(effect, options) { + return doWatch(effect, null, Object.assign(options || {}, { + flush: 'sync' + })); +} // initial value for watchers to trigger on undefined initial values - if (deep !== undefined) { - warn("watch() \"deep\" option is only respected when using the " + "watch(source, callback, options?) signature."); - } - } - var 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."); - }; +var INITIAL_WATCHER_VALUE = {}; // implementation - var instance = currentInstance; - var getter; - var forceTrigger = false; - var isMultiSource = false; - - if (reactivity.isRef(source)) { - getter = () => source.value; - - forceTrigger = reactivity.isShallow(source); - } else if (reactivity.isReactive(source)) { - getter = () => source; - - deep = true; - } else if (shared.isArray(source)) { - isMultiSource = true; - forceTrigger = source.some(reactivity.isReactive); - - getter = () => source.map(s => { - if (reactivity.isRef(s)) { - return s.value; - } else if (reactivity.isReactive(s)) { - return traverse(s); - } else if (shared.isFunction(s)) { - return callWithErrorHandling(s, instance, 2 - /* WATCH_GETTER */ - ); - } else { - warnInvalidSource(s); - } - }); - } else if (shared.isFunction(source)) { - if (cb) { - // getter with cb - getter = () => callWithErrorHandling(source, instance, 2 - /* WATCH_GETTER */ - ); - } else { - // no cb -> simple effect - getter = () => { - if (instance && instance.isUnmounted) { - return; - } +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."); + } - if (cleanup) { - cleanup(); - } + return doWatch(source, cb, options); +} - return callWithAsyncErrorHandling(source, instance, 3 - /* WATCH_CALLBACK */ - , [onCleanup]); - }; - } +function doWatch(source, cb) { + var { + immediate, + deep, + flush, + onTrack, + onTrigger + } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EMPTY_OBJ; + + 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."); + } + } + + var 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."); + }; + + var instance = currentInstance; + var getter; + var forceTrigger = false; + var isMultiSource = false; + + if (isRef(source)) { + getter = () => source.value; + + forceTrigger = isShallow$1(source); + } 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 */ + ); } else { - getter = shared.NOOP; - warnInvalidSource(source); + warnInvalidSource(s); } + }); + } else if (isFunction(source)) { + if (cb) { + // getter with cb + getter = () => callWithErrorHandling(source, instance, 2 + /* WATCH_GETTER */ + ); + } else { + // no cb -> simple effect + getter = () => { + if (instance && instance.isUnmounted) { + return; + } - if (cb && deep) { - var baseGetter = getter; - - getter = () => traverse(baseGetter()); - } + if (cleanup) { + cleanup(); + } - var cleanup; + return callWithAsyncErrorHandling(source, instance, 3 + /* WATCH_CALLBACK */ + , [onCleanup]); + }; + } + } else { + getter = NOOP; + warnInvalidSource(source); + } - var onCleanup = fn => { - cleanup = effect.onStop = () => { - callWithErrorHandling(fn, instance, 4 - /* WATCH_CLEANUP */ - ); - }; - }; // in SSR there is no need to setup an actual effect, and it should be noop - // unless it's eager + if (cb && deep) { + var baseGetter = getter; + getter = () => traverse(baseGetter()); + } - if (isInSSRComponentSetup) { - // we will also not call the invalidate callback (+ runner is not set up) - onCleanup = shared.NOOP; + var cleanup; - if (!cb) { - getter(); - } else if (immediate) { - callWithAsyncErrorHandling(cb, instance, 3 - /* WATCH_CALLBACK */ - , [getter(), isMultiSource ? [] : undefined, onCleanup]); - } + var onCleanup = fn => { + cleanup = effect.onStop = () => { + callWithErrorHandling(fn, instance, 4 + /* WATCH_CLEANUP */ + ); + }; + }; // in SSR there is no need to setup an actual effect, and it should be noop + // unless it's eager - return shared.NOOP; - } - var oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE; + if (isInSSRComponentSetup) { + // we will also not call the invalidate callback (+ runner is not set up) + onCleanup = NOOP; - var job = () => { - if (!effect.active) { - return; - } + if (!cb) { + getter(); + } else if (immediate) { + callWithAsyncErrorHandling(cb, instance, 3 + /* WATCH_CALLBACK */ + , [getter(), isMultiSource ? [] : undefined, onCleanup]); + } - if (cb) { - // watch(source, cb) - var newValue = effect.run(); + return NOOP; + } - if (deep || forceTrigger || (isMultiSource ? newValue.some((v, i) => shared.hasChanged(v, oldValue[i])) : shared.hasChanged(newValue, oldValue)) || false) { - // cleanup before running cb again - if (cleanup) { - cleanup(); - } + var oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE; - 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, onCleanup]); - oldValue = newValue; - } - } else { - // watchEffect - effect.run(); - } - }; // important: mark the job as a watcher callback so that scheduler knows - // it is allowed to self-trigger (#1727) + var job = () => { + if (!effect.active) { + return; + } + if (cb) { + // watch(source, cb) + var newValue = effect.run(); - job.allowRecurse = !!cb; - var scheduler; + if (deep || forceTrigger || (isMultiSource ? newValue.some((v, i) => hasChanged(v, oldValue[i])) : hasChanged(newValue, oldValue)) || false) { + // cleanup before running cb again + if (cleanup) { + cleanup(); + } - if (flush === 'sync') { - scheduler = job; // the scheduler function gets called directly - } 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(); - } - }; + 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, onCleanup]); + oldValue = newValue; } + } else { + // watchEffect + effect.run(); + } + }; // important: mark the job as a watcher callback so that scheduler knows + // it is allowed to self-trigger (#1727) - var effect = new reactivity.ReactiveEffect(getter, scheduler); - { - effect.onTrack = onTrack; - effect.onTrigger = onTrigger; - } // initial run - if (cb) { - if (immediate) { - job(); - } else { - oldValue = effect.run(); - } - } else if (flush === 'post') { - queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense); + job.allowRecurse = !!cb; + var scheduler; + + if (flush === 'sync') { + scheduler = job; // the scheduler function gets called directly + } else if (flush === 'post') { + scheduler = () => queuePostRenderEffect(job, instance && instance.suspense); + } else { + // default: 'pre' + scheduler = () => { + if (!instance || instance.isMounted) { + queuePreFlushCb(job); } else { - effect.run(); + // with 'pre' option, the first call must happen before + // the component is mounted so it is called synchronously. + job(); } + }; + } + + var effect = new ReactiveEffect(getter, scheduler); + { + effect.onTrack = onTrack; + effect.onTrigger = onTrigger; + } // initial run + + if (cb) { + if (immediate) { + job(); + } else { + oldValue = effect.run(); + } + } else if (flush === 'post') { + queuePostRenderEffect(effect.run.bind(effect), instance && instance.suspense); + } else { + effect.run(); + } + + return () => { + effect.stop(); + + if (instance && instance.scope) { + remove(instance.scope.effects, effect); + } + }; +} // this.$watch + + +function instanceWatch(source, value, options) { + var publicThis = this.proxy; + var getter = isString(source) ? source.includes('.') ? createPathGetter(publicThis, source) : () => publicThis[source] : source.bind(publicThis, publicThis); + var cb; + + if (isFunction(value)) { + cb = value; + } else { + cb = value.handler; + options = value; + } + + var cur = currentInstance; + setCurrentInstance(this); + var res = doWatch(getter, cb.bind(publicThis), options); + + if (cur) { + setCurrentInstance(cur); + } else { + unsetCurrentInstance(); + } + + return res; +} - return () => { - effect.stop(); +function createPathGetter(ctx, path) { + var segments = path.split('.'); + return () => { + var cur = ctx; - if (instance && instance.scope) { - shared.remove(instance.scope.effects, effect); - } - }; - } // this.$watch + for (var i = 0; i < segments.length && cur; i++) { + cur = cur[segments[i]]; + } + return cur; + }; +} - function instanceWatch(source, value, options) { - var publicThis = this.proxy; - var getter = shared.isString(source) ? source.includes('.') ? createPathGetter(publicThis, source) : () => publicThis[source] : source.bind(publicThis, publicThis); - var cb; +function traverse(value, seen) { + if (!isObject(value) || value["__v_skip" + /* SKIP */ + ]) { + return value; + } - if (shared.isFunction(value)) { - cb = value; - } else { - cb = value.handler; - options = value; - } + seen = seen || new Set(); - var cur = currentInstance; - setCurrentInstance(this); - var res = doWatch(getter, cb.bind(publicThis), options); + if (seen.has(value)) { + return value; + } - if (cur) { - setCurrentInstance(cur); - } else { - unsetCurrentInstance(); - } + seen.add(value); - return res; + if (isRef(value)) { + traverse(value.value, seen); + } else if (isArray(value)) { + for (var 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 (var key in value) { + traverse(value[key], seen); + } + } - function createPathGetter(ctx, path) { - var segments = path.split('.'); - return () => { - var cur = ctx; - - for (var i = 0; i < segments.length && cur; i++) { - cur = cur[segments[i]]; - } + return value; +} - return cur; - }; - } +function useTransitionState() { + var state = { + isMounted: false, + isLeaving: false, + isUnmounting: false, + leavingVNodes: new Map() + }; + onMounted(() => { + state.isMounted = true; + }); + onBeforeUnmount(() => { + state.isUnmounting = true; + }); + return state; +} - function traverse(value, seen) { - if (!shared.isObject(value) || value["__v_skip" - /* SKIP */ - ]) { - return value; - } +var TransitionHookValidator = [Function, Array]; +var 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, _ref6) { + var { + slots + } = _ref6; + var instance = getCurrentInstance(); + var state = useTransitionState(); + var prevTransitionKey; + return () => { + var children = slots.default && getTransitionRawChildren(slots.default(), true); + + if (!children || !children.length) { + return; + } // warn multiple elements - seen = seen || new Set(); - if (seen.has(value)) { - return value; - } + 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 - seen.add(value); - if (reactivity.isRef(value)) { - traverse(value.value, seen); - } else if (shared.isArray(value)) { - for (var i = 0; i < value.length; i++) { - traverse(value[i], seen); - } - } else if (shared.isSet(value) || shared.isMap(value)) { - value.forEach(v => { - traverse(v, seen); - }); - } else if (shared.isPlainObject(value)) { - for (var key in value) { - traverse(value[key], seen); - } - } + var rawProps = toRaw(props); + var { + mode + } = rawProps; // check mode - return value; - } + if (mode && mode !== 'in-out' && mode !== 'out-in' && mode !== 'default') { + warn("invalid mode: ".concat(mode)); + } // at this point children has a guaranteed length of 1. - function useTransitionState() { - var state = { - isMounted: false, - isLeaving: false, - isUnmounting: false, - leavingVNodes: new Map() - }; - onMounted(() => { - state.isMounted = true; - }); - onBeforeUnmount(() => { - state.isUnmounting = true; - }); - return state; - } - - var TransitionHookValidator = [Function, Array]; - var 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, _ref6) { - var { - slots - } = _ref6; - var instance = getCurrentInstance(); - var state = useTransitionState(); - var prevTransitionKey; - return () => { - var children = slots.default && getTransitionRawChildren(slots.default(), true); - - if (!children || !children.length) { - return; - } // warn multiple elements + var child = children[0]; + if (state.isLeaving) { + return emptyPlaceholder(child); + } // in the case of , we need to + // compare the type of the kept-alive children. - 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 + var innerChild = getKeepAliveChild(child); - var rawProps = reactivity.toRaw(props); - var { - mode - } = rawProps; // check mode + if (!innerChild) { + return emptyPlaceholder(child); + } - if (mode && mode !== 'in-out' && mode !== 'out-in' && mode !== 'default') { - warn("invalid mode: ".concat(mode)); - } // at this point children has a guaranteed length of 1. + var enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance); + setTransitionHooks(innerChild, enterHooks); + var oldChild = instance.subTree; + var oldInnerChild = oldChild && getKeepAliveChild(oldChild); + var transitionKeyChanged = false; + var { + getTransitionKey + } = innerChild.type; + if (getTransitionKey) { + var key = getTransitionKey(); - var child = children[0]; + if (prevTransitionKey === undefined) { + prevTransitionKey = key; + } else if (key !== prevTransitionKey) { + prevTransitionKey = key; + transitionKeyChanged = true; + } + } // handle mode - if (state.isLeaving) { - return emptyPlaceholder(child); - } // in the case of , we need to - // compare the type of the kept-alive children. + if (oldInnerChild && oldInnerChild.type !== Comment && (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) { + var leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); // update old tree's hooks in case of dynamic transition - var innerChild = getKeepAliveChild(child); + setTransitionHooks(oldInnerChild, leavingHooks); // switching between different views - if (!innerChild) { - return emptyPlaceholder(child); - } + if (mode === 'out-in') { + state.isLeaving = true; // return placeholder node and queue update when leave finishes - var enterHooks = resolveTransitionHooks(innerChild, rawProps, state, instance); - setTransitionHooks(innerChild, enterHooks); - var oldChild = instance.subTree; - var oldInnerChild = oldChild && getKeepAliveChild(oldChild); - var transitionKeyChanged = false; - var { - getTransitionKey - } = innerChild.type; - - if (getTransitionKey) { - var key = getTransitionKey(); - - if (prevTransitionKey === undefined) { - prevTransitionKey = key; - } else if (key !== prevTransitionKey) { - prevTransitionKey = key; - transitionKeyChanged = true; - } - } // handle mode + leavingHooks.afterLeave = () => { + state.isLeaving = false; + instance.update(); + }; + return emptyPlaceholder(child); + } else if (mode === 'in-out' && innerChild.type !== Comment) { + leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { + var leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); + leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; // early removal callback - if (oldInnerChild && oldInnerChild.type !== Comment && (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) { - var leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); // update old tree's hooks in case of dynamic transition + el._leaveCb = () => { + earlyRemove(); + el._leaveCb = undefined; + delete enterHooks.delayedLeave; + }; - setTransitionHooks(oldInnerChild, leavingHooks); // switching between different views + enterHooks.delayedLeave = delayedLeave; + }; + } + } - if (mode === 'out-in') { - state.isLeaving = true; // return placeholder node and queue update when leave finishes + return child; + }; + } + +}; // export the public type for h/tsx inference +// also to avoid inline import() in generated d.ts files + +var BaseTransition = BaseTransitionImpl; + +function getLeavingNodesForType(state, vnode) { + var { + leavingVNodes + } = state; + var 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) { + var { + appear, + mode, + persisted = false, + onBeforeEnter, + onEnter, + onAfterEnter, + onEnterCancelled, + onBeforeLeave, + onLeave, + onAfterLeave, + onLeaveCancelled, + onBeforeAppear, + onAppear, + onAfterAppear, + onAppearCancelled + } = props; + var key = String(vnode.key); + var leavingVNodesCache = getLeavingNodesForType(state, vnode); + + var callHook = (hook, args) => { + hook && callWithAsyncErrorHandling(hook, instance, 9 + /* TRANSITION_HOOK */ + , args); + }; + + var hooks = { + mode, + persisted, + + beforeEnter(el) { + var hook = onBeforeEnter; + + if (!state.isMounted) { + if (appear) { + hook = onBeforeAppear || onBeforeEnter; + } else { + return; + } + } // for same element (v-show) - leavingHooks.afterLeave = () => { - state.isLeaving = false; - instance.update(); - }; - return emptyPlaceholder(child); - } else if (mode === 'in-out' && innerChild.type !== Comment) { - leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { - var leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); - leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; // early removal callback + if (el._leaveCb) { + el._leaveCb(true + /* cancelled */ + ); + } // for toggled element with same key (v-if) - el._leaveCb = () => { - earlyRemove(); - el._leaveCb = undefined; - delete enterHooks.delayedLeave; - }; - enterHooks.delayedLeave = delayedLeave; - }; - } - } + var leavingVNode = leavingVNodesCache[key]; - return child; - }; + if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el._leaveCb) { + // force early removal (not cancelled) + leavingVNode.el._leaveCb(); } - }; // export the public type for h/tsx inference - // also to avoid inline import() in generated d.ts files - - var BaseTransition = BaseTransitionImpl; + callHook(hook, [el]); + }, - function getLeavingNodesForType(state, vnode) { - var { - leavingVNodes - } = state; - var leavingVNodesCache = leavingVNodes.get(vnode.type); + enter(el) { + var hook = onEnter; + var afterHook = onAfterEnter; + var cancelHook = onEnterCancelled; - if (!leavingVNodesCache) { - leavingVNodesCache = Object.create(null); - leavingVNodes.set(vnode.type, leavingVNodesCache); + if (!state.isMounted) { + if (appear) { + hook = onAppear || onEnter; + afterHook = onAfterAppear || onAfterEnter; + cancelHook = onAppearCancelled || onEnterCancelled; + } else { + return; + } } - return leavingVNodesCache; - } // The transition hooks are attached to the vnode as vnode.transition - // and will be called at appropriate timing in the renderer. + var called = false; + var done = el._enterCb = cancelled => { + if (called) return; + called = true; - function resolveTransitionHooks(vnode, props, state, instance) { - var { - appear, - mode, - persisted = false, - onBeforeEnter, - onEnter, - onAfterEnter, - onEnterCancelled, - onBeforeLeave, - onLeave, - onAfterLeave, - onLeaveCancelled, - onBeforeAppear, - onAppear, - onAfterAppear, - onAppearCancelled - } = props; - var key = String(vnode.key); - var leavingVNodesCache = getLeavingNodesForType(state, vnode); + if (cancelled) { + callHook(cancelHook, [el]); + } else { + callHook(afterHook, [el]); + } - var callHook = (hook, args) => { - hook && callWithAsyncErrorHandling(hook, instance, 9 - /* TRANSITION_HOOK */ - , args); - }; + if (hooks.delayedLeave) { + hooks.delayedLeave(); + } - var hooks = { - mode, - persisted, + el._enterCb = undefined; + }; - beforeEnter(el) { - var hook = onBeforeEnter; + if (hook) { + hook(el, done); - if (!state.isMounted) { - if (appear) { - hook = onBeforeAppear || onBeforeEnter; - } else { - return; - } - } // for same element (v-show) + if (hook.length <= 1) { + done(); + } + } else { + done(); + } + }, + leave(el, remove) { + var key = String(vnode.key); - if (el._leaveCb) { - el._leaveCb(true - /* cancelled */ - ); - } // for toggled element with same key (v-if) + if (el._enterCb) { + el._enterCb(true + /* cancelled */ + ); + } + if (state.isUnmounting) { + return remove(); + } - var leavingVNode = leavingVNodesCache[key]; + callHook(onBeforeLeave, [el]); + var called = false; - if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el._leaveCb) { - // force early removal (not cancelled) - leavingVNode.el._leaveCb(); - } + var done = el._leaveCb = cancelled => { + if (called) return; + called = true; + remove(); - callHook(hook, [el]); - }, + if (cancelled) { + callHook(onLeaveCancelled, [el]); + } else { + callHook(onAfterLeave, [el]); + } - enter(el) { - var hook = onEnter; - var afterHook = onAfterEnter; - var cancelHook = onEnterCancelled; + el._leaveCb = undefined; - if (!state.isMounted) { - if (appear) { - hook = onAppear || onEnter; - afterHook = onAfterAppear || onAfterEnter; - cancelHook = onAppearCancelled || onEnterCancelled; - } else { - return; - } - } + if (leavingVNodesCache[key] === vnode) { + delete leavingVNodesCache[key]; + } + }; - var called = false; + leavingVNodesCache[key] = vnode; - var done = el._enterCb = cancelled => { - if (called) return; - called = true; + if (onLeave) { + onLeave(el, done); - if (cancelled) { - callHook(cancelHook, [el]); - } else { - callHook(afterHook, [el]); - } + if (onLeave.length <= 1) { + done(); + } + } else { + done(); + } + }, - if (hooks.delayedLeave) { - hooks.delayedLeave(); - } + clone(vnode) { + return resolveTransitionHooks(vnode, props, state, instance); + } - el._enterCb = undefined; - }; + }; + 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. - if (hook) { - hook(el, done); - if (hook.length <= 1) { - done(); - } - } else { - done(); - } - }, +function emptyPlaceholder(vnode) { + if (isKeepAlive(vnode)) { + vnode = cloneVNode(vnode); + vnode.children = null; + return vnode; + } +} - leave(el, remove) { - var key = String(vnode.key); +function getKeepAliveChild(vnode) { + return isKeepAlive(vnode) ? vnode.children ? vnode.children[0] : undefined : vnode; +} - if (el._enterCb) { - el._enterCb(true - /* cancelled */ - ); - } +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; + } +} - if (state.isUnmounting) { - return remove(); - } +function getTransitionRawChildren(children) { + var keepComment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var ret = []; + var keyedFragmentCount = 0; - callHook(onBeforeLeave, [el]); - var called = false; + for (var i = 0; i < children.length; i++) { + var child = children[i]; // handle fragment children case, e.g. v-for - var done = el._leaveCb = cancelled => { - if (called) return; - called = true; - remove(); + 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 (cancelled) { - callHook(onLeaveCancelled, [el]); - } else { - callHook(onAfterLeave, [el]); - } - el._leaveCb = undefined; + if (keyedFragmentCount > 1) { + for (var _i = 0; _i < ret.length; _i++) { + ret[_i].patchFlag = -2 + /* BAIL */ + ; + } + } - if (leavingVNodesCache[key] === vnode) { - delete leavingVNodesCache[key]; - } - }; + return ret; +} // implementation, close to no-op - leavingVNodesCache[key] = vnode; - if (onLeave) { - onLeave(el, done); +function defineComponent(options) { + return isFunction(options) ? { + setup: options, + name: options.name + } : options; +} - if (onLeave.length <= 1) { - done(); - } - } else { - done(); - } - }, +var isAsyncWrapper = i => !!i.type.__asyncLoader; - clone(vnode) { - return resolveTransitionHooks(vnode, props, state, instance); - } +function defineAsyncComponent(source) { + if (isFunction(source)) { + source = { + loader: source + }; + } + + var { + loader, + loadingComponent, + errorComponent, + delay = 200, + timeout, + // undefined = never times out + suspensible = true, + onError: userOnError + } = source; + var pendingRequest = null; + var resolvedComp; + var retries = 0; + + var retry = () => { + retries++; + pendingRequest = null; + return load(); + }; + + var load = () => { + var thisRequest; + return pendingRequest || (thisRequest = pendingRequest = loader().catch(err => { + err = err instanceof Error ? err : new Error(String(err)); + + if (userOnError) { + return new Promise((resolve, reject) => { + var userRetry = () => resolve(retry()); + + var userFail = () => reject(err); + + userOnError(err, userRetry, userFail, retries + 1); + }); + } else { + throw err; + } + }).then(comp => { + if (thisRequest !== pendingRequest && pendingRequest) { + return pendingRequest; + } - }; - 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. + if (!comp) { + warn("Async component loader resolved to undefined. " + "If you are using retry(), make sure to return its return value."); + } // interop module default - function emptyPlaceholder(vnode) { - if (isKeepAlive(vnode)) { - vnode = cloneVNode(vnode); - vnode.children = null; - return vnode; + if (comp && (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) { + comp = comp.default; } - } - - 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; + if (comp && !isObject(comp) && !isFunction(comp)) { + throw new Error("Invalid async component load result: ".concat(comp)); } - } - function getTransitionRawChildren(children) { - var keepComment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var ret = []; - var keyedFragmentCount = 0; + resolvedComp = comp; + return comp; + })); + }; - for (var i = 0; i < children.length; i++) { - var 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 (var _i = 0; _i < ret.length; _i++) { - ret[_i].patchFlag = -2 - /* BAIL */ - ; - } - } + return defineComponent({ + name: 'AsyncComponentWrapper', + __asyncLoader: load, - return ret; - } // implementation, close to no-op + get __asyncResolved() { + return resolvedComp; + }, + setup() { + var instance = currentInstance; // already resolved - function defineComponent(options) { - return shared.isFunction(options) ? { - setup: options, - name: options.name - } : options; - } - - var isAsyncWrapper = i => !!i.type.__asyncLoader; - - function defineAsyncComponent(source) { - if (shared.isFunction(source)) { - source = { - loader: source - }; + if (resolvedComp) { + return () => createInnerComp(resolvedComp, instance); } - var { - loader, - loadingComponent, - errorComponent, - delay = 200, - timeout, - // undefined = never times out - suspensible = true, - onError: userOnError - } = source; - var pendingRequest = null; - var resolvedComp; - var retries = 0; - - var retry = () => { - retries++; + var onError = err => { pendingRequest = null; - return load(); - }; - - var load = () => { - var thisRequest; - return pendingRequest || (thisRequest = pendingRequest = loader().catch(err => { - err = err instanceof Error ? err : new Error(String(err)); - - if (userOnError) { - return new Promise((resolve, reject) => { - var userRetry = () => resolve(retry()); + handleError(err, instance, 13 + /* ASYNC_COMPONENT_LOADER */ + , !errorComponent + /* do not throw in dev if user provided error component */ + ); + }; // suspense-controlled or SSR. - var userFail = () => reject(err); - userOnError(err, userRetry, userFail, retries + 1); - }); - } else { - throw err; - } - }).then(comp => { - if (thisRequest !== pendingRequest && pendingRequest) { - return pendingRequest; - } + if (suspensible && instance.suspense || isInSSRComponentSetup) { + return load().then(comp => { + return () => createInnerComp(comp, instance); + }).catch(err => { + onError(err); + return () => errorComponent ? createVNode(errorComponent, { + error: err + }) : null; + }); + } - if (!comp) { - warn("Async component loader resolved to undefined. " + "If you are using retry(), make sure to return its return value."); - } // interop module default + var loaded = ref(false); + var error = ref(); + var delayed = ref(!!delay); + if (delay) { + setTimeout(() => { + delayed.value = false; + }, delay); + } - if (comp && (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) { - comp = comp.default; + if (timeout != null) { + setTimeout(() => { + if (!loaded.value && !error.value) { + var err = new Error("Async component timed out after ".concat(timeout, "ms.")); + onError(err); + error.value = err; } + }, timeout); + } - if (comp && !shared.isObject(comp) && !shared.isFunction(comp)) { - throw new Error("Invalid async component load result: ".concat(comp)); - } + load().then(() => { + loaded.value = true; - resolvedComp = comp; - return comp; - })); + if (instance.parent && isKeepAlive(instance.parent.vnode)) { + // parent is keep-alive, force update so the loaded component's + // name is taken into account + queueJob(instance.parent.update); + } + }).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); + } }; + } - return defineComponent({ - name: 'AsyncComponentWrapper', - __asyncLoader: load, - - get __asyncResolved() { - return resolvedComp; - }, - - setup() { - var instance = currentInstance; // already resolved - - if (resolvedComp) { - return () => createInnerComp(resolvedComp, instance); - } + }); +} - var 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 || isInSSRComponentSetup) { - return load().then(comp => { - return () => createInnerComp(comp, instance); - }).catch(err => { - onError(err); - return () => errorComponent ? createVNode(errorComponent, { - error: err - }) : null; - }); - } +function createInnerComp(comp, _ref7) { + var { + vnode: { + ref, + props, + children + } + } = _ref7; + var vnode = createVNode(comp, props, children); // ensure inner component inherits the async wrapper's ref owner - var loaded = reactivity.ref(false); - var error = reactivity.ref(); - var delayed = reactivity.ref(!!delay); + vnode.ref = ref; + return vnode; +} - if (delay) { - setTimeout(() => { - delayed.value = false; - }, delay); - } +var isKeepAlive = vnode => vnode.type.__isKeepAlive; + +var 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] + }, + + setup(props, _ref8) { + var { + slots + } = _ref8; + var 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. + + var 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; + } + + var cache = new Map(); + var keys = new Set(); + var current = null; + { + instance.__v_cache = cache; + } + var parentSuspense = instance.suspense; + var { + renderer: { + p: patch, + m: move, + um: _unmount, + o: { + createElement + } + } + } = sharedContext; + var storageContainer = createElement('div'); - if (timeout != null) { - setTimeout(() => { - if (!loaded.value && !error.value) { - var err = new Error("Async component timed out after ".concat(timeout, "ms.")); - onError(err); - error.value = err; - } - }, timeout); - } + sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { + var instance = vnode.component; + move(vnode, container, anchor, 0 + /* ENTER */ + , parentSuspense); // in case props have changed - load().then(() => { - loaded.value = true; + patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized); + queuePostRenderEffect(() => { + instance.isDeactivated = false; - if (instance.parent && isKeepAlive(instance.parent.vnode)) { - // parent is keep-alive, force update so the loaded component's - // name is taken into account - queueJob(instance.parent.update); - } - }).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); - } - }; + if (instance.a) { + invokeArrayFns(instance.a); } - }); - } + var vnodeHook = vnode.props && vnode.props.onVnodeMounted; - function createInnerComp(comp, _ref7) { - var { - vnode: { - ref, - props, - children - } - } = _ref7; - var vnode = createVNode(comp, props, children); // ensure inner component inherits the async wrapper's ref owner - - vnode.ref = ref; - return vnode; - } - - var isKeepAlive = vnode => vnode.type.__isKeepAlive; - - var 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] - }, + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance.parent, vnode); + } + }, parentSuspense); + { + // Update components tree + devtoolsComponentAdded(instance); + } + }; - setup(props, _ref8) { - var { - slots - } = _ref8; - var 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. + sharedContext.deactivate = vnode => { + var instance = vnode.component; + move(vnode, storageContainer, null, 1 + /* LEAVE */ + , parentSuspense); + queuePostRenderEffect(() => { + if (instance.da) { + invokeArrayFns(instance.da); + } - var 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 + var vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; - if (!sharedContext.renderer) { - return slots.default; + if (vnodeHook) { + invokeVNodeHook(vnodeHook, instance.parent, vnode); } - var cache = new Map(); - var keys = new Set(); - var current = null; - { - instance.__v_cache = cache; - } - var parentSuspense = instance.suspense; - var { - renderer: { - p: patch, - m: move, - um: _unmount, - o: { - createElement - } - } - } = sharedContext; - var storageContainer = createElement('div'); + instance.isDeactivated = true; + }, parentSuspense); + { + // Update components tree + devtoolsComponentAdded(instance); + } + }; - sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { - var instance = vnode.component; - move(vnode, container, anchor, 0 - /* ENTER */ - , parentSuspense); // in case props have changed + function unmount(vnode) { + // reset the shapeFlag so it can be properly unmounted + resetShapeFlag(vnode); - patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, vnode.slotScopeIds, optimized); - queuePostRenderEffect(() => { - instance.isDeactivated = false; + _unmount(vnode, instance, parentSuspense, true); + } - if (instance.a) { - shared.invokeArrayFns(instance.a); - } + function pruneCache(filter) { + cache.forEach((vnode, key) => { + var name = getComponentName(vnode.type); - var vnodeHook = vnode.props && vnode.props.onVnodeMounted; + if (name && (!filter || !filter(name))) { + pruneCacheEntry(key); + } + }); + } - if (vnodeHook) { - invokeVNodeHook(vnodeHook, instance.parent, vnode); - } - }, parentSuspense); - { - // Update components tree - devtoolsComponentAdded(instance); - } - }; + function pruneCacheEntry(key) { + var cached = cache.get(key); - sharedContext.deactivate = vnode => { - var instance = vnode.component; - move(vnode, storageContainer, null, 1 - /* LEAVE */ - , parentSuspense); - queuePostRenderEffect(() => { - if (instance.da) { - shared.invokeArrayFns(instance.da); - } + if (!current || cached.type !== current.type) { + 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); + } - var vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; + cache.delete(key); + keys.delete(key); + } // prune cache on include/exclude prop change - if (vnodeHook) { - invokeVNodeHook(vnodeHook, instance.parent, vnode); - } - instance.isDeactivated = true; - }, parentSuspense); - { - // Update components tree - devtoolsComponentAdded(instance); - } - }; + watch(() => [props.include, props.exclude], _ref9 => { + var [include, exclude] = _ref9; + 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 - function unmount(vnode) { - // reset the shapeFlag so it can be properly unmounted - resetShapeFlag(vnode); + var pendingCacheKey = null; - _unmount(vnode, instance, parentSuspense, true); - } + var 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 => { + var { + subTree, + suspense + } = instance; + var vnode = getInnerChild(subTree); - function pruneCache(filter) { - cache.forEach((vnode, key) => { - var name = getComponentName(vnode.type); + if (cached.type === vnode.type) { + // current instance will be unmounted as part of keep-alive's unmount + resetShapeFlag(vnode); // but invoke its deactivated hook here - if (name && (!filter || !filter(name))) { - pruneCacheEntry(key); - } - }); + var da = vnode.component.da; + da && queuePostRenderEffect(da, suspense); + return; } - function pruneCacheEntry(key) { - var cached = cache.get(key); - - if (!current || cached.type !== current.type) { - 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); - } + unmount(cached); + }); + }); + return () => { + pendingCacheKey = null; - cache.delete(key); - keys.delete(key); - } // prune cache on include/exclude prop change + if (!slots.default) { + return null; + } + var children = slots.default(); + var rawVNode = children[0]; - watch(() => [props.include, props.exclude], _ref9 => { - var [include, exclude] = _ref9; - include && pruneCache(name => matches(include, name)); - exclude && pruneCache(name => !matches(exclude, name)); - }, // prune post-render after `current` has been updated + if (children.length > 1) { { - flush: 'post', - deep: true - }); // cache sub tree after render + warn("KeepAlive should contain exactly one component child."); + } + current = null; + return children; + } else if (!isVNode(rawVNode) || !(rawVNode.shapeFlag & 4 + /* STATEFUL_COMPONENT */ + ) && !(rawVNode.shapeFlag & 128 + /* SUSPENSE */ + )) { + current = null; + return rawVNode; + } - var pendingCacheKey = null; + var vnode = getInnerChild(rawVNode); + var comp = vnode.type; // for async components, name check should be based in its loaded + // inner component if available - var cacheSubtree = () => { - // fix #1621, the pendingCacheKey could be 0 - if (pendingCacheKey != null) { - cache.set(pendingCacheKey, getInnerChild(instance.subTree)); - } - }; + var name = getComponentName(isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp); + var { + include, + exclude, + max + } = props; - onMounted(cacheSubtree); - onUpdated(cacheSubtree); - onBeforeUnmount(() => { - cache.forEach(cached => { - var { - subTree, - suspense - } = instance; - var vnode = getInnerChild(subTree); - - if (cached.type === vnode.type) { - // current instance will be unmounted as part of keep-alive's unmount - resetShapeFlag(vnode); // but invoke its deactivated hook here - - var da = vnode.component.da; - da && queuePostRenderEffect(da, suspense); - return; - } + if (include && (!name || !matches(include, name)) || exclude && name && matches(exclude, name)) { + current = vnode; + return rawVNode; + } - unmount(cached); - }); - }); - return () => { - pendingCacheKey = null; + var key = vnode.key == null ? comp : vnode.key; + var cachedVNode = cache.get(key); // clone vnode if it's reused because we are going to mutate it - if (!slots.default) { - return null; - } + if (vnode.el) { + vnode = cloneVNode(vnode); - var children = slots.default(); - var rawVNode = children[0]; + if (rawVNode.shapeFlag & 128 + /* SUSPENSE */ + ) { + 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. - 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 */ - ) && !(rawVNode.shapeFlag & 128 - /* SUSPENSE */ - )) { - current = null; - return rawVNode; - } - var vnode = getInnerChild(rawVNode); - var comp = vnode.type; // for async components, name check should be based in its loaded - // inner component if available + pendingCacheKey = key; - var name = getComponentName(isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp); - var { - include, - exclude, - max - } = props; + if (cachedVNode) { + // copy over mounted state + vnode.el = cachedVNode.el; + vnode.component = cachedVNode.component; - if (include && (!name || !matches(include, name)) || exclude && name && matches(exclude, name)) { - current = vnode; - return rawVNode; - } + if (vnode.transition) { + // recursively update transition hooks on subTree + setTransitionHooks(vnode, vnode.transition); + } // avoid vnode being mounted as fresh - var key = vnode.key == null ? comp : vnode.key; - var cachedVNode = cache.get(key); // clone vnode if it's reused because we are going to mutate it - if (vnode.el) { - vnode = cloneVNode(vnode); + vnode.shapeFlag |= 512 + /* COMPONENT_KEPT_ALIVE */ + ; // make this key the freshest - if (rawVNode.shapeFlag & 128 - /* SUSPENSE */ - ) { - 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. + keys.delete(key); + keys.add(key); + } else { + keys.add(key); // prune oldest entry + if (max && keys.size > parseInt(max, 10)) { + pruneCacheEntry(keys.values().next().value); + } + } // avoid vnode being unmounted - pendingCacheKey = key; - if (cachedVNode) { - // copy over mounted state - vnode.el = cachedVNode.el; - vnode.component = cachedVNode.component; + vnode.shapeFlag |= 256 + /* COMPONENT_SHOULD_KEEP_ALIVE */ + ; + current = vnode; + return rawVNode; + }; + } - if (vnode.transition) { - // recursively update transition hooks on subTree - setTransitionHooks(vnode, vnode.transition); - } // avoid vnode being mounted as fresh +}; // export the public type for h/tsx inference +// also to avoid inline import() in generated d.ts files +var KeepAlive = KeepAliveImpl; - vnode.shapeFlag |= 512 - /* COMPONENT_KEPT_ALIVE */ - ; // make this key the freshest +function matches(pattern, name) { + if (isArray(pattern)) { + return pattern.some(p => matches(p, name)); + } else if (isString(pattern)) { + return pattern.split(',').includes(name); + } else if (pattern.test) { + return pattern.test(name); + } + /* istanbul ignore next */ - keys.delete(key); - keys.add(key); - } else { - keys.add(key); // prune oldest entry - if (max && keys.size > parseInt(max, 10)) { - pruneCacheEntry(keys.values().next().value); - } - } // avoid vnode being unmounted + return false; +} +function onActivated(hook, target) { + registerKeepAliveHook(hook, "a" + /* ACTIVATED */ + , target); +} - vnode.shapeFlag |= 256 - /* COMPONENT_SHOULD_KEEP_ALIVE */ - ; - current = vnode; - return rawVNode; - }; - } +function onDeactivated(hook, target) { + registerKeepAliveHook(hook, "da" + /* DEACTIVATED */ + , target); +} - }; // export the public type for h/tsx inference - // also to avoid inline import() in generated d.ts files +function registerKeepAliveHook(hook, type) { + var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : currentInstance; - var KeepAlive = KeepAliveImpl; + // 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". + var wrappedHook = hook.__wdc || (hook.__wdc = () => { + // only fire the hook if the target instance is NOT in a deactivated branch. + var current = target; - function matches(pattern, name) { - if (shared.isArray(pattern)) { - return pattern.some(p => matches(p, name)); - } else if (shared.isString(pattern)) { - return pattern.split(',').includes(name); - } else if (pattern.test) { - return pattern.test(name); + while (current) { + if (current.isDeactivated) { + return; } - /* istanbul ignore next */ - - return false; + current = current.parent; } - function onActivated(hook, target) { - registerKeepAliveHook(hook, "a" - /* ACTIVATED */ - , target); - } + return hook(); + }); - function onDeactivated(hook, target) { - registerKeepAliveHook(hook, "da" - /* DEACTIVATED */ - , target); - } + 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. - function registerKeepAliveHook(hook, type) { - var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : currentInstance; + if (target) { + var current = target.parent; - // 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". - var wrappedHook = hook.__wdc || (hook.__wdc = () => { - // only fire the hook if the target instance is NOT in a deactivated branch. - var current = target; + while (current && current.parent) { + if (isKeepAlive(current.parent.vnode)) { + injectToKeepAliveRoot(wrappedHook, type, target, current); + } - while (current) { - if (current.isDeactivated) { - return; - } + current = current.parent; + } + } +} - current = current.parent; - } +function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { + // injectHook wraps the original for error handling, so make sure to remove + // the wrapped version. + var injected = injectHook(type, hook, keepAliveRoot, true + /* prepend */ + ); + onUnmounted(() => { + remove(keepAliveRoot[type], injected); + }, target); +} - return hook(); - }); +function resetShapeFlag(vnode) { + var 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; +} - 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. +function getInnerChild(vnode) { + return vnode.shapeFlag & 128 + /* SUSPENSE */ + ? vnode.ssContent : vnode; +} - if (target) { - var current = target.parent; +function injectHook(type, hook) { + var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : currentInstance; + var prepend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - while (current && current.parent) { - if (isKeepAlive(current.parent.vnode)) { - injectToKeepAliveRoot(wrappedHook, type, target, current); - } + if (target) { + var 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". - current = current.parent; - } - } - } + var wrappedHook = hook.__weh || (hook.__weh = function () { + if (target.isUnmounted) { + return; + } // disable tracking inside all lifecycle hooks + // since they can potentially be called inside effects. - function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { - // injectHook wraps the original for error handling, so make sure to remove - // the wrapped version. - var injected = injectHook(type, hook, keepAliveRoot, true - /* prepend */ - ); - onUnmounted(() => { - shared.remove(keepAliveRoot[type], injected); - }, target); - } - function resetShapeFlag(vnode) { - var shapeFlag = vnode.shapeFlag; + 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. - if (shapeFlag & 256 - /* COMPONENT_SHOULD_KEEP_ALIVE */ - ) { - shapeFlag -= 256 - /* COMPONENT_SHOULD_KEEP_ALIVE */ - ; - } + setCurrentInstance(target); - if (shapeFlag & 512 - /* COMPONENT_KEPT_ALIVE */ - ) { - shapeFlag -= 512 - /* COMPONENT_KEPT_ALIVE */ - ; + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; } - vnode.shapeFlag = shapeFlag; - } + var res = callWithAsyncErrorHandling(hook, target, type, args); + unsetCurrentInstance(); + resetTracking(); + return res; + }); - function getInnerChild(vnode) { - return vnode.shapeFlag & 128 - /* SUSPENSE */ - ? vnode.ssContent : vnode; + if (prepend) { + hooks.unshift(wrappedHook); + } else { + hooks.push(wrappedHook); } - function injectHook(type, hook) { - var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : currentInstance; - var prepend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - - if (target) { - var 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". - - var wrappedHook = hook.__weh || (hook.__weh = function () { - if (target.isUnmounted) { - return; - } // disable tracking inside all lifecycle hooks - // since they can potentially be called inside effects. - + return wrappedHook; + } else { + // fixed by xxxxxx + var apiName = toHandlerKey((ErrorTypeStrings[type] || type.replace(/^on/, '')).replace(/ hook$/, '')); + warn("".concat(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.")); + } +} - reactivity.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. +var createHook = lifecycle => function (hook) { + var target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : currentInstance; + return (// post-create lifecycle registrations are noops during SSR (except for serverPrefetch) + (!isInSSRComponentSetup || lifecycle === "sp" + /* SERVER_PREFETCH */ + ) && injectHook(lifecycle, hook, target) + ); +}; + +var onBeforeMount = createHook("bm" +/* BEFORE_MOUNT */ +); +var onMounted = createHook("m" +/* MOUNTED */ +); +var onBeforeUpdate = createHook("bu" +/* BEFORE_UPDATE */ +); +var onUpdated = createHook("u" +/* UPDATED */ +); +var onBeforeUnmount = createHook("bum" +/* BEFORE_UNMOUNT */ +); +var onUnmounted = createHook("um" +/* UNMOUNTED */ +); +var onServerPrefetch = createHook("sp" +/* SERVER_PREFETCH */ +); +var onRenderTriggered = createHook("rtg" +/* RENDER_TRIGGERED */ +); +var onRenderTracked = createHook("rtc" +/* RENDER_TRACKED */ +); + +function onErrorCaptured(hook) { + var target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : currentInstance; + injectHook("ec" + /* ERROR_CAPTURED */ + , hook, target); +} - setCurrentInstance(target); +function createDuplicateChecker() { + var cache = Object.create(null); + return (type, key) => { + if (cache[key]) { + warn("".concat(type, " property \"").concat(key, "\" is already defined in ").concat(cache[key], ".")); + } else { + cache[key] = type; + } + }; +} - for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { - args[_key4] = arguments[_key4]; - } +var shouldCacheAccess = true; - var res = callWithAsyncErrorHandling(hook, target, type, args); - unsetCurrentInstance(); - reactivity.resetTracking(); - return res; - }); +function applyOptions(instance) { + var options = resolveMergedOptions(instance); + var publicThis = instance.proxy; + var ctx = instance.ctx; // do not cache property access on public proxy during state initialization - if (prepend) { - hooks.unshift(wrappedHook); - } else { - hooks.push(wrappedHook); - } + shouldCacheAccess = false; // call beforeCreate first before accessing other options since + // the hook may mutate resolved options (#2791) - return wrappedHook; - } else { - // fixed by xxxxxx - var apiName = shared.toHandlerKey((ErrorTypeStrings[type] || type.replace(/^on/, '')).replace(/ hook$/, '')); - warn("".concat(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.")); + if (options.beforeCreate) { + callHook(options.beforeCreate, instance, "bc" + /* BEFORE_CREATE */ + ); + } + + var { + // state + data: dataOptions, + computed: computedOptions, + methods, + watch: watchOptions, + provide: provideOptions, + inject: injectOptions, + // lifecycle + created, + beforeMount, + mounted, + beforeUpdate, + updated, + activated, + deactivated, + beforeDestroy, + beforeUnmount, + destroyed, + unmounted, + render, + renderTracked, + renderTriggered, + errorCaptured, + serverPrefetch, + // public API + expose, + inheritAttrs, + // assets + components, + directives, + filters + } = options; + var checkDuplicateProperties = createDuplicateChecker(); + { + var [propsOptions] = instance.propsOptions; + + if (propsOptions) { + for (var 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) - var createHook = lifecycle => function (hook) { - var target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : currentInstance; - return (// post-create lifecycle registrations are noops during SSR (except for serverPrefetch) - (!isInSSRComponentSetup || lifecycle === "sp" - /* SERVER_PREFETCH */ - ) && injectHook(lifecycle, hook, target) - ); - }; - - var onBeforeMount = createHook("bm" - /* BEFORE_MOUNT */ - ); - var onMounted = createHook("m" - /* MOUNTED */ - ); - var onBeforeUpdate = createHook("bu" - /* BEFORE_UPDATE */ - ); - var onUpdated = createHook("u" - /* UPDATED */ - ); - var onBeforeUnmount = createHook("bum" - /* BEFORE_UNMOUNT */ - ); - var onUnmounted = createHook("um" - /* UNMOUNTED */ - ); - var onServerPrefetch = createHook("sp" - /* SERVER_PREFETCH */ - ); - var onRenderTriggered = createHook("rtg" - /* RENDER_TRIGGERED */ - ); - var onRenderTracked = createHook("rtc" - /* RENDER_TRACKED */ - ); + if (injectOptions) { + resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef); + } - function onErrorCaptured(hook) { - var target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : currentInstance; - injectHook("ec" - /* ERROR_CAPTURED */ - , hook, target); - } + if (methods) { + for (var _key5 in methods) { + var methodHandler = methods[_key5]; - function createDuplicateChecker() { - var cache = Object.create(null); - return (type, key) => { - if (cache[key]) { - warn("".concat(type, " property \"").concat(key, "\" is already defined in ").concat(cache[key], ".")); - } else { - cache[key] = type; + 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, _key5, { + value: methodHandler.bind(publicThis), + configurable: true, + enumerable: true, + writable: true + }); } - }; + { + checkDuplicateProperties("Methods" + /* METHODS */ + , _key5); + } + } else { + warn("Method \"".concat(_key5, "\" has type \"").concat(typeof methodHandler, "\" in the component definition. ") + "Did you reference the function correctly?"); + } } + } - var shouldCacheAccess = true; - - function applyOptions(instance) { - var options = resolveMergedOptions(instance); - var publicThis = instance.proxy; - var ctx = instance.ctx; // do not cache property access on public proxy during state initialization - - shouldCacheAccess = false; // call beforeCreate first before accessing other options since - // the hook may mutate resolved options (#2791) - - if (options.beforeCreate) { - callHook(options.beforeCreate, instance, "bc" - /* BEFORE_CREATE */ - ); + if (dataOptions) { + (function () { + if (!isFunction(dataOptions)) { + warn("The data option must be a function. " + "Plain object usage is no longer supported."); } - var { - // state - data: dataOptions, - computed: computedOptions, - methods, - watch: watchOptions, - provide: provideOptions, - inject: injectOptions, - // lifecycle - created, - beforeMount, - mounted, - beforeUpdate, - updated, - activated, - deactivated, - beforeDestroy, - beforeUnmount, - destroyed, - unmounted, - render, - renderTracked, - renderTriggered, - errorCaptured, - serverPrefetch, - // public API - expose, - inheritAttrs, - // assets - components, - directives, - filters - } = options; - var checkDuplicateProperties = createDuplicateChecker(); - { - var [propsOptions] = instance.propsOptions; - - if (propsOptions) { - for (var 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) + var data = dataOptions.call(publicThis, publicThis); - if (injectOptions) { - resolveInjections(injectOptions, ctx, checkDuplicateProperties, instance.appContext.config.unwrapInjectedRef); + 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 (methods) { - for (var _key5 in methods) { - var methodHandler = methods[_key5]; + if (!isObject(data)) { + warn("data() should return an object."); + } else { + instance.data = reactive(data); + { + var _loop = function (_key6) { + checkDuplicateProperties("Data" + /* DATA */ + , _key6); // expose data on ctx during dev - if (shared.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, _key5, { - value: methodHandler.bind(publicThis), + if (_key6[0] !== '$' && _key6[0] !== '_') { + Object.defineProperty(ctx, _key6, { configurable: true, enumerable: true, - writable: true + get: () => data[_key6], + set: NOOP }); } - { - checkDuplicateProperties("Methods" - /* METHODS */ - , _key5); - } - } else { - warn("Method \"".concat(_key5, "\" has type \"").concat(typeof methodHandler, "\" in the component definition. ") + "Did you reference the function correctly?"); + }; + + for (var _key6 in data) { + _loop(_key6); } } } + })(); + } // state initialization complete at this point - start caching access - if (dataOptions) { - (function () { - if (!shared.isFunction(dataOptions)) { - warn("The data option must be a function. " + "Plain object usage is no longer supported."); - } - var data = dataOptions.call(publicThis, publicThis); + shouldCacheAccess = true; - if (shared.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 (computedOptions) { + var _loop2 = function (_key7) { + var opt = computedOptions[_key7]; + var get = isFunction(opt) ? opt.bind(publicThis, publicThis) : isFunction(opt.get) ? opt.get.bind(publicThis, publicThis) : NOOP; - if (!shared.isObject(data)) { - warn("data() should return an object."); - } else { - instance.data = reactivity.reactive(data); - { - var _loop = function (_key6) { - checkDuplicateProperties("Data" - /* DATA */ - , _key6); // expose data on ctx during dev - - if (_key6[0] !== '$' && _key6[0] !== '_') { - Object.defineProperty(ctx, _key6, { - configurable: true, - enumerable: true, - get: () => data[_key6], - set: shared.NOOP - }); - } - }; - - for (var _key6 in data) { - _loop(_key6); - } - } - } - })(); - } // state initialization complete at this point - start caching access + if (get === NOOP) { + warn("Computed property \"".concat(_key7, "\" has no getter.")); + } + var set = !isFunction(opt) && isFunction(opt.set) ? opt.set.bind(publicThis) : () => { + warn("Write operation failed: computed property \"".concat(_key7, "\" is readonly.")); + }; + var c = computed({ + get, + set + }); + Object.defineProperty(ctx, _key7, { + enumerable: true, + configurable: true, + get: () => c.value, + set: v => c.value = v + }); + { + checkDuplicateProperties("Computed" + /* COMPUTED */ + , _key7); + } + }; - shouldCacheAccess = true; - - if (computedOptions) { - var _loop2 = function (_key7) { - var opt = computedOptions[_key7]; - var get = shared.isFunction(opt) ? opt.bind(publicThis, publicThis) : shared.isFunction(opt.get) ? opt.get.bind(publicThis, publicThis) : shared.NOOP; - - if (get === shared.NOOP) { - warn("Computed property \"".concat(_key7, "\" has no getter.")); - } - - var set = !shared.isFunction(opt) && shared.isFunction(opt.set) ? opt.set.bind(publicThis) : () => { - warn("Write operation failed: computed property \"".concat(_key7, "\" is readonly.")); - }; - var c = computed({ - get, - set - }); - Object.defineProperty(ctx, _key7, { - enumerable: true, - configurable: true, - get: () => c.value, - set: v => c.value = v - }); - { - checkDuplicateProperties("Computed" - /* COMPUTED */ - , _key7); - } - }; + for (var _key7 in computedOptions) { + _loop2(_key7); + } + } - for (var _key7 in computedOptions) { - _loop2(_key7); - } - } + if (watchOptions) { + for (var _key8 in watchOptions) { + createWatcher(watchOptions[_key8], ctx, publicThis, _key8); + } + } - if (watchOptions) { - for (var _key8 in watchOptions) { - createWatcher(watchOptions[_key8], ctx, publicThis, _key8); - } - } + if (provideOptions) { + var provides = isFunction(provideOptions) ? provideOptions.call(publicThis) : provideOptions; + Reflect.ownKeys(provides).forEach(key => { + provide(key, provides[key]); + }); + } - if (provideOptions) { - var provides = shared.isFunction(provideOptions) ? provideOptions.call(publicThis) : provideOptions; - Reflect.ownKeys(provides).forEach(key => { - provide(key, provides[key]); + if (created) { + callHook(created, instance, "c" + /* CREATED */ + ); + } + + function registerLifecycleHook(register, hook) { + if (isArray(hook)) { + hook.forEach(_hook => register(_hook.bind(publicThis))); + } else if (hook) { + register(hook.bind(publicThis)); + } + } + + registerLifecycleHook(onBeforeMount, beforeMount); + registerLifecycleHook(onMounted, mounted); + registerLifecycleHook(onBeforeUpdate, beforeUpdate); + registerLifecycleHook(onUpdated, updated); + registerLifecycleHook(onActivated, activated); + registerLifecycleHook(onDeactivated, deactivated); + registerLifecycleHook(onErrorCaptured, errorCaptured); + registerLifecycleHook(onRenderTracked, renderTracked); + registerLifecycleHook(onRenderTriggered, renderTriggered); + registerLifecycleHook(onBeforeUnmount, beforeUnmount); + registerLifecycleHook(onUnmounted, unmounted); + registerLifecycleHook(onServerPrefetch, serverPrefetch); + + if (isArray(expose)) { + if (expose.length) { + var exposed = instance.exposed || (instance.exposed = {}); + expose.forEach(key => { + Object.defineProperty(exposed, key, { + get: () => publicThis[key], + set: val => publicThis[key] = val }); - } + }); + } else if (!instance.exposed) { + instance.exposed = {}; + } + } // options that are handled when creating the instance but also need to be + // applied from mixins - if (created) { - callHook(created, instance, "c" - /* CREATED */ - ); - } - function registerLifecycleHook(register, hook) { - if (shared.isArray(hook)) { - hook.forEach(_hook => register(_hook.bind(publicThis))); - } else if (hook) { - register(hook.bind(publicThis)); - } - } - - registerLifecycleHook(onBeforeMount, beforeMount); - registerLifecycleHook(onMounted, mounted); - registerLifecycleHook(onBeforeUpdate, beforeUpdate); - registerLifecycleHook(onUpdated, updated); - registerLifecycleHook(onActivated, activated); - registerLifecycleHook(onDeactivated, deactivated); - registerLifecycleHook(onErrorCaptured, errorCaptured); - registerLifecycleHook(onRenderTracked, renderTracked); - registerLifecycleHook(onRenderTriggered, renderTriggered); - registerLifecycleHook(onBeforeUnmount, beforeUnmount); - registerLifecycleHook(onUnmounted, unmounted); - registerLifecycleHook(onServerPrefetch, serverPrefetch); - - if (shared.isArray(expose)) { - if (expose.length) { - var exposed = instance.exposed || (instance.exposed = {}); - expose.forEach(key => { - Object.defineProperty(exposed, key, { - get: () => publicThis[key], - set: val => publicThis[key] = val - }); - }); - } else if (!instance.exposed) { - instance.exposed = {}; - } - } // options that are handled when creating the instance but also need to be - // applied from mixins + if (render && instance.render === NOOP) { + instance.render = render; + } + if (inheritAttrs != null) { + instance.inheritAttrs = inheritAttrs; + } // asset options. - if (render && instance.render === shared.NOOP) { - instance.render = render; - } - if (inheritAttrs != null) { - instance.inheritAttrs = inheritAttrs; - } // asset options. + if (components) instance.components = components; + if (directives) instance.directives = directives; +} +function resolveInjections(injectOptions, ctx) { + var checkDuplicateProperties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : NOOP; + var unwrapRef = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - if (components) instance.components = components; - if (directives) instance.directives = directives; - } + if (isArray(injectOptions)) { + injectOptions = normalizeInject(injectOptions); + } - function resolveInjections(injectOptions, ctx) { - var checkDuplicateProperties = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : shared.NOOP; - var unwrapRef = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var _loop3 = function (key) { + var opt = injectOptions[key]; + var injected = void 0; - if (shared.isArray(injectOptions)) { - injectOptions = normalizeInject(injectOptions); + if (isObject(opt)) { + if ('default' in opt) { + injected = inject(opt.from || key, opt.default, true + /* treat default function as factory */ + ); + } else { + injected = inject(opt.from || key); } + } else { + injected = inject(opt); + } - var _loop3 = function (key) { - var opt = injectOptions[key]; - var injected = void 0; - - if (shared.isObject(opt)) { - if ('default' in opt) { - injected = inject(opt.from || key, opt.default, true - /* treat default function as factory */ - ); - } else { - injected = inject(opt.from || key); - } - } else { - injected = inject(opt); - } - - if (reactivity.isRef(injected)) { - // TODO remove the check in 3.3 - if (unwrapRef) { - Object.defineProperty(ctx, key, { - enumerable: true, - configurable: true, - get: () => injected.value, - set: v => injected.value = v - }); - } else { - { - warn("injected property \"".concat(key, "\" is a ref and will be auto-unwrapped ") + "and no longer needs `.value` in the next minor release. " + "To opt-in to the new behavior now, " + "set `app.config.unwrapInjectedRef = true` (this config is " + "temporary and will not be needed in the future.)"); - } - ctx[key] = injected; - } - } else { - ctx[key] = injected; - } - + if (isRef(injected)) { + // TODO remove the check in 3.3 + if (unwrapRef) { + Object.defineProperty(ctx, key, { + enumerable: true, + configurable: true, + get: () => injected.value, + set: v => injected.value = v + }); + } else { { - checkDuplicateProperties("Inject" - /* INJECT */ - , key); + warn("injected property \"".concat(key, "\" is a ref and will be auto-unwrapped ") + "and no longer needs `.value` in the next minor release. " + "To opt-in to the new behavior now, " + "set `app.config.unwrapInjectedRef = true` (this config is " + "temporary and will not be needed in the future.)"); } - }; - - for (var key in injectOptions) { - _loop3(key); + ctx[key] = injected; } + } else { + ctx[key] = injected; } - function callHook(hook, instance, type) { - callWithAsyncErrorHandling(shared.isArray(hook) ? hook.map(h => h.bind(instance.proxy)) : hook.bind(instance.proxy), instance, type); + { + checkDuplicateProperties("Inject" + /* INJECT */ + , key); } + }; - function createWatcher(raw, ctx, publicThis, key) { - var getter = key.includes('.') ? createPathGetter(publicThis, key) : () => publicThis[key]; + for (var key in injectOptions) { + _loop3(key); + } +} - if (shared.isString(raw)) { - var handler = ctx[raw]; +function callHook(hook, instance, type) { + callWithAsyncErrorHandling(isArray(hook) ? hook.map(h => h.bind(instance.proxy)) : hook.bind(instance.proxy), instance, type); +} - if (shared.isFunction(handler)) { - watch(getter, handler); - } else { - warn("Invalid watch handler specified by key \"".concat(raw, "\""), handler); - } - } else if (shared.isFunction(raw)) { - watch(getter, raw.bind(publicThis)); - } else if (shared.isObject(raw)) { - if (shared.isArray(raw)) { - raw.forEach(r => createWatcher(r, ctx, publicThis, key)); - } else { - var _handler = shared.isFunction(raw.handler) ? raw.handler.bind(publicThis) : ctx[raw.handler]; +function createWatcher(raw, ctx, publicThis, key) { + var getter = key.includes('.') ? createPathGetter(publicThis, key) : () => publicThis[key]; - if (shared.isFunction(_handler)) { - watch(getter, _handler, raw); - } else { - warn("Invalid watch handler specified by key \"".concat(raw.handler, "\""), _handler); - } - } - } else { - warn("Invalid watch option: \"".concat(key, "\""), raw); - } - } - /** - * Resolve merged options and cache it on the component. - * This is done only once per-component since the merging does not involve - * instances. - */ + if (isString(raw)) { + var handler = ctx[raw]; + if (isFunction(handler)) { + watch(getter, handler); + } else { + warn("Invalid watch handler specified by key \"".concat(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 { + var _handler = isFunction(raw.handler) ? raw.handler.bind(publicThis) : ctx[raw.handler]; - function resolveMergedOptions(instance) { - var base = instance.type; - var { - mixins, - extends: extendsOptions - } = base; - var { - mixins: globalMixins, - optionsCache: cache, - config: { - optionMergeStrategies - } - } = instance.appContext; - var cached = cache.get(base); - var resolved; - - if (cached) { - resolved = cached; - } else if (!globalMixins.length && !mixins && !extendsOptions) { - { - resolved = base; - } + if (isFunction(_handler)) { + watch(getter, _handler, raw); } else { - resolved = {}; - - if (globalMixins.length) { - globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true)); - } - - mergeOptions(resolved, base, optionMergeStrategies); + warn("Invalid watch handler specified by key \"".concat(raw.handler, "\""), _handler); } - - cache.set(base, resolved); - return resolved; } + } else { + warn("Invalid watch option: \"".concat(key, "\""), raw); + } +} +/** + * Resolve merged options and cache it on the component. + * This is done only once per-component since the merging does not involve + * instances. + */ + + +function resolveMergedOptions(instance) { + var base = instance.type; + var { + mixins, + extends: extendsOptions + } = base; + var { + mixins: globalMixins, + optionsCache: cache, + config: { + optionMergeStrategies + } + } = instance.appContext; + var cached = cache.get(base); + var resolved; + + if (cached) { + resolved = cached; + } else if (!globalMixins.length && !mixins && !extendsOptions) { + { + resolved = base; + } + } else { + resolved = {}; - function mergeOptions(to, from, strats) { - var asMixin = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - var { - mixins, - extends: extendsOptions - } = from; + if (globalMixins.length) { + globalMixins.forEach(m => mergeOptions(resolved, m, optionMergeStrategies, true)); + } - if (extendsOptions) { - mergeOptions(to, extendsOptions, strats, true); - } + mergeOptions(resolved, base, optionMergeStrategies); + } - if (mixins) { - mixins.forEach(m => mergeOptions(to, m, strats, true)); - } + cache.set(base, resolved); + return resolved; +} - for (var key in from) { - if (asMixin && key === 'expose') { - warn("\"expose\" option is ignored when declared in mixins or extends. " + "It should only be declared in the base component itself."); - } else { - var strat = internalOptionMergeStrats[key] || strats && strats[key]; - to[key] = strat ? strat(to[key], from[key]) : from[key]; - } - } - - return to; - } - - var internalOptionMergeStrats = { - data: mergeDataFn, - props: mergeObjectOptions, - emits: mergeObjectOptions, - // objects - methods: mergeObjectOptions, - computed: mergeObjectOptions, - // lifecycle - beforeCreate: mergeAsArray, - created: mergeAsArray, - beforeMount: mergeAsArray, - mounted: mergeAsArray, - beforeUpdate: mergeAsArray, - updated: mergeAsArray, - beforeDestroy: mergeAsArray, - beforeUnmount: mergeAsArray, - destroyed: mergeAsArray, - unmounted: mergeAsArray, - activated: mergeAsArray, - deactivated: mergeAsArray, - errorCaptured: mergeAsArray, - serverPrefetch: mergeAsArray, - // assets - components: mergeObjectOptions, - directives: mergeObjectOptions, - // watch - watch: mergeWatchOptions, - // provide / inject - provide: mergeDataFn, - inject: mergeInject - }; +function mergeOptions(to, from, strats) { + var asMixin = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var { + mixins, + extends: extendsOptions + } = from; - function mergeDataFn(to, from) { - if (!from) { - return to; - } + if (extendsOptions) { + mergeOptions(to, extendsOptions, strats, true); + } - if (!to) { - return from; - } + if (mixins) { + mixins.forEach(m => mergeOptions(to, m, strats, true)); + } - return function mergedDataFn() { - return shared.extend(shared.isFunction(to) ? to.call(this, this) : to, shared.isFunction(from) ? from.call(this, this) : from); - }; + for (var key in from) { + if (asMixin && key === 'expose') { + warn("\"expose\" option is ignored when declared in mixins or extends. " + "It should only be declared in the base component itself."); + } else { + var strat = internalOptionMergeStrats[key] || strats && strats[key]; + to[key] = strat ? strat(to[key], from[key]) : from[key]; } + } - function mergeInject(to, from) { - return mergeObjectOptions(normalizeInject(to), normalizeInject(from)); - } + return to; +} - function normalizeInject(raw) { - if (shared.isArray(raw)) { - var res = {}; +var internalOptionMergeStrats = { + data: mergeDataFn, + props: mergeObjectOptions, + emits: mergeObjectOptions, + // objects + methods: mergeObjectOptions, + computed: mergeObjectOptions, + // lifecycle + beforeCreate: mergeAsArray, + created: mergeAsArray, + beforeMount: mergeAsArray, + mounted: mergeAsArray, + beforeUpdate: mergeAsArray, + updated: mergeAsArray, + beforeDestroy: mergeAsArray, + beforeUnmount: mergeAsArray, + destroyed: mergeAsArray, + unmounted: mergeAsArray, + activated: mergeAsArray, + deactivated: mergeAsArray, + errorCaptured: mergeAsArray, + serverPrefetch: mergeAsArray, + // assets + components: mergeObjectOptions, + directives: mergeObjectOptions, + // watch + watch: mergeWatchOptions, + // provide / inject + provide: mergeDataFn, + inject: mergeInject +}; + +function mergeDataFn(to, from) { + if (!from) { + return to; + } + + if (!to) { + return from; + } + + return function mergedDataFn() { + return extend(isFunction(to) ? to.call(this, this) : to, isFunction(from) ? from.call(this, this) : from); + }; +} - for (var i = 0; i < raw.length; i++) { - res[raw[i]] = raw[i]; - } +function mergeInject(to, from) { + return mergeObjectOptions(normalizeInject(to), normalizeInject(from)); +} - return res; - } +function normalizeInject(raw) { + if (isArray(raw)) { + var res = {}; - return raw; + for (var i = 0; i < raw.length; i++) { + res[raw[i]] = raw[i]; } - function mergeAsArray(to, from) { - return to ? [...new Set([].concat(to, from))] : from; - } + return res; + } - function mergeObjectOptions(to, from) { - return to ? shared.extend(shared.extend(Object.create(null), to), from) : from; - } + return raw; +} - function mergeWatchOptions(to, from) { - if (!to) return from; - if (!from) return to; - var merged = shared.extend(Object.create(null), to); +function mergeAsArray(to, from) { + return to ? [...new Set([].concat(to, from))] : from; +} - for (var key in from) { - merged[key] = mergeAsArray(to[key], from[key]); - } +function mergeObjectOptions(to, from) { + return to ? extend(extend(Object.create(null), to), from) : from; +} - return merged; - } +function mergeWatchOptions(to, from) { + if (!to) return from; + if (!from) return to; + var merged = extend(Object.create(null), to); - function initProps(instance, rawProps, isStateful) { - var isSSR = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - var props = {}; - var attrs = {}; - shared.def(attrs, InternalObjectKey, 1); - instance.propsDefaults = Object.create(null); - setFullProps(instance, rawProps, props, attrs); // ensure all declared prop keys are present + for (var key in from) { + merged[key] = mergeAsArray(to[key], from[key]); + } - for (var key in instance.propsOptions[0]) { - if (!(key in props)) { - props[key] = undefined; - } - } // validation + return merged; +} +function initProps(instance, rawProps, isStateful) { + var isSSR = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var props = {}; + var attrs = {}; + def(attrs, InternalObjectKey, 1); + instance.propsDefaults = Object.create(null); + setFullProps(instance, rawProps, props, attrs); // ensure all declared prop keys are present - { - validateProps(rawProps || {}, props, instance); - } + for (var key in instance.propsOptions[0]) { + if (!(key in props)) { + props[key] = undefined; + } + } // validation - if (isStateful) { - // stateful - instance.props = isSSR ? props : reactivity.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; + { + 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; } + } - function updateProps(instance, rawProps, rawPrevProps, optimized) { - var { - props, - attrs, - vnode: { - patchFlag - } - } = instance; - var rawCurrentProps = reactivity.toRaw(props); - var [options] = instance.propsOptions; - var 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. - var propsToUpdate = instance.vnode.dynamicProps; + instance.attrs = attrs; +} - for (var i = 0; i < propsToUpdate.length; i++) { - var key = propsToUpdate[i]; // PROPS flag guarantees rawProps to be non-null - - var 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 (shared.hasOwn(attrs, key)) { - if (value !== attrs[key]) { - attrs[key] = value; - hasAttrsChanged = true; - } - } else { - var camelizedKey = shared.camelize(key); - props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false - /* isAbsent */ - ); - } - } else { - 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 - - - var kebabKey; - - for (var _key9 in rawCurrentProps) { - if (!rawProps || // for camelCase - !shared.hasOwn(rawProps, _key9) && ( // it's possible the original props was passed in as kebab-case - // and converted to camelCase (#955) - (kebabKey = shared.hyphenate(_key9)) === _key9 || !shared.hasOwn(rawProps, kebabKey))) { - if (options) { - if (rawPrevProps && ( // for camelCase - rawPrevProps[_key9] !== undefined || // for kebab-case - rawPrevProps[kebabKey] !== undefined)) { - props[_key9] = resolvePropValue(options, rawCurrentProps, _key9, undefined, instance, true - /* isAbsent */ - ); - } - } else { - delete props[_key9]; - } - } - } // 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. +function updateProps(instance, rawProps, rawPrevProps, optimized) { + var { + props, + attrs, + vnode: { + patchFlag + } + } = instance; + var rawCurrentProps = toRaw(props); + var [options] = instance.propsOptions; + var 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. + var propsToUpdate = instance.vnode.dynamicProps; + for (var i = 0; i < propsToUpdate.length; i++) { + var key = propsToUpdate[i]; // PROPS flag guarantees rawProps to be non-null - if (attrs !== rawCurrentProps) { - for (var _key10 in attrs) { - if (!rawProps || !shared.hasOwn(rawProps, _key10) && !false) { - delete attrs[_key10]; + var 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 { + var camelizedKey = camelize(key); + props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value, instance, false + /* isAbsent */ + ); + } + } else { + if (value !== attrs[key]) { + attrs[key] = value; + hasAttrsChanged = true; } } - } // trigger updates for $attrs in case it's used in component slots - - - if (hasAttrsChanged) { - reactivity.trigger(instance, "set" - /* SET */ - , '$attrs'); - } - - { - validateProps(rawProps || {}, props, instance); } } + } 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 - function setFullProps(instance, rawProps, props, attrs) { - var [options, needCastKeys] = instance.propsOptions; - var hasAttrsChanged = false; - var rawCastValues; - - if (rawProps) { - for (var key in rawProps) { - // key, ref are reserved and never passed down - if (shared.isReservedProp(key)) { - continue; - } - - var value = rawProps[key]; // prop option names are camelized during normalization, so to support - // kebab -> camel conversion here we need to camelize the key. - var camelKey = void 0; + var kebabKey; - if (options && shared.hasOwn(options, camelKey = shared.camelize(key))) { - if (!needCastKeys || !needCastKeys.includes(camelKey)) { - props[camelKey] = value; - } else { - (rawCastValues || (rawCastValues = {}))[camelKey] = value; - } - } else if (!isEmitListener(instance.emitsOptions, key)) { - if (!(key in attrs) || value !== attrs[key]) { - attrs[key] = value; - hasAttrsChanged = true; - } + for (var _key9 in rawCurrentProps) { + if (!rawProps || // for camelCase + !hasOwn(rawProps, _key9) && ( // it's possible the original props was passed in as kebab-case + // and converted to camelCase (#955) + (kebabKey = hyphenate(_key9)) === _key9 || !hasOwn(rawProps, kebabKey))) { + if (options) { + if (rawPrevProps && ( // for camelCase + rawPrevProps[_key9] !== undefined || // for kebab-case + rawPrevProps[kebabKey] !== undefined)) { + props[_key9] = resolvePropValue(options, rawCurrentProps, _key9, undefined, instance, true + /* isAbsent */ + ); } + } else { + delete props[_key9]; } } + } // 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 (needCastKeys) { - var rawCurrentProps = reactivity.toRaw(props); - var castValues = rawCastValues || shared.EMPTY_OBJ; - for (var i = 0; i < needCastKeys.length; i++) { - var _key11 = needCastKeys[i]; - props[_key11] = resolvePropValue(options, rawCurrentProps, _key11, castValues[_key11], instance, !shared.hasOwn(castValues, _key11)); + if (attrs !== rawCurrentProps) { + for (var _key10 in attrs) { + if (!rawProps || !hasOwn(rawProps, _key10) && !false) { + delete attrs[_key10]; + hasAttrsChanged = true; } } - - return hasAttrsChanged; } + } // trigger updates for $attrs in case it's used in component slots - function resolvePropValue(options, props, key, value, instance, isAbsent) { - var opt = options[key]; - if (opt != null) { - var hasDefault = shared.hasOwn(opt, 'default'); // default values + if (hasAttrsChanged) { + trigger(instance, "set" + /* SET */ + , '$attrs'); + } - if (hasDefault && value === undefined) { - var defaultValue = opt.default; + { + validateProps(rawProps || {}, props, instance); + } +} - if (opt.type !== Function && shared.isFunction(defaultValue)) { - var { - propsDefaults - } = instance; +function setFullProps(instance, rawProps, props, attrs) { + var [options, needCastKeys] = instance.propsOptions; + var hasAttrsChanged = false; + var rawCastValues; - if (key in propsDefaults) { - value = propsDefaults[key]; - } else { - setCurrentInstance(instance); - value = propsDefaults[key] = defaultValue.call(null, props); - unsetCurrentInstance(); - } - } else { - value = defaultValue; - } - } // boolean casting + if (rawProps) { + for (var key in rawProps) { + // key, ref are reserved and never passed down + if (isReservedProp(key)) { + continue; + } + var value = rawProps[key]; // prop option names are camelized during normalization, so to support + // kebab -> camel conversion here we need to camelize the key. - if (opt[0 - /* shouldCast */ - ]) { - if (isAbsent && !hasDefault) { - value = false; - } else if (opt[1 - /* shouldCastTrue */ - ] && (value === '' || value === shared.hyphenate(key))) { - value = true; - } + var camelKey = void 0; + + if (options && hasOwn(options, camelKey = camelize(key))) { + if (!needCastKeys || !needCastKeys.includes(camelKey)) { + props[camelKey] = value; + } else { + (rawCastValues || (rawCastValues = {}))[camelKey] = value; + } + } else if (!isEmitListener(instance.emitsOptions, key)) { + if (!(key in attrs) || value !== attrs[key]) { + attrs[key] = value; + hasAttrsChanged = true; } } - - return value; } + } - function normalizePropsOptions(comp, appContext) { - var asMixin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - var cache = appContext.propsCache; - var cached = cache.get(comp); + if (needCastKeys) { + var rawCurrentProps = toRaw(props); + var castValues = rawCastValues || EMPTY_OBJ; - if (cached) { - return cached; - } + for (var i = 0; i < needCastKeys.length; i++) { + var _key11 = needCastKeys[i]; + props[_key11] = resolvePropValue(options, rawCurrentProps, _key11, castValues[_key11], instance, !hasOwn(castValues, _key11)); + } + } - var raw = comp.props; - var normalized = {}; - var needCastKeys = []; // apply mixin/extends props + return hasAttrsChanged; +} - var hasExtends = false; +function resolvePropValue(options, props, key, value, instance, isAbsent) { + var opt = options[key]; - if (!shared.isFunction(comp)) { - var extendProps = raw => { - hasExtends = true; - var [props, keys] = normalizePropsOptions(raw, appContext, true); - shared.extend(normalized, props); - if (keys) needCastKeys.push(...keys); - }; + if (opt != null) { + var hasDefault = hasOwn(opt, 'default'); // default values - if (!asMixin && appContext.mixins.length) { - appContext.mixins.forEach(extendProps); - } + if (hasDefault && value === undefined) { + var defaultValue = opt.default; - if (comp.extends) { - extendProps(comp.extends); - } + if (opt.type !== Function && isFunction(defaultValue)) { + var { + propsDefaults + } = instance; - if (comp.mixins) { - comp.mixins.forEach(extendProps); + if (key in propsDefaults) { + value = propsDefaults[key]; + } else { + setCurrentInstance(instance); + value = propsDefaults[key] = defaultValue.call(null, props); + unsetCurrentInstance(); } + } else { + value = defaultValue; } + } // boolean casting - if (!raw && !hasExtends) { - cache.set(comp, shared.EMPTY_ARR); - return shared.EMPTY_ARR; - } - if (shared.isArray(raw)) { - for (var i = 0; i < raw.length; i++) { - if (!shared.isString(raw[i])) { - warn("props must be strings when using array syntax.", raw[i]); - } + if (opt[0 + /* shouldCast */ + ]) { + if (isAbsent && !hasDefault) { + value = false; + } else if (opt[1 + /* shouldCastTrue */ + ] && (value === '' || value === hyphenate(key))) { + value = true; + } + } + } - var normalizedKey = shared.camelize(raw[i]); + return value; +} - if (validatePropName(normalizedKey)) { - normalized[normalizedKey] = shared.EMPTY_OBJ; - } - } - } else if (raw) { - if (!shared.isObject(raw)) { - warn("invalid props options", raw); - } +function normalizePropsOptions(comp, appContext) { + var asMixin = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var cache = appContext.propsCache; + var cached = cache.get(comp); - for (var key in raw) { - var _normalizedKey = shared.camelize(key); + if (cached) { + return cached; + } - if (validatePropName(_normalizedKey)) { - var opt = raw[key]; - var prop = normalized[_normalizedKey] = shared.isArray(opt) || shared.isFunction(opt) ? { - type: opt - } : opt; + var raw = comp.props; + var normalized = {}; + var needCastKeys = []; // apply mixin/extends props - if (prop) { - var booleanIndex = getTypeIndex(Boolean, prop.type); - var 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 + var hasExtends = false; - if (booleanIndex > -1 || shared.hasOwn(prop, 'default')) { - needCastKeys.push(_normalizedKey); - } - } - } - } - } + if (!isFunction(comp)) { + var extendProps = raw => { + hasExtends = true; + var [props, keys] = normalizePropsOptions(raw, appContext, true); + extend(normalized, props); + if (keys) needCastKeys.push(...keys); + }; - var res = [normalized, needCastKeys]; - cache.set(comp, res); - return res; + if (!asMixin && appContext.mixins.length) { + appContext.mixins.forEach(extendProps); } - function validatePropName(key) { - if (key[0] !== '$') { - return true; - } else { - warn("Invalid prop name: \"".concat(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) { - var match = ctor && ctor.toString().match(/^\s*function (\w+)/); - return match ? match[1] : ctor === null ? 'null' : ''; + if (comp.extends) { + extendProps(comp.extends); } - function isSameType(a, b) { - return getType(a) === getType(b); + if (comp.mixins) { + comp.mixins.forEach(extendProps); } + } + + if (!raw && !hasExtends) { + cache.set(comp, EMPTY_ARR); + return EMPTY_ARR; + } - function getTypeIndex(type, expectedTypes) { - if (shared.isArray(expectedTypes)) { - return expectedTypes.findIndex(t => isSameType(t, type)); - } else if (shared.isFunction(expectedTypes)) { - return isSameType(expectedTypes, type) ? 0 : -1; + if (isArray(raw)) { + for (var i = 0; i < raw.length; i++) { + if (!isString(raw[i])) { + warn("props must be strings when using array syntax.", raw[i]); } - return -1; + var normalizedKey = camelize(raw[i]); + + if (validatePropName(normalizedKey)) { + normalized[normalizedKey] = EMPTY_OBJ; + } } - /** - * dev only - */ + } else if (raw) { + if (!isObject(raw)) { + warn("invalid props options", raw); + } + + for (var key in raw) { + var _normalizedKey = camelize(key); + if (validatePropName(_normalizedKey)) { + var opt = raw[key]; + var prop = normalized[_normalizedKey] = isArray(opt) || isFunction(opt) ? { + type: opt + } : opt; - function validateProps(rawProps, props, instance) { - var resolvedValues = reactivity.toRaw(props); - var options = instance.propsOptions[0]; + if (prop) { + var booleanIndex = getTypeIndex(Boolean, prop.type); + var 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 - for (var key in options) { - var opt = options[key]; - if (opt == null) continue; - validateProp(key, resolvedValues[key], opt, !shared.hasOwn(rawProps, key) && !shared.hasOwn(rawProps, shared.hyphenate(key))); + if (booleanIndex > -1 || hasOwn(prop, 'default')) { + needCastKeys.push(_normalizedKey); + } + } } } - /** - * dev only - */ + } + + var res = [normalized, needCastKeys]; + cache.set(comp, res); + return res; +} +function validatePropName(key) { + if (key[0] !== '$') { + return true; + } else { + warn("Invalid prop name: \"".concat(key, "\" is a reserved property.")); + } - function validateProp(name, value, prop, isAbsent) { - var { - type, - required, - validator - } = prop; // required! + return false; +} // use function string name to check type constructors +// so that it works across vms / iframes. - if (required && isAbsent) { - warn('Missing required prop: "' + name + '"'); - return; - } // missing but optional +function getType(ctor) { + var match = ctor && ctor.toString().match(/^\s*function (\w+)/); + return match ? match[1] : ctor === null ? 'null' : ''; +} - if (value == null && !prop.required) { - return; - } // type check +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; + } - if (type != null && type !== true) { - var isValid = false; - var types = shared.isArray(type) ? type : [type]; - var expectedTypes = []; // value is valid as long as one of the specified types match + return -1; +} +/** + * dev only + */ - for (var i = 0; i < types.length && !isValid; i++) { - var { - valid, - expectedType - } = assertType(value, types[i]); - expectedTypes.push(expectedType || ''); - isValid = valid; - } - if (!isValid) { - warn(getInvalidTypeMessage(name, value, expectedTypes)); - return; - } - } // custom validator +function validateProps(rawProps, props, instance) { + var resolvedValues = toRaw(props); + var options = instance.propsOptions[0]; + for (var key in options) { + var opt = options[key]; + if (opt == null) continue; + validateProp(key, resolvedValues[key], opt, !hasOwn(rawProps, key) && !hasOwn(rawProps, hyphenate(key))); + } +} +/** + * dev only + */ - if (validator && !validator(value)) { - warn('Invalid prop: custom validator check failed for prop "' + name + '".'); - } - } - var isSimpleType = /*#__PURE__*/shared.makeMap('String,Number,Boolean,Function,Symbol,BigInt'); - /** - * dev only - */ +function validateProp(name, value, prop, isAbsent) { + var { + type, + required, + validator + } = prop; // required! - function assertType(value, type) { - var valid; - var expectedType = getType(type); + if (required && isAbsent) { + warn('Missing required prop: "' + name + '"'); + return; + } // missing but optional - if (isSimpleType(expectedType)) { - var t = typeof value; - valid = t === expectedType.toLowerCase(); // for primitive wrapper objects - if (!valid && t === 'object') { - valid = value instanceof type; - } - } else if (expectedType === 'Object') { - valid = shared.isObject(value); - } else if (expectedType === 'Array') { - valid = shared.isArray(value); - } else if (expectedType === 'null') { - valid = value === null; - } else { - valid = value instanceof type; - } + if (value == null && !prop.required) { + return; + } // type check - return { + + if (type != null && type !== true) { + var isValid = false; + var types = isArray(type) ? type : [type]; + var expectedTypes = []; // value is valid as long as one of the specified types match + + for (var i = 0; i < types.length && !isValid; i++) { + var { valid, expectedType - }; + } = assertType(value, types[i]); + expectedTypes.push(expectedType || ''); + isValid = valid; } - /** - * dev only - */ + if (!isValid) { + warn(getInvalidTypeMessage(name, value, expectedTypes)); + return; + } + } // custom validator - function getInvalidTypeMessage(name, value, expectedTypes) { - var message = "Invalid prop: type check failed for prop \"".concat(name, "\".") + " Expected ".concat(expectedTypes.map(shared.capitalize).join(' | ')); - var expectedType = expectedTypes[0]; - var receivedType = shared.toRawType(value); - var expectedValue = styleValue(value, expectedType); - var receivedValue = styleValue(value, receivedType); // check if we need to specify expected value - if (expectedTypes.length === 1 && isExplicable(expectedType) && !isBoolean(expectedType, receivedType)) { - message += " with value ".concat(expectedValue); - } + if (validator && !validator(value)) { + warn('Invalid prop: custom validator check failed for prop "' + name + '".'); + } +} - message += ", got ".concat(receivedType, " "); // check if we need to specify received value +var isSimpleType = /*#__PURE__*/makeMap('String,Number,Boolean,Function,Symbol,BigInt'); +/** + * dev only + */ + +function assertType(value, type) { + var valid; + var expectedType = getType(type); + + if (isSimpleType(expectedType)) { + var 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 if (expectedType === 'null') { + valid = value === null; + } else { + valid = value instanceof type; + } + + return { + valid, + expectedType + }; +} +/** + * dev only + */ - if (isExplicable(receivedType)) { - message += "with value ".concat(receivedValue, "."); - } - return message; - } - /** - * dev only - */ +function getInvalidTypeMessage(name, value, expectedTypes) { + var message = "Invalid prop: type check failed for prop \"".concat(name, "\".") + " Expected ".concat(expectedTypes.map(capitalize).join(' | ')); + var expectedType = expectedTypes[0]; + var receivedType = toRawType(value); + var expectedValue = styleValue(value, expectedType); + var receivedValue = styleValue(value, receivedType); // check if we need to specify expected value + if (expectedTypes.length === 1 && isExplicable(expectedType) && !isBoolean(expectedType, receivedType)) { + message += " with value ".concat(expectedValue); + } - function styleValue(value, type) { - if (type === 'String') { - return "\"".concat(value, "\""); - } else if (type === 'Number') { - return "".concat(Number(value)); - } else { - return "".concat(value); - } - } - /** - * dev only - */ + message += ", got ".concat(receivedType, " "); // check if we need to specify received value + if (isExplicable(receivedType)) { + message += "with value ".concat(receivedValue, "."); + } - function isExplicable(type) { - var explicitTypes = ['string', 'number', 'boolean']; - return explicitTypes.some(elem => type.toLowerCase() === elem); - } - /** - * dev only - */ + return message; +} +/** + * dev only + */ + + +function styleValue(value, type) { + if (type === 'String') { + return "\"".concat(value, "\""); + } else if (type === 'Number') { + return "".concat(Number(value)); + } else { + return "".concat(value); + } +} +/** + * dev only + */ - function isBoolean() { - for (var _len5 = arguments.length, args = new Array(_len5), _key12 = 0; _key12 < _len5; _key12++) { - args[_key12] = arguments[_key12]; - } +function isExplicable(type) { + var explicitTypes = ['string', 'number', 'boolean']; + return explicitTypes.some(elem => type.toLowerCase() === elem); +} +/** + * dev only + */ - return args.some(elem => elem.toLowerCase() === 'boolean'); - } - var isInternalKey = key => key[0] === '_' || key === '$stable'; +function isBoolean() { + for (var _len5 = arguments.length, args = new Array(_len5), _key12 = 0; _key12 < _len5; _key12++) { + args[_key12] = arguments[_key12]; + } - var normalizeSlotValue = value => shared.isArray(value) ? value.map(normalizeVNode) : [normalizeVNode(value)]; + return args.some(elem => elem.toLowerCase() === 'boolean'); +} - var normalizeSlot = (key, rawSlot, ctx) => { - var normalized = withCtx(function () { - if (currentInstance) { - warn("Slot \"".concat(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."); - } +var isInternalKey = key => key[0] === '_' || key === '$stable'; - return normalizeSlotValue(rawSlot(...arguments)); - }, ctx); - normalized._c = false; - return normalized; - }; +var normalizeSlotValue = value => isArray(value) ? value.map(normalizeVNode) : [normalizeVNode(value)]; - var normalizeObjectSlots = (rawSlots, slots, instance) => { - var ctx = rawSlots._ctx; +var normalizeSlot = (key, rawSlot, ctx) => { + var normalized = withCtx(function () { + if (currentInstance) { + warn("Slot \"".concat(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."); + } - for (var key in rawSlots) { - if (isInternalKey(key)) continue; - var value = rawSlots[key]; + return normalizeSlotValue(rawSlot(...arguments)); + }, ctx); + normalized._c = false; + return normalized; +}; - if (shared.isFunction(value)) { - slots[key] = normalizeSlot(key, value, ctx); - } else if (value != null) { - (function () { - { - warn("Non-function value encountered for slot \"".concat(key, "\". ") + "Prefer function slots for better performance."); - } - var normalized = normalizeSlotValue(value); +var normalizeObjectSlots = (rawSlots, slots, instance) => { + var ctx = rawSlots._ctx; + + for (var key in rawSlots) { + if (isInternalKey(key)) continue; + var value = rawSlots[key]; - slots[key] = () => normalized; - })(); + if (isFunction(value)) { + slots[key] = normalizeSlot(key, value, ctx); + } else if (value != null) { + (function () { + { + warn("Non-function value encountered for slot \"".concat(key, "\". ") + "Prefer function slots for better performance."); } - } - }; + var normalized = normalizeSlotValue(value); - var normalizeVNodeSlots = (instance, children) => { - if (!isKeepAlive(instance.vnode) && !false) { - warn("Non-function value encountered for default slot. " + "Prefer function slots for better performance."); - } + slots[key] = () => normalized; + })(); + } + } +}; - var normalized = normalizeSlotValue(children); +var normalizeVNodeSlots = (instance, children) => { + if (!isKeepAlive(instance.vnode) && !false) { + warn("Non-function value encountered for default slot. " + "Prefer function slots for better performance."); + } - instance.slots.default = () => normalized; - }; + var normalized = normalizeSlotValue(children); - var initSlots = (instance, children) => { - if (instance.vnode.shapeFlag & 32 - /* SLOTS_CHILDREN */ - ) { - var type = children._; + instance.slots.default = () => normalized; +}; - if (type) { - // users can get the shallow readonly version of the slots object through `this.$slots`, - // we should avoid the proxy object polluting the slots of the internal instance - instance.slots = reactivity.toRaw(children); // make compiler marker non-enumerable - - shared.def(children, '_', type); - } else { - normalizeObjectSlots(children, instance.slots = {}); - } - } else { - instance.slots = {}; +var initSlots = (instance, children) => { + if (instance.vnode.shapeFlag & 32 + /* SLOTS_CHILDREN */ + ) { + var type = children._; - if (children) { - normalizeVNodeSlots(instance, children); - } - } + if (type) { + // users can get the shallow readonly version of the slots object through `this.$slots`, + // we should avoid the proxy object polluting the slots of the internal instance + instance.slots = toRaw(children); // make compiler marker non-enumerable - shared.def(instance.slots, InternalObjectKey, 1); - }; + def(children, '_', type); + } else { + normalizeObjectSlots(children, instance.slots = {}); + } + } else { + instance.slots = {}; - var updateSlots = (instance, children, optimized) => { - var { - vnode, - slots - } = instance; - var needDeletionCheck = true; - var deletionComparisonTarget = shared.EMPTY_OBJ; + if (children) { + normalizeVNodeSlots(instance, children); + } + } - if (vnode.shapeFlag & 32 - /* SLOTS_CHILDREN */ - ) { - var 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 - shared.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. - shared.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); - } + def(instance.slots, InternalObjectKey, 1); +}; - deletionComparisonTarget = children; - } else if (children) { - // non slot object children (direct value) passed to a component - normalizeVNodeSlots(instance, children); - deletionComparisonTarget = { - default: 1 - }; - } // delete stale slots +var updateSlots = (instance, children, optimized) => { + var { + vnode, + slots + } = instance; + var needDeletionCheck = true; + var deletionComparisonTarget = EMPTY_OBJ; + if (vnode.shapeFlag & 32 + /* SLOTS_CHILDREN */ + ) { + var type = children._; - if (needDeletionCheck) { - for (var key in slots) { - if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { - delete slots[key]; - } + 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); + } + + deletionComparisonTarget = children; + } else if (children) { + // non slot object children (direct value) passed to a component + normalizeVNodeSlots(instance, children); + deletionComparisonTarget = { + default: 1 }; - /** - 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] - ]) - */ + } // delete stale slots - function validateDirectiveName(name) { - if (shared.isBuiltInDirective(name)) { - warn('Do not use built-in directive ids as custom directive id: ' + name); + if (needDeletionCheck) { + for (var key in slots) { + if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { + delete slots[key]; } } - /** - * Adds directives to a VNode. - */ + } +}; +/** +Runtime helper for applying directives to a vnode. Example usage: +const comp = resolveComponent('comp') +const foo = resolveDirective('foo') +const bar = resolveDirective('bar') - function withDirectives(vnode, directives) { - var internalInstance = currentRenderingInstance; +return withDirectives(h(comp), [ + [foo, this.x], + [bar, this.y] +]) +*/ - if (internalInstance === null) { - warn("withDirectives can only be used inside render functions."); - return vnode; - } - var instance = internalInstance.proxy; - var bindings = vnode.dirs || (vnode.dirs = []); +function validateDirectiveName(name) { + if (isBuiltInDirective(name)) { + warn('Do not use built-in directive ids as custom directive id: ' + name); + } +} +/** + * Adds directives to a VNode. + */ - for (var i = 0; i < directives.length; i++) { - var [dir, value, arg, modifiers = shared.EMPTY_OBJ] = directives[i]; - if (shared.isFunction(dir)) { - dir = { - mounted: dir, - updated: dir - }; - } +function withDirectives(vnode, directives) { + var internalInstance = currentRenderingInstance; - if (dir.deep) { - traverse(value); - } + if (internalInstance === null) { + warn("withDirectives can only be used inside render functions."); + return vnode; + } - bindings.push({ - dir, - instance, - value, - oldValue: void 0, - arg, - modifiers - }); - } + var instance = internalInstance.proxy; + var bindings = vnode.dirs || (vnode.dirs = []); - return vnode; + for (var i = 0; i < directives.length; i++) { + var [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]; + + if (isFunction(dir)) { + dir = { + mounted: dir, + updated: dir + }; } - function invokeDirectiveHook(vnode, prevVNode, instance, name) { - var bindings = vnode.dirs; - var oldBindings = prevVNode && prevVNode.dirs; + if (dir.deep) { + traverse(value); + } - for (var i = 0; i < bindings.length; i++) { - var binding = bindings[i]; + bindings.push({ + dir, + instance, + value, + oldValue: void 0, + arg, + modifiers + }); + } - if (oldBindings) { - binding.oldValue = oldBindings[i].value; - } + return vnode; +} - var hook = binding.dir[name]; +function invokeDirectiveHook(vnode, prevVNode, instance, name) { + var bindings = vnode.dirs; + var oldBindings = prevVNode && prevVNode.dirs; - if (hook) { - // disable tracking inside all lifecycle hooks - // since they can potentially be called inside effects. - reactivity.pauseTracking(); - callWithAsyncErrorHandling(hook, instance, 8 - /* DIRECTIVE_HOOK */ - , [vnode.el, binding, vnode, prevVNode]); - reactivity.resetTracking(); - } - } - } + for (var i = 0; i < bindings.length; i++) { + var binding = bindings[i]; - function createAppContext() { - return { - app: null, - config: { - isNativeTag: shared.NO, - performance: false, - globalProperties: {}, - optionMergeStrategies: {}, - errorHandler: undefined, - warnHandler: undefined, - compilerOptions: {} - }, - mixins: [], - components: {}, - directives: {}, - provides: Object.create(null), - optionsCache: new WeakMap(), - propsCache: new WeakMap(), - emitsCache: new WeakMap() - }; + if (oldBindings) { + binding.oldValue = oldBindings[i].value; } - var uid = 0; + var hook = binding.dir[name]; - function createAppAPI(render, hydrate) { - return function createApp(rootComponent) { - var rootProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + if (hook) { + // disable tracking inside all lifecycle hooks + // since they can potentially be called inside effects. + pauseTracking(); + callWithAsyncErrorHandling(hook, instance, 8 + /* DIRECTIVE_HOOK */ + , [vnode.el, binding, vnode, prevVNode]); + resetTracking(); + } + } +} - if (rootProps != null && !shared.isObject(rootProps)) { - warn("root props passed to app.mount() must be an object."); - rootProps = null; - } +function createAppContext() { + return { + app: null, + config: { + isNativeTag: NO, + performance: false, + globalProperties: {}, + optionMergeStrategies: {}, + errorHandler: undefined, + warnHandler: undefined, + compilerOptions: {} + }, + mixins: [], + components: {}, + directives: {}, + provides: Object.create(null), + optionsCache: new WeakMap(), + propsCache: new WeakMap(), + emitsCache: new WeakMap() + }; +} - var context = createAppContext(); - var installedPlugins = new Set(); - var isMounted = false; - var app = context.app = { - _uid: uid++, - _component: rootComponent, - _props: rootProps, - _container: null, - _context: context, - _instance: null, - version, +var uid = 0; - get config() { - return context.config; - }, +function createAppAPI(render, hydrate) { + return function createApp(rootComponent) { + var rootProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - set config(v) { - { - warn("app.config cannot be replaced. Modify individual options instead."); - } - }, + if (rootProps != null && !isObject(rootProps)) { + warn("root props passed to app.mount() must be an object."); + rootProps = null; + } - use(plugin) { - for (var _len6 = arguments.length, options = new Array(_len6 > 1 ? _len6 - 1 : 0), _key13 = 1; _key13 < _len6; _key13++) { - options[_key13 - 1] = arguments[_key13]; - } + var context = createAppContext(); + var installedPlugins = new Set(); + var isMounted = false; + var app = context.app = { + _uid: uid++, + _component: rootComponent, + _props: rootProps, + _container: null, + _context: context, + _instance: null, + version, - if (installedPlugins.has(plugin)) { - warn("Plugin has already been applied to target app."); - } else if (plugin && shared.isFunction(plugin.install)) { - installedPlugins.add(plugin); - plugin.install(app, ...options); - } else if (shared.isFunction(plugin)) { - installedPlugins.add(plugin); - plugin(app, ...options); - } else { - warn("A plugin must either be a function or an object with an \"install\" " + "function."); - } + get config() { + return context.config; + }, + + set config(v) { + { + warn("app.config cannot be replaced. Modify individual options instead."); + } + }, - return app; - }, + use(plugin) { + for (var _len6 = arguments.length, options = new Array(_len6 > 1 ? _len6 - 1 : 0), _key13 = 1; _key13 < _len6; _key13++) { + options[_key13 - 1] = arguments[_key13]; + } - mixin(mixin) { - { - if (!context.mixins.includes(mixin)) { - context.mixins.push(mixin); - } else { - warn('Mixin has already been applied to target app' + (mixin.name ? ": ".concat(mixin.name) : '')); - } - } - return app; - }, + 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."); + } - component(name, component) { - { - validateComponentName(name, context.config); - } + return app; + }, - if (!component) { - return context.components[name]; - } + mixin(mixin) { + { + if (!context.mixins.includes(mixin)) { + context.mixins.push(mixin); + } else { + warn('Mixin has already been applied to target app' + (mixin.name ? ": ".concat(mixin.name) : '')); + } + } + return app; + }, - if (context.components[name]) { - warn("Component \"".concat(name, "\" has already been registered in target app.")); - } + component(name, component) { + { + validateComponentName(name, context.config); + } - context.components[name] = component; - return app; - }, + if (!component) { + return context.components[name]; + } - directive(name, directive) { - { - validateDirectiveName(name); - } + if (context.components[name]) { + warn("Component \"".concat(name, "\" has already been registered in target app.")); + } - if (!directive) { - return context.directives[name]; - } + context.components[name] = component; + return app; + }, - if (context.directives[name]) { - warn("Directive \"".concat(name, "\" has already been registered in target app.")); - } + directive(name, directive) { + { + validateDirectiveName(name); + } - context.directives[name] = directive; - return app; - }, + if (!directive) { + return context.directives[name]; + } - mount(rootContainer, isHydrate, isSVG) { - if (!isMounted) { - var vnode = createVNode(rootComponent, rootProps); // store app context on the root VNode. - // this will be set on the root instance on initial mount. + if (context.directives[name]) { + warn("Directive \"".concat(name, "\" has already been registered in target app.")); + } - vnode.appContext = context; // HMR root reload + context.directives[name] = directive; + return app; + }, - { - context.reload = () => { - render(cloneVNode(vnode), rootContainer, isSVG); - }; - } + mount(rootContainer, isHydrate, isSVG) { + if (!isMounted) { + var vnode = createVNode(rootComponent, rootProps); // store app context on the root VNode. + // this will be set on the root instance on initial mount. - if (isHydrate && hydrate) { - hydrate(vnode, rootContainer); - } else { - render(vnode, rootContainer, isSVG); - } + vnode.appContext = context; // HMR root reload - isMounted = true; - app._container = rootContainer; - rootContainer.__vue_app__ = app; - { - app._instance = vnode.component; - devtoolsInitApp(app, version); - } - return getExposeProxy(vnode.component) || 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); - { - app._instance = null; - devtoolsUnmountApp(app); - } - delete app._container.__vue_app__; - } else { - warn("Cannot unmount an app that is not mounted."); - } - }, + { + context.reload = () => { + render(cloneVNode(vnode), rootContainer, isSVG); + }; + } - provide(key, value) { - if (key in context.provides) { - warn("App already provides property with key \"".concat(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 + if (isHydrate && hydrate) { + hydrate(vnode, rootContainer); + } else { + render(vnode, rootContainer, isSVG); + } + isMounted = true; + app._container = rootContainer; + rootContainer.__vue_app__ = app; + { + app._instance = vnode.component; + devtoolsInitApp(app, version); + } + return getExposeProxy(vnode.component) || 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)`"); + } + }, - context.provides[key] = value; - return app; + unmount() { + if (isMounted) { + render(null, app._container); + { + app._instance = null; + 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 \"".concat(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; + } + + }; + return app; + }; +} +/** + * Function for handling a template ref + */ + + +function setRef(rawRef, oldRawRef, parentSuspense, vnode) { + var isUnmount = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 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; + } + + var refValue = vnode.shapeFlag & 4 + /* STATEFUL_COMPONENT */ + ? getExposeProxy(vnode.component) || vnode.component.proxy : vnode.el; + var value = isUnmount ? null : refValue; + var { + 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; + } + + var oldRef = oldRawRef && oldRawRef.r; + var refs = owner.refs === EMPTY_OBJ ? owner.refs = {} : owner.refs; + var 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 (isFunction(ref)) { + callWithErrorHandling(ref, owner, 12 + /* FUNCTION_REF */ + , [value, refs]); + } else { + var _isString = isString(ref); + + var _isRef = isRef(ref); + + if (_isString || _isRef) { + var doSet = () => { + if (rawRef.f) { + var existing = _isString ? refs[ref] : ref.value; + + if (isUnmount) { + isArray(existing) && remove(existing, refValue); + } else { + if (!isArray(existing)) { + if (_isString) { + refs[ref] = [refValue]; + } else { + ref.value = [refValue]; + if (rawRef.k) refs[rawRef.k] = ref.value; + } + } else if (!existing.includes(refValue)) { + existing.push(refValue); + } + } + } else if (_isString) { + refs[ref] = value; + + if (hasOwn(setupState, ref)) { + setupState[ref] = value; + } + } else if (isRef(ref)) { + ref.value = value; + if (rawRef.k) refs[rawRef.k] = value; + } else { + warn('Invalid template ref type:', ref, "(".concat(typeof ref, ")")); + } }; + + if (value) { + doSet.id = -1; + queuePostRenderEffect(doSet, parentSuspense); + } else { + doSet(); + } + } else { + warn('Invalid template ref type:', ref, "(".concat(typeof ref, ")")); } - /** - * Function for handling a template ref - */ + } +} +var hasMismatch = false; + +var isSVGContainer = container => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; + +var 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) { + var { + mt: mountComponent, + p: patch, + o: { + patchProp, + nextSibling, + parentNode, + remove, + insert, + createComment + } + } = rendererInternals; + + var hydrate = (vnode, container) => { + if (!container.hasChildNodes()) { + warn("Attempting to hydrate existing markup but container is empty. " + "Performing full mount instead."); + patch(null, vnode, container); + flushPostFlushCbs(); + 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."); + } + }; + + var hydrateNode = function (node, vnode, parentComponent, parentSuspense, slotScopeIds) { + var optimized = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; + var isFragmentStart = isComment(node) && node.data === '['; + + var onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart); + + var { + type, + ref, + shapeFlag + } = vnode; + var domType = node.nodeType; + vnode.el = node; + var 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: ".concat(JSON.stringify(node.data)) + "\n- Server: ".concat(JSON.stringify(vnode.children))); + node.data = vnode.children; + } - function setRef(rawRef, oldRawRef, parentSuspense, vnode) { - var isUnmount = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + nextNode = nextSibling(node); + } - if (shared.isArray(rawRef)) { - rawRef.forEach((r, i) => setRef(r, oldRawRef && (shared.isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount)); - return; - } + break; - if (isAsyncWrapper(vnode) && !isUnmount) { - // when mounting async components, nothing needs to be done, - // because the template ref is forwarded to inner component - return; - } + case Comment: + if (domType !== 8 + /* COMMENT */ + || isFragmentStart) { + nextNode = onMismatch(); + } else { + nextNode = nextSibling(node); + } - var refValue = vnode.shapeFlag & 4 - /* STATEFUL_COMPONENT */ - ? getExposeProxy(vnode.component) || vnode.component.proxy : vnode.el; - var value = isUnmount ? null : refValue; - var { - i: owner, - r: ref - } = rawRef; + break; - 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; - } + 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. + + var needToAdoptContent = !vnode.children.length; - var oldRef = oldRawRef && oldRawRef.r; - var refs = owner.refs === shared.EMPTY_OBJ ? owner.refs = {} : owner.refs; - var setupState = owner.setupState; // dynamic ref changed. unset old ref + for (var i = 0; i < vnode.staticCount; i++) { + if (needToAdoptContent) vnode.children += nextNode.outerHTML; - if (oldRef != null && oldRef !== ref) { - if (shared.isString(oldRef)) { - refs[oldRef] = null; + if (i === vnode.staticCount - 1) { + vnode.anchor = nextNode; + } - if (shared.hasOwn(setupState, oldRef)) { - setupState[oldRef] = null; + nextNode = nextSibling(nextNode); } - } else if (reactivity.isRef(oldRef)) { - oldRef.value = null; - } - } - if (shared.isFunction(ref)) { - callWithErrorHandling(ref, owner, 12 - /* FUNCTION_REF */ - , [value, refs]); - } else { - var _isString = shared.isString(ref); + return nextNode; + } - var _isRef = reactivity.isRef(ref); + break; - if (_isString || _isRef) { - var doSet = () => { - if (rawRef.f) { - var existing = _isString ? refs[ref] : ref.value; + case Fragment: + if (!isFragmentStart) { + nextNode = onMismatch(); + } else { + nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized); + } - if (isUnmount) { - shared.isArray(existing) && shared.remove(existing, refValue); - } else { - if (!shared.isArray(existing)) { - if (_isString) { - refs[ref] = [refValue]; - } else { - ref.value = [refValue]; - if (rawRef.k) refs[rawRef.k] = ref.value; - } - } else if (!existing.includes(refValue)) { - existing.push(refValue); - } - } - } else if (_isString) { - refs[ref] = value; + break; - if (shared.hasOwn(setupState, ref)) { - setupState[ref] = value; - } - } else if (reactivity.isRef(ref)) { - ref.value = value; - if (rawRef.k) refs[rawRef.k] = value; + 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; + var 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); // #3787 + // if component is async, it may get moved / unmounted before its + // inner component is loaded, so we need to give it a placeholder + // vnode that matches its adopted DOM. + + if (isAsyncWrapper(vnode)) { + var subTree; + + if (isFragmentStart) { + subTree = createVNode(Fragment); + subTree.anchor = nextNode ? nextNode.previousSibling : container.lastChild; } else { - warn('Invalid template ref type:', ref, "(".concat(typeof ref, ")")); + subTree = node.nodeType === 3 ? createTextVNode('') : createVNode('div'); } - }; - if (value) { - doSet.id = -1; - queuePostRenderEffect(doSet, parentSuspense); + subTree.el = node; + vnode.component.subTree = subTree; + } + } else if (shapeFlag & 64 + /* TELEPORT */ + ) { + if (domType !== 8 + /* COMMENT */ + ) { + nextNode = onMismatch(); } else { - doSet(); + 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 template ref type:', ref, "(".concat(typeof ref, ")")); + warn('Invalid HostVNode type:', type, "(".concat(typeof type, ")")); } - } + } - var hasMismatch = false; + if (ref != null) { + setRef(ref, null, parentSuspense, vnode); + } - var isSVGContainer = container => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; + return nextNode; + }; - var 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. + var hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => { + optimized = optimized || !!vnode.dynamicChildren; + var { + type, + props, + patchFlag, + shapeFlag, + dirs + } = vnode; // #4006 for form elements with non-string v-model value bindings + // e.g.