{"version":3,"file":"luckysheet.umd.js","sources":["../node_modules/core-js/internals/global.js","../node_modules/core-js/internals/fails.js","../node_modules/core-js/internals/descriptors.js","../node_modules/core-js/internals/object-property-is-enumerable.js","../node_modules/core-js/internals/create-property-descriptor.js","../node_modules/core-js/internals/classof-raw.js","../node_modules/core-js/internals/indexed-object.js","../node_modules/core-js/internals/require-object-coercible.js","../node_modules/core-js/internals/to-indexed-object.js","../node_modules/core-js/internals/is-object.js","../node_modules/core-js/internals/to-primitive.js","../node_modules/core-js/internals/has.js","../node_modules/core-js/internals/document-create-element.js","../node_modules/core-js/internals/ie8-dom-define.js","../node_modules/core-js/internals/object-get-own-property-descriptor.js","../node_modules/core-js/internals/an-object.js","../node_modules/core-js/internals/object-define-property.js","../node_modules/core-js/internals/create-non-enumerable-property.js","../node_modules/core-js/internals/set-global.js","../node_modules/core-js/internals/shared-store.js","../node_modules/core-js/internals/inspect-source.js","../node_modules/core-js/internals/internal-state.js","../node_modules/core-js/internals/native-weak-map.js","../node_modules/core-js/internals/shared.js","../node_modules/core-js/internals/uid.js","../node_modules/core-js/internals/shared-key.js","../node_modules/core-js/internals/hidden-keys.js","../node_modules/core-js/internals/redefine.js","../node_modules/core-js/internals/path.js","../node_modules/core-js/internals/get-built-in.js","../node_modules/core-js/internals/to-integer.js","../node_modules/core-js/internals/to-length.js","../node_modules/core-js/internals/to-absolute-index.js","../node_modules/core-js/internals/array-includes.js","../node_modules/core-js/internals/object-keys-internal.js","../node_modules/core-js/internals/enum-bug-keys.js","../node_modules/core-js/internals/object-get-own-property-names.js","../node_modules/core-js/internals/object-get-own-property-symbols.js","../node_modules/core-js/internals/own-keys.js","../node_modules/core-js/internals/copy-constructor-properties.js","../node_modules/core-js/internals/is-forced.js","../node_modules/core-js/internals/export.js","../node_modules/core-js/internals/array-method-is-strict.js","../node_modules/core-js/internals/array-method-uses-to-length.js","../node_modules/core-js/modules/es.array.index-of.js","../node_modules/core-js/internals/a-possible-prototype.js","../node_modules/core-js/internals/object-create.js","../node_modules/core-js/internals/object-set-prototype-of.js","../node_modules/core-js/internals/inherit-if-required.js","../node_modules/core-js/internals/object-keys.js","../node_modules/core-js/internals/object-define-properties.js","../node_modules/core-js/internals/html.js","../node_modules/core-js/internals/whitespaces.js","../node_modules/core-js/internals/string-trim.js","../node_modules/core-js/modules/es.number.constructor.js","../node_modules/core-js/modules/es.number.is-nan.js","../node_modules/core-js/internals/this-number-value.js","../node_modules/core-js/internals/string-repeat.js","../node_modules/core-js/modules/es.number.to-fixed.js","../node_modules/core-js/internals/native-symbol.js","../node_modules/core-js/internals/use-symbol-as-uid.js","../node_modules/core-js/internals/well-known-symbol.js","../node_modules/core-js/internals/to-string-tag-support.js","../node_modules/core-js/internals/classof.js","../node_modules/core-js/internals/object-to-string.js","../node_modules/core-js/modules/es.object.to-string.js","../node_modules/core-js/internals/regexp-flags.js","../node_modules/core-js/internals/regexp-sticky-helpers.js","../node_modules/core-js/internals/regexp-exec.js","../node_modules/core-js/modules/es.regexp.exec.js","../node_modules/core-js/modules/es.regexp.to-string.js","../node_modules/core-js/internals/fix-regexp-well-known-symbol-logic.js","../node_modules/core-js/internals/to-object.js","../node_modules/core-js/internals/string-multibyte.js","../node_modules/core-js/internals/advance-string-index.js","../node_modules/core-js/internals/regexp-exec-abstract.js","../node_modules/core-js/modules/es.string.replace.js","../src/controllers/luckysheetConfigsetting.js","../src/store/index.js","../src/global/validate.js","../src/utils/math.js","../node_modules/core-js/internals/engine-v8-version.js","../src/config.js","../node_modules/core-js/internals/is-array.js","../node_modules/core-js/internals/create-property.js","../node_modules/core-js/internals/array-species-create.js","../node_modules/core-js/internals/engine-user-agent.js","../node_modules/core-js/internals/array-method-has-species-support.js","../node_modules/core-js/modules/es.array.concat.js","../node_modules/core-js/internals/a-function.js","../node_modules/core-js/internals/function-bind-context.js","../node_modules/core-js/internals/array-iteration.js","../node_modules/core-js/internals/add-to-unscopables.js","../node_modules/core-js/modules/es.array.find.js","../node_modules/core-js/internals/array-for-each.js","../node_modules/core-js/modules/es.array.for-each.js","../node_modules/core-js/modules/es.array.join.js","../node_modules/core-js/modules/es.array.slice.js","../node_modules/core-js/modules/es.array.some.js","../node_modules/core-js/modules/es.array.splice.js","../node_modules/core-js/internals/correct-prototype-getter.js","../node_modules/core-js/internals/object-get-prototype-of.js","../node_modules/core-js/modules/es.reflect.set.js","../node_modules/core-js/modules/es.string.match.js","../node_modules/core-js/internals/is-regexp.js","../node_modules/core-js/internals/species-constructor.js","../node_modules/core-js/modules/es.string.split.js","../node_modules/core-js/internals/dom-iterables.js","../node_modules/core-js/modules/web.dom-collections.for-each.js","../node_modules/core-js/modules/es.array.every.js","../node_modules/core-js/modules/es.array.filter.js","../node_modules/core-js/modules/es.array.sort.js","../node_modules/core-js/internals/object-assign.js","../node_modules/core-js/modules/es.object.assign.js","../node_modules/core-js/internals/object-to-array.js","../node_modules/core-js/modules/es.object.values.js","../node_modules/core-js/internals/create-html.js","../node_modules/core-js/internals/string-html-forced.js","../node_modules/core-js/modules/es.string.bold.js","../node_modules/core-js/modules/es.string.link.js","../src/locale/locale.js","../src/locale/en.js","../src/locale/zh.js","../src/locale/es.js","../src/locale/zh_tw.js","../src/controllers/constant.js","../node_modules/core-js/internals/string-trim-forced.js","../node_modules/core-js/modules/es.string.trim.js","../node_modules/core-js/modules/es.object.keys.js","../node_modules/core-js/modules/es.function.name.js","../node_modules/core-js/internals/object-get-own-property-names-external.js","../node_modules/core-js/modules/es.object.get-own-property-names.js","../node_modules/core-js/internals/set-species.js","../node_modules/core-js/modules/es.regexp.constructor.js","../node_modules/core-js/modules/es.string.repeat.js","../node_modules/core-js/internals/same-value.js","../src/methods/get.js","../src/methods/set.js","../node_modules/core-js/modules/es.string.search.js","../node_modules/core-js/modules/es.array.includes.js","../node_modules/core-js/modules/es.array.map.js","../src/global/browser.js","../node_modules/pako/lib/utils/common.js","../node_modules/pako/lib/zlib/trees.js","../node_modules/pako/lib/zlib/adler32.js","../node_modules/pako/lib/zlib/crc32.js","../node_modules/pako/lib/zlib/deflate.js","../node_modules/pako/lib/zlib/messages.js","../node_modules/pako/lib/utils/strings.js","../node_modules/pako/lib/zlib/zstream.js","../node_modules/pako/lib/deflate.js","../node_modules/pako/lib/zlib/inffast.js","../node_modules/pako/lib/zlib/inftrees.js","../node_modules/pako/lib/zlib/inflate.js","../node_modules/pako/lib/zlib/constants.js","../node_modules/pako/lib/zlib/gzheader.js","../node_modules/pako/lib/inflate.js","../node_modules/pako/index.js","../src/global/loading.js","../src/global/rhchInit.js","../src/global/dynamicArray.js","../src/global/cursorPos.js","../src/controllers/inlineString.js","../src/global/getdata.js","../src/global/editor.js","../node_modules/core-js/internals/array-last-index-of.js","../node_modules/core-js/modules/es.array.last-index-of.js","../node_modules/dayjs/dayjs.min.js","../src/global/datecontroll.js","../node_modules/numeral/numeral.js","../src/global/format.js","../src/global/setdata.js","../src/controllers/sheetSearch.js","../src/global/location.js","../src/global/getRowlen.js","../node_modules/core-js/internals/array-fill.js","../node_modules/core-js/modules/es.array.fill.js","../node_modules/core-js/internals/iterators.js","../node_modules/core-js/internals/iterators-core.js","../node_modules/core-js/internals/set-to-string-tag.js","../node_modules/core-js/internals/create-iterator-constructor.js","../node_modules/core-js/internals/define-iterator.js","../node_modules/core-js/modules/es.array.iterator.js","../node_modules/core-js/modules/web.dom-collections.iterator.js","../src/global/count.js","../src/controllers/sheetMove.js","../src/controllers/alternateformat.js","../src/global/json.js","../src/controllers/filter.js","../src/controllers/imageCtrl.js","../src/controllers/dataVerificationCtrl.js","../src/global/extend.js","../src/global/method.js","../src/global/createsheet.js","../src/controllers/postil.js","../src/global/border.js","../src/controllers/dropCell.js","../src/controllers/freezen.js","../src/controllers/resize.js","../src/controllers/protection.js","../src/utils/util.js","../src/global/sort.js","../src/global/array.js","../src/global/analysis.js","../src/controllers/pivotTable.js","../src/controllers/sparkline.js","../src/global/draw.js","../src/controllers/hyperlinkCtrl.js","../src/global/refresh.js","../src/controllers/server.js","../src/global/tooltip.js","../src/controllers/conditionformat.js","../src/controllers/selection.js","../src/global/cleargridelement.js","../src/global/createdom.js","../node_modules/core-js/modules/es.array.find-index.js","../node_modules/core-js/internals/freezing.js","../node_modules/core-js/internals/internal-metadata.js","../node_modules/core-js/internals/is-array-iterator-method.js","../node_modules/core-js/internals/get-iterator-method.js","../node_modules/core-js/internals/call-with-safe-iteration-closing.js","../node_modules/core-js/internals/iterate.js","../node_modules/core-js/internals/an-instance.js","../node_modules/core-js/internals/check-correctness-of-iteration.js","../node_modules/core-js/internals/redefine-all.js","../node_modules/core-js/internals/collection-strong.js","../node_modules/core-js/modules/es.string.iterator.js","../node_modules/core-js/internals/collection.js","../node_modules/core-js/modules/es.map.js","../src/utils/chartUtil.js","../src/global/func_methods.js","../src/function/matrix_methods.js","../src/function/func.js","../src/expendPlugins/chart/plugin.js","../src/controllers/zoom.js","../src/controllers/sheetmanage.js","../src/global/formula.js","../src/controllers/select.js","../src/controllers/moreFormat.js","../src/controllers/searchReplace.js","../src/controllers/locationCell.js","../node_modules/core-js/internals/not-a-regexp.js","../node_modules/core-js/internals/correct-is-regexp-logic.js","../node_modules/core-js/modules/es.string.includes.js","../node_modules/flatpickr/dist/flatpickr.js","../node_modules/core-js/internals/math-sign.js","../node_modules/core-js/modules/es.math.cbrt.js","../src/controllers/controlHistory.js","../src/global/api.js","../src/controllers/cellDatePickerCtrl.js","../src/controllers/updateCell.js","../src/controllers/ifFormulaGenerator.js","../src/controllers/insertFormula.js","../src/controllers/menuButton.js","../node_modules/core-js/internals/array-buffer-native.js","../node_modules/core-js/internals/array-buffer-view-core.js","../node_modules/core-js/internals/typed-array-constructors-require-wrappers.js","../node_modules/core-js/internals/to-index.js","../node_modules/core-js/internals/ieee754.js","../node_modules/core-js/internals/array-buffer.js","../node_modules/core-js/internals/to-offset.js","../node_modules/core-js/internals/to-positive-integer.js","../node_modules/core-js/internals/typed-array-from.js","../node_modules/core-js/internals/typed-array-constructor.js","../node_modules/core-js/modules/es.typed-array.uint8-array.js","../node_modules/core-js/internals/array-copy-within.js","../node_modules/core-js/modules/es.typed-array.copy-within.js","../node_modules/core-js/modules/es.typed-array.every.js","../node_modules/core-js/modules/es.typed-array.fill.js","../node_modules/core-js/modules/es.typed-array.filter.js","../node_modules/core-js/modules/es.typed-array.find.js","../node_modules/core-js/modules/es.typed-array.find-index.js","../node_modules/core-js/modules/es.typed-array.for-each.js","../node_modules/core-js/modules/es.typed-array.includes.js","../node_modules/core-js/modules/es.typed-array.index-of.js","../node_modules/core-js/modules/es.typed-array.iterator.js","../node_modules/core-js/modules/es.typed-array.join.js","../node_modules/core-js/modules/es.typed-array.last-index-of.js","../node_modules/core-js/modules/es.typed-array.map.js","../node_modules/core-js/internals/array-reduce.js","../node_modules/core-js/modules/es.typed-array.reduce.js","../node_modules/core-js/modules/es.typed-array.reduce-right.js","../node_modules/core-js/modules/es.typed-array.reverse.js","../node_modules/core-js/modules/es.typed-array.set.js","../node_modules/core-js/modules/es.typed-array.slice.js","../node_modules/core-js/modules/es.typed-array.some.js","../node_modules/core-js/modules/es.typed-array.sort.js","../node_modules/core-js/modules/es.typed-array.subarray.js","../node_modules/core-js/modules/es.typed-array.to-locale-string.js","../node_modules/core-js/modules/es.typed-array.to-string.js","../node_modules/core-js/internals/native-url.js","../node_modules/core-js/internals/array-from.js","../node_modules/core-js/internals/string-punycode-to-ascii.js","../node_modules/core-js/internals/get-iterator.js","../node_modules/core-js/modules/web.url-search-params.js","../node_modules/core-js/modules/web.url.js","../src/controllers/splitColumn.js","../src/controllers/cellFormat.js","../src/global/scroll.js","../src/controllers/handler.js","../src/controllers/mobile.js","../src/controllers/sheetBar.js","../src/controllers/rowColumnOperation.js","../src/controllers/keyboard.js","../src/expendPlugins/print/plugin.js","../src/controllers/expendPlugins.js","../src/function/functionImplementation.js","../src/controllers/print.js","../node_modules/flatpickr/dist/l10n/zh.js","../src/core.js","../src/controllers/formulaBar.js","../src/controllers/matrixOperation.js","../src/controllers/orderBy.js","../src/controllers/listener.js","../src/function/functionlist.js","../node_modules/core-js/internals/object-prototype-accessors-forced.js","../src/utils/polyfill.js","../node_modules/core-js/modules/es.object.define-getter.js","../src/index.js"],"sourcesContent":["var check = function (it) {\n return it && it.Math == Math && it;\n};\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nmodule.exports =\n // eslint-disable-next-line no-undef\n check(typeof globalThis == 'object' && globalThis) ||\n check(typeof window == 'object' && window) ||\n check(typeof self == 'object' && self) ||\n check(typeof global == 'object' && global) ||\n // eslint-disable-next-line no-new-func\n Function('return this')();\n","module.exports = function (exec) {\n try {\n return !!exec();\n } catch (error) {\n return true;\n }\n};\n","var fails = require('../internals/fails');\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !fails(function () {\n return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7;\n});\n","'use strict';\nvar nativePropertyIsEnumerable = {}.propertyIsEnumerable;\nvar getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// Nashorn ~ JDK8 bug\nvar NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);\n\n// `Object.prototype.propertyIsEnumerable` method implementation\n// https://tc39.github.io/ecma262/#sec-object.prototype.propertyisenumerable\nexports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {\n var descriptor = getOwnPropertyDescriptor(this, V);\n return !!descriptor && descriptor.enumerable;\n} : nativePropertyIsEnumerable;\n","module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n","var fails = require('../internals/fails');\nvar classof = require('../internals/classof-raw');\n\nvar split = ''.split;\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nmodule.exports = fails(function () {\n // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346\n // eslint-disable-next-line no-prototype-builtins\n return !Object('z').propertyIsEnumerable(0);\n}) ? function (it) {\n return classof(it) == 'String' ? split.call(it, '') : Object(it);\n} : Object;\n","// `RequireObjectCoercible` abstract operation\n// https://tc39.github.io/ecma262/#sec-requireobjectcoercible\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n","// toObject with fallback for non-array-like ES3 strings\nvar IndexedObject = require('../internals/indexed-object');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\nmodule.exports = function (it) {\n return IndexedObject(requireObjectCoercible(it));\n};\n","module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n","var isObject = require('../internals/is-object');\n\n// `ToPrimitive` abstract operation\n// https://tc39.github.io/ecma262/#sec-toprimitive\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (input, PREFERRED_STRING) {\n if (!isObject(input)) return input;\n var fn, val;\n if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;\n if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;\n if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n","var hasOwnProperty = {}.hasOwnProperty;\n\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n","var global = require('../internals/global');\nvar isObject = require('../internals/is-object');\n\nvar document = global.document;\n// typeof document.createElement is 'object' in old IE\nvar EXISTS = isObject(document) && isObject(document.createElement);\n\nmodule.exports = function (it) {\n return EXISTS ? document.createElement(it) : {};\n};\n","var DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\nvar createElement = require('../internals/document-create-element');\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !DESCRIPTORS && !fails(function () {\n return Object.defineProperty(createElement('div'), 'a', {\n get: function () { return 7; }\n }).a != 7;\n});\n","var DESCRIPTORS = require('../internals/descriptors');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toPrimitive = require('../internals/to-primitive');\nvar has = require('../internals/has');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\n\nvar nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;\n\n// `Object.getOwnPropertyDescriptor` method\n// https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptor\nexports.f = DESCRIPTORS ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {\n O = toIndexedObject(O);\n P = toPrimitive(P, true);\n if (IE8_DOM_DEFINE) try {\n return nativeGetOwnPropertyDescriptor(O, P);\n } catch (error) { /* empty */ }\n if (has(O, P)) return createPropertyDescriptor(!propertyIsEnumerableModule.f.call(O, P), O[P]);\n};\n","var isObject = require('../internals/is-object');\n\nmodule.exports = function (it) {\n if (!isObject(it)) {\n throw TypeError(String(it) + ' is not an object');\n } return it;\n};\n","var DESCRIPTORS = require('../internals/descriptors');\nvar IE8_DOM_DEFINE = require('../internals/ie8-dom-define');\nvar anObject = require('../internals/an-object');\nvar toPrimitive = require('../internals/to-primitive');\n\nvar nativeDefineProperty = Object.defineProperty;\n\n// `Object.defineProperty` method\n// https://tc39.github.io/ecma262/#sec-object.defineproperty\nexports.f = DESCRIPTORS ? nativeDefineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return nativeDefineProperty(O, P, Attributes);\n } catch (error) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","var DESCRIPTORS = require('../internals/descriptors');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = DESCRIPTORS ? function (object, key, value) {\n return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","var global = require('../internals/global');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\n\nmodule.exports = function (key, value) {\n try {\n createNonEnumerableProperty(global, key, value);\n } catch (error) {\n global[key] = value;\n } return value;\n};\n","var global = require('../internals/global');\nvar setGlobal = require('../internals/set-global');\n\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || setGlobal(SHARED, {});\n\nmodule.exports = store;\n","var store = require('../internals/shared-store');\n\nvar functionToString = Function.toString;\n\n// this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper\nif (typeof store.inspectSource != 'function') {\n store.inspectSource = function (it) {\n return functionToString.call(it);\n };\n}\n\nmodule.exports = store.inspectSource;\n","var NATIVE_WEAK_MAP = require('../internals/native-weak-map');\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar objectHas = require('../internals/has');\nvar sharedKey = require('../internals/shared-key');\nvar hiddenKeys = require('../internals/hidden-keys');\n\nvar WeakMap = global.WeakMap;\nvar set, get, has;\n\nvar enforce = function (it) {\n return has(it) ? get(it) : set(it, {});\n};\n\nvar getterFor = function (TYPE) {\n return function (it) {\n var state;\n if (!isObject(it) || (state = get(it)).type !== TYPE) {\n throw TypeError('Incompatible receiver, ' + TYPE + ' required');\n } return state;\n };\n};\n\nif (NATIVE_WEAK_MAP) {\n var store = new WeakMap();\n var wmget = store.get;\n var wmhas = store.has;\n var wmset = store.set;\n set = function (it, metadata) {\n wmset.call(store, it, metadata);\n return metadata;\n };\n get = function (it) {\n return wmget.call(store, it) || {};\n };\n has = function (it) {\n return wmhas.call(store, it);\n };\n} else {\n var STATE = sharedKey('state');\n hiddenKeys[STATE] = true;\n set = function (it, metadata) {\n createNonEnumerableProperty(it, STATE, metadata);\n return metadata;\n };\n get = function (it) {\n return objectHas(it, STATE) ? it[STATE] : {};\n };\n has = function (it) {\n return objectHas(it, STATE);\n };\n}\n\nmodule.exports = {\n set: set,\n get: get,\n has: has,\n enforce: enforce,\n getterFor: getterFor\n};\n","var global = require('../internals/global');\nvar inspectSource = require('../internals/inspect-source');\n\nvar WeakMap = global.WeakMap;\n\nmodule.exports = typeof WeakMap === 'function' && /native code/.test(inspectSource(WeakMap));\n","var IS_PURE = require('../internals/is-pure');\nvar store = require('../internals/shared-store');\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: '3.6.5',\n mode: IS_PURE ? 'pure' : 'global',\n copyright: '© 2020 Denis Pushkarev (zloirock.ru)'\n});\n","var id = 0;\nvar postfix = Math.random();\n\nmodule.exports = function (key) {\n return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);\n};\n","var shared = require('../internals/shared');\nvar uid = require('../internals/uid');\n\nvar keys = shared('keys');\n\nmodule.exports = function (key) {\n return keys[key] || (keys[key] = uid(key));\n};\n","module.exports = {};\n","var global = require('../internals/global');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar has = require('../internals/has');\nvar setGlobal = require('../internals/set-global');\nvar inspectSource = require('../internals/inspect-source');\nvar InternalStateModule = require('../internals/internal-state');\n\nvar getInternalState = InternalStateModule.get;\nvar enforceInternalState = InternalStateModule.enforce;\nvar TEMPLATE = String(String).split('String');\n\n(module.exports = function (O, key, value, options) {\n var unsafe = options ? !!options.unsafe : false;\n var simple = options ? !!options.enumerable : false;\n var noTargetGet = options ? !!options.noTargetGet : false;\n if (typeof value == 'function') {\n if (typeof key == 'string' && !has(value, 'name')) createNonEnumerableProperty(value, 'name', key);\n enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');\n }\n if (O === global) {\n if (simple) O[key] = value;\n else setGlobal(key, value);\n return;\n } else if (!unsafe) {\n delete O[key];\n } else if (!noTargetGet && O[key]) {\n simple = true;\n }\n if (simple) O[key] = value;\n else createNonEnumerableProperty(O, key, value);\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, 'toString', function toString() {\n return typeof this == 'function' && getInternalState(this).source || inspectSource(this);\n});\n","var global = require('../internals/global');\n\nmodule.exports = global;\n","var path = require('../internals/path');\nvar global = require('../internals/global');\n\nvar aFunction = function (variable) {\n return typeof variable == 'function' ? variable : undefined;\n};\n\nmodule.exports = function (namespace, method) {\n return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global[namespace])\n : path[namespace] && path[namespace][method] || global[namespace] && global[namespace][method];\n};\n","var ceil = Math.ceil;\nvar floor = Math.floor;\n\n// `ToInteger` abstract operation\n// https://tc39.github.io/ecma262/#sec-tointeger\nmodule.exports = function (argument) {\n return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);\n};\n","var toInteger = require('../internals/to-integer');\n\nvar min = Math.min;\n\n// `ToLength` abstract operation\n// https://tc39.github.io/ecma262/#sec-tolength\nmodule.exports = function (argument) {\n return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991\n};\n","var toInteger = require('../internals/to-integer');\n\nvar max = Math.max;\nvar min = Math.min;\n\n// Helper for a popular repeating case of the spec:\n// Let integer be ? ToInteger(index).\n// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).\nmodule.exports = function (index, length) {\n var integer = toInteger(index);\n return integer < 0 ? max(integer + length, 0) : min(integer, length);\n};\n","var toIndexedObject = require('../internals/to-indexed-object');\nvar toLength = require('../internals/to-length');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\n\n// `Array.prototype.{ indexOf, includes }` methods implementation\nvar createMethod = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIndexedObject($this);\n var length = toLength(O.length);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) {\n if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.includes` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.includes\n includes: createMethod(true),\n // `Array.prototype.indexOf` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.indexof\n indexOf: createMethod(false)\n};\n","var has = require('../internals/has');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar indexOf = require('../internals/array-includes').indexOf;\nvar hiddenKeys = require('../internals/hidden-keys');\n\nmodule.exports = function (object, names) {\n var O = toIndexedObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (has(O, key = names[i++])) {\n ~indexOf(result, key) || result.push(key);\n }\n return result;\n};\n","// IE8- don't enum bug keys\nmodule.exports = [\n 'constructor',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n 'toString',\n 'valueOf'\n];\n","var internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\nvar hiddenKeys = enumBugKeys.concat('length', 'prototype');\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.github.io/ecma262/#sec-object.getownpropertynames\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n return internalObjectKeys(O, hiddenKeys);\n};\n","exports.f = Object.getOwnPropertySymbols;\n","var getBuiltIn = require('../internals/get-built-in');\nvar getOwnPropertyNamesModule = require('../internals/object-get-own-property-names');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar anObject = require('../internals/an-object');\n\n// all object keys, includes non-enumerable and symbols\nmodule.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {\n var keys = getOwnPropertyNamesModule.f(anObject(it));\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;\n};\n","var has = require('../internals/has');\nvar ownKeys = require('../internals/own-keys');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar definePropertyModule = require('../internals/object-define-property');\n\nmodule.exports = function (target, source) {\n var keys = ownKeys(source);\n var defineProperty = definePropertyModule.f;\n var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));\n }\n};\n","var fails = require('../internals/fails');\n\nvar replacement = /#|\\.prototype\\./;\n\nvar isForced = function (feature, detection) {\n var value = data[normalize(feature)];\n return value == POLYFILL ? true\n : value == NATIVE ? false\n : typeof detection == 'function' ? fails(detection)\n : !!detection;\n};\n\nvar normalize = isForced.normalize = function (string) {\n return String(string).replace(replacement, '.').toLowerCase();\n};\n\nvar data = isForced.data = {};\nvar NATIVE = isForced.NATIVE = 'N';\nvar POLYFILL = isForced.POLYFILL = 'P';\n\nmodule.exports = isForced;\n","var global = require('../internals/global');\nvar getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar redefine = require('../internals/redefine');\nvar setGlobal = require('../internals/set-global');\nvar copyConstructorProperties = require('../internals/copy-constructor-properties');\nvar isForced = require('../internals/is-forced');\n\n/*\n options.target - name of the target object\n options.global - target is the global object\n options.stat - export as static methods of target\n options.proto - export as prototype methods of target\n options.real - real prototype method for the `pure` version\n options.forced - export even if the native feature is available\n options.bind - bind methods to the target, required for the `pure` version\n options.wrap - wrap constructors to preventing global pollution, required for the `pure` version\n options.unsafe - use the simple assignment of property instead of delete + defineProperty\n options.sham - add a flag to not completely full polyfills\n options.enumerable - export as enumerable property\n options.noTargetGet - prevent calling a getter on target\n*/\nmodule.exports = function (options, source) {\n var TARGET = options.target;\n var GLOBAL = options.global;\n var STATIC = options.stat;\n var FORCED, target, key, targetProperty, sourceProperty, descriptor;\n if (GLOBAL) {\n target = global;\n } else if (STATIC) {\n target = global[TARGET] || setGlobal(TARGET, {});\n } else {\n target = (global[TARGET] || {}).prototype;\n }\n if (target) for (key in source) {\n sourceProperty = source[key];\n if (options.noTargetGet) {\n descriptor = getOwnPropertyDescriptor(target, key);\n targetProperty = descriptor && descriptor.value;\n } else targetProperty = target[key];\n FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);\n // contained in target\n if (!FORCED && targetProperty !== undefined) {\n if (typeof sourceProperty === typeof targetProperty) continue;\n copyConstructorProperties(sourceProperty, targetProperty);\n }\n // add a flag to not completely full polyfills\n if (options.sham || (targetProperty && targetProperty.sham)) {\n createNonEnumerableProperty(sourceProperty, 'sham', true);\n }\n // extend global\n redefine(target, key, sourceProperty, options);\n }\n};\n","'use strict';\nvar fails = require('../internals/fails');\n\nmodule.exports = function (METHOD_NAME, argument) {\n var method = [][METHOD_NAME];\n return !!method && fails(function () {\n // eslint-disable-next-line no-useless-call,no-throw-literal\n method.call(null, argument || function () { throw 1; }, 1);\n });\n};\n","var DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\nvar has = require('../internals/has');\n\nvar defineProperty = Object.defineProperty;\nvar cache = {};\n\nvar thrower = function (it) { throw it; };\n\nmodule.exports = function (METHOD_NAME, options) {\n if (has(cache, METHOD_NAME)) return cache[METHOD_NAME];\n if (!options) options = {};\n var method = [][METHOD_NAME];\n var ACCESSORS = has(options, 'ACCESSORS') ? options.ACCESSORS : false;\n var argument0 = has(options, 0) ? options[0] : thrower;\n var argument1 = has(options, 1) ? options[1] : undefined;\n\n return cache[METHOD_NAME] = !!method && !fails(function () {\n if (ACCESSORS && !DESCRIPTORS) return true;\n var O = { length: -1 };\n\n if (ACCESSORS) defineProperty(O, 1, { enumerable: true, get: thrower });\n else O[1] = 1;\n\n method.call(O, argument0, argument1);\n });\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar $indexOf = require('../internals/array-includes').indexOf;\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar nativeIndexOf = [].indexOf;\n\nvar NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;\nvar STRICT_METHOD = arrayMethodIsStrict('indexOf');\nvar USES_TO_LENGTH = arrayMethodUsesToLength('indexOf', { ACCESSORS: true, 1: 0 });\n\n// `Array.prototype.indexOf` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.indexof\n$({ target: 'Array', proto: true, forced: NEGATIVE_ZERO || !STRICT_METHOD || !USES_TO_LENGTH }, {\n indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {\n return NEGATIVE_ZERO\n // convert -0 to +0\n ? nativeIndexOf.apply(this, arguments) || 0\n : $indexOf(this, searchElement, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n","var isObject = require('../internals/is-object');\n\nmodule.exports = function (it) {\n if (!isObject(it) && it !== null) {\n throw TypeError(\"Can't set \" + String(it) + ' as a prototype');\n } return it;\n};\n","var anObject = require('../internals/an-object');\nvar defineProperties = require('../internals/object-define-properties');\nvar enumBugKeys = require('../internals/enum-bug-keys');\nvar hiddenKeys = require('../internals/hidden-keys');\nvar html = require('../internals/html');\nvar documentCreateElement = require('../internals/document-create-element');\nvar sharedKey = require('../internals/shared-key');\n\nvar GT = '>';\nvar LT = '<';\nvar PROTOTYPE = 'prototype';\nvar SCRIPT = 'script';\nvar IE_PROTO = sharedKey('IE_PROTO');\n\nvar EmptyConstructor = function () { /* empty */ };\n\nvar scriptTag = function (content) {\n return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;\n};\n\n// Create object with fake `null` prototype: use ActiveX Object with cleared prototype\nvar NullProtoObjectViaActiveX = function (activeXDocument) {\n activeXDocument.write(scriptTag(''));\n activeXDocument.close();\n var temp = activeXDocument.parentWindow.Object;\n activeXDocument = null; // avoid memory leak\n return temp;\n};\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar NullProtoObjectViaIFrame = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = documentCreateElement('iframe');\n var JS = 'java' + SCRIPT + ':';\n var iframeDocument;\n iframe.style.display = 'none';\n html.appendChild(iframe);\n // https://github.com/zloirock/core-js/issues/475\n iframe.src = String(JS);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(scriptTag('document.F=Object'));\n iframeDocument.close();\n return iframeDocument.F;\n};\n\n// Check for document.domain and active x support\n// No need to use active x approach when document.domain is not set\n// see https://github.com/es-shims/es5-shim/issues/150\n// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346\n// avoid IE GC bug\nvar activeXDocument;\nvar NullProtoObject = function () {\n try {\n /* global ActiveXObject */\n activeXDocument = document.domain && new ActiveXObject('htmlfile');\n } catch (error) { /* ignore */ }\n NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();\n var length = enumBugKeys.length;\n while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];\n return NullProtoObject();\n};\n\nhiddenKeys[IE_PROTO] = true;\n\n// `Object.create` method\n// https://tc39.github.io/ecma262/#sec-object.create\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n EmptyConstructor[PROTOTYPE] = anObject(O);\n result = new EmptyConstructor();\n EmptyConstructor[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = NullProtoObject();\n return Properties === undefined ? result : defineProperties(result, Properties);\n};\n","var anObject = require('../internals/an-object');\nvar aPossiblePrototype = require('../internals/a-possible-prototype');\n\n// `Object.setPrototypeOf` method\n// https://tc39.github.io/ecma262/#sec-object.setprototypeof\n// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nmodule.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () {\n var CORRECT_SETTER = false;\n var test = {};\n var setter;\n try {\n setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;\n setter.call(test, []);\n CORRECT_SETTER = test instanceof Array;\n } catch (error) { /* empty */ }\n return function setPrototypeOf(O, proto) {\n anObject(O);\n aPossiblePrototype(proto);\n if (CORRECT_SETTER) setter.call(O, proto);\n else O.__proto__ = proto;\n return O;\n };\n}() : undefined);\n","var isObject = require('../internals/is-object');\nvar setPrototypeOf = require('../internals/object-set-prototype-of');\n\n// makes subclassing work correct for wrapped built-ins\nmodule.exports = function ($this, dummy, Wrapper) {\n var NewTarget, NewTargetPrototype;\n if (\n // it can work only with native `setPrototypeOf`\n setPrototypeOf &&\n // we haven't completely correct pre-ES6 way for getting `new.target`, so use this\n typeof (NewTarget = dummy.constructor) == 'function' &&\n NewTarget !== Wrapper &&\n isObject(NewTargetPrototype = NewTarget.prototype) &&\n NewTargetPrototype !== Wrapper.prototype\n ) setPrototypeOf($this, NewTargetPrototype);\n return $this;\n};\n","var internalObjectKeys = require('../internals/object-keys-internal');\nvar enumBugKeys = require('../internals/enum-bug-keys');\n\n// `Object.keys` method\n// https://tc39.github.io/ecma262/#sec-object.keys\nmodule.exports = Object.keys || function keys(O) {\n return internalObjectKeys(O, enumBugKeys);\n};\n","var DESCRIPTORS = require('../internals/descriptors');\nvar definePropertyModule = require('../internals/object-define-property');\nvar anObject = require('../internals/an-object');\nvar objectKeys = require('../internals/object-keys');\n\n// `Object.defineProperties` method\n// https://tc39.github.io/ecma262/#sec-object.defineproperties\nmodule.exports = DESCRIPTORS ? Object.defineProperties : function defineProperties(O, Properties) {\n anObject(O);\n var keys = objectKeys(Properties);\n var length = keys.length;\n var index = 0;\n var key;\n while (length > index) definePropertyModule.f(O, key = keys[index++], Properties[key]);\n return O;\n};\n","var getBuiltIn = require('../internals/get-built-in');\n\nmodule.exports = getBuiltIn('document', 'documentElement');\n","// a string of all valid unicode whitespaces\n// eslint-disable-next-line max-len\nmodule.exports = '\\u0009\\u000A\\u000B\\u000C\\u000D\\u0020\\u00A0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n","var requireObjectCoercible = require('../internals/require-object-coercible');\nvar whitespaces = require('../internals/whitespaces');\n\nvar whitespace = '[' + whitespaces + ']';\nvar ltrim = RegExp('^' + whitespace + whitespace + '*');\nvar rtrim = RegExp(whitespace + whitespace + '*$');\n\n// `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation\nvar createMethod = function (TYPE) {\n return function ($this) {\n var string = String(requireObjectCoercible($this));\n if (TYPE & 1) string = string.replace(ltrim, '');\n if (TYPE & 2) string = string.replace(rtrim, '');\n return string;\n };\n};\n\nmodule.exports = {\n // `String.prototype.{ trimLeft, trimStart }` methods\n // https://tc39.github.io/ecma262/#sec-string.prototype.trimstart\n start: createMethod(1),\n // `String.prototype.{ trimRight, trimEnd }` methods\n // https://tc39.github.io/ecma262/#sec-string.prototype.trimend\n end: createMethod(2),\n // `String.prototype.trim` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.trim\n trim: createMethod(3)\n};\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar global = require('../internals/global');\nvar isForced = require('../internals/is-forced');\nvar redefine = require('../internals/redefine');\nvar has = require('../internals/has');\nvar classof = require('../internals/classof-raw');\nvar inheritIfRequired = require('../internals/inherit-if-required');\nvar toPrimitive = require('../internals/to-primitive');\nvar fails = require('../internals/fails');\nvar create = require('../internals/object-create');\nvar getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;\nvar defineProperty = require('../internals/object-define-property').f;\nvar trim = require('../internals/string-trim').trim;\n\nvar NUMBER = 'Number';\nvar NativeNumber = global[NUMBER];\nvar NumberPrototype = NativeNumber.prototype;\n\n// Opera ~12 has broken Object#toString\nvar BROKEN_CLASSOF = classof(create(NumberPrototype)) == NUMBER;\n\n// `ToNumber` abstract operation\n// https://tc39.github.io/ecma262/#sec-tonumber\nvar toNumber = function (argument) {\n var it = toPrimitive(argument, false);\n var first, third, radix, maxCode, digits, length, index, code;\n if (typeof it == 'string' && it.length > 2) {\n it = trim(it);\n first = it.charCodeAt(0);\n if (first === 43 || first === 45) {\n third = it.charCodeAt(2);\n if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix\n } else if (first === 48) {\n switch (it.charCodeAt(1)) {\n case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i\n case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i\n default: return +it;\n }\n digits = it.slice(2);\n length = digits.length;\n for (index = 0; index < length; index++) {\n code = digits.charCodeAt(index);\n // parseInt parses a string to a first unavailable symbol\n // but ToNumber should return NaN if a string contains unavailable symbols\n if (code < 48 || code > maxCode) return NaN;\n } return parseInt(digits, radix);\n }\n } return +it;\n};\n\n// `Number` constructor\n// https://tc39.github.io/ecma262/#sec-number-constructor\nif (isForced(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) {\n var NumberWrapper = function Number(value) {\n var it = arguments.length < 1 ? 0 : value;\n var dummy = this;\n return dummy instanceof NumberWrapper\n // check on 1..constructor(foo) case\n && (BROKEN_CLASSOF ? fails(function () { NumberPrototype.valueOf.call(dummy); }) : classof(dummy) != NUMBER)\n ? inheritIfRequired(new NativeNumber(toNumber(it)), dummy, NumberWrapper) : toNumber(it);\n };\n for (var keys = DESCRIPTORS ? getOwnPropertyNames(NativeNumber) : (\n // ES3:\n 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +\n // ES2015 (in case, if modules with ES2015 Number statics required before):\n 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +\n 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'\n ).split(','), j = 0, key; keys.length > j; j++) {\n if (has(NativeNumber, key = keys[j]) && !has(NumberWrapper, key)) {\n defineProperty(NumberWrapper, key, getOwnPropertyDescriptor(NativeNumber, key));\n }\n }\n NumberWrapper.prototype = NumberPrototype;\n NumberPrototype.constructor = NumberWrapper;\n redefine(global, NUMBER, NumberWrapper);\n}\n","var $ = require('../internals/export');\n\n// `Number.isNaN` method\n// https://tc39.github.io/ecma262/#sec-number.isnan\n$({ target: 'Number', stat: true }, {\n isNaN: function isNaN(number) {\n // eslint-disable-next-line no-self-compare\n return number != number;\n }\n});\n","var classof = require('../internals/classof-raw');\n\n// `thisNumberValue` abstract operation\n// https://tc39.github.io/ecma262/#sec-thisnumbervalue\nmodule.exports = function (value) {\n if (typeof value != 'number' && classof(value) != 'Number') {\n throw TypeError('Incorrect invocation');\n }\n return +value;\n};\n","'use strict';\nvar toInteger = require('../internals/to-integer');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\n// `String.prototype.repeat` method implementation\n// https://tc39.github.io/ecma262/#sec-string.prototype.repeat\nmodule.exports = ''.repeat || function repeat(count) {\n var str = String(requireObjectCoercible(this));\n var result = '';\n var n = toInteger(count);\n if (n < 0 || n == Infinity) throw RangeError('Wrong number of repetitions');\n for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) result += str;\n return result;\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar toInteger = require('../internals/to-integer');\nvar thisNumberValue = require('../internals/this-number-value');\nvar repeat = require('../internals/string-repeat');\nvar fails = require('../internals/fails');\n\nvar nativeToFixed = 1.0.toFixed;\nvar floor = Math.floor;\n\nvar pow = function (x, n, acc) {\n return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);\n};\n\nvar log = function (x) {\n var n = 0;\n var x2 = x;\n while (x2 >= 4096) {\n n += 12;\n x2 /= 4096;\n }\n while (x2 >= 2) {\n n += 1;\n x2 /= 2;\n } return n;\n};\n\nvar FORCED = nativeToFixed && (\n 0.00008.toFixed(3) !== '0.000' ||\n 0.9.toFixed(0) !== '1' ||\n 1.255.toFixed(2) !== '1.25' ||\n 1000000000000000128.0.toFixed(0) !== '1000000000000000128'\n) || !fails(function () {\n // V8 ~ Android 4.3-\n nativeToFixed.call({});\n});\n\n// `Number.prototype.toFixed` method\n// https://tc39.github.io/ecma262/#sec-number.prototype.tofixed\n$({ target: 'Number', proto: true, forced: FORCED }, {\n // eslint-disable-next-line max-statements\n toFixed: function toFixed(fractionDigits) {\n var number = thisNumberValue(this);\n var fractDigits = toInteger(fractionDigits);\n var data = [0, 0, 0, 0, 0, 0];\n var sign = '';\n var result = '0';\n var e, z, j, k;\n\n var multiply = function (n, c) {\n var index = -1;\n var c2 = c;\n while (++index < 6) {\n c2 += n * data[index];\n data[index] = c2 % 1e7;\n c2 = floor(c2 / 1e7);\n }\n };\n\n var divide = function (n) {\n var index = 6;\n var c = 0;\n while (--index >= 0) {\n c += data[index];\n data[index] = floor(c / n);\n c = (c % n) * 1e7;\n }\n };\n\n var dataToString = function () {\n var index = 6;\n var s = '';\n while (--index >= 0) {\n if (s !== '' || index === 0 || data[index] !== 0) {\n var t = String(data[index]);\n s = s === '' ? t : s + repeat.call('0', 7 - t.length) + t;\n }\n } return s;\n };\n\n if (fractDigits < 0 || fractDigits > 20) throw RangeError('Incorrect fraction digits');\n // eslint-disable-next-line no-self-compare\n if (number != number) return 'NaN';\n if (number <= -1e21 || number >= 1e21) return String(number);\n if (number < 0) {\n sign = '-';\n number = -number;\n }\n if (number > 1e-21) {\n e = log(number * pow(2, 69, 1)) - 69;\n z = e < 0 ? number * pow(2, -e, 1) : number / pow(2, e, 1);\n z *= 0x10000000000000;\n e = 52 - e;\n if (e > 0) {\n multiply(0, z);\n j = fractDigits;\n while (j >= 7) {\n multiply(1e7, 0);\n j -= 7;\n }\n multiply(pow(10, j, 1), 0);\n j = e - 1;\n while (j >= 23) {\n divide(1 << 23);\n j -= 23;\n }\n divide(1 << j);\n multiply(1, 1);\n divide(2);\n result = dataToString();\n } else {\n multiply(0, z);\n multiply(1 << -e, 0);\n result = dataToString() + repeat.call('0', fractDigits);\n }\n }\n if (fractDigits > 0) {\n k = result.length;\n result = sign + (k <= fractDigits\n ? '0.' + repeat.call('0', fractDigits - k) + result\n : result.slice(0, k - fractDigits) + '.' + result.slice(k - fractDigits));\n } else {\n result = sign + result;\n } return result;\n }\n});\n","var fails = require('../internals/fails');\n\nmodule.exports = !!Object.getOwnPropertySymbols && !fails(function () {\n // Chrome 38 Symbol has incorrect toString conversion\n // eslint-disable-next-line no-undef\n return !String(Symbol());\n});\n","var NATIVE_SYMBOL = require('../internals/native-symbol');\n\nmodule.exports = NATIVE_SYMBOL\n // eslint-disable-next-line no-undef\n && !Symbol.sham\n // eslint-disable-next-line no-undef\n && typeof Symbol.iterator == 'symbol';\n","var global = require('../internals/global');\nvar shared = require('../internals/shared');\nvar has = require('../internals/has');\nvar uid = require('../internals/uid');\nvar NATIVE_SYMBOL = require('../internals/native-symbol');\nvar USE_SYMBOL_AS_UID = require('../internals/use-symbol-as-uid');\n\nvar WellKnownSymbolsStore = shared('wks');\nvar Symbol = global.Symbol;\nvar createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol : Symbol && Symbol.withoutSetter || uid;\n\nmodule.exports = function (name) {\n if (!has(WellKnownSymbolsStore, name)) {\n if (NATIVE_SYMBOL && has(Symbol, name)) WellKnownSymbolsStore[name] = Symbol[name];\n else WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);\n } return WellKnownSymbolsStore[name];\n};\n","var wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar test = {};\n\ntest[TO_STRING_TAG] = 'z';\n\nmodule.exports = String(test) === '[object z]';\n","var TO_STRING_TAG_SUPPORT = require('../internals/to-string-tag-support');\nvar classofRaw = require('../internals/classof-raw');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\n// ES3 wrong here\nvar CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (error) { /* empty */ }\n};\n\n// getting tag from ES6+ `Object.prototype.toString`\nmodule.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {\n var O, tag, result;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG)) == 'string' ? tag\n // builtinTag case\n : CORRECT_ARGUMENTS ? classofRaw(O)\n // ES3 arguments fallback\n : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;\n};\n","'use strict';\nvar TO_STRING_TAG_SUPPORT = require('../internals/to-string-tag-support');\nvar classof = require('../internals/classof');\n\n// `Object.prototype.toString` method implementation\n// https://tc39.github.io/ecma262/#sec-object.prototype.tostring\nmodule.exports = TO_STRING_TAG_SUPPORT ? {}.toString : function toString() {\n return '[object ' + classof(this) + ']';\n};\n","var TO_STRING_TAG_SUPPORT = require('../internals/to-string-tag-support');\nvar redefine = require('../internals/redefine');\nvar toString = require('../internals/object-to-string');\n\n// `Object.prototype.toString` method\n// https://tc39.github.io/ecma262/#sec-object.prototype.tostring\nif (!TO_STRING_TAG_SUPPORT) {\n redefine(Object.prototype, 'toString', toString, { unsafe: true });\n}\n","'use strict';\nvar anObject = require('../internals/an-object');\n\n// `RegExp.prototype.flags` getter implementation\n// https://tc39.github.io/ecma262/#sec-get-regexp.prototype.flags\nmodule.exports = function () {\n var that = anObject(this);\n var result = '';\n if (that.global) result += 'g';\n if (that.ignoreCase) result += 'i';\n if (that.multiline) result += 'm';\n if (that.dotAll) result += 's';\n if (that.unicode) result += 'u';\n if (that.sticky) result += 'y';\n return result;\n};\n","'use strict';\n\nvar fails = require('./fails');\n\n// babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError,\n// so we use an intermediate function.\nfunction RE(s, f) {\n return RegExp(s, f);\n}\n\nexports.UNSUPPORTED_Y = fails(function () {\n // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError\n var re = RE('a', 'y');\n re.lastIndex = 2;\n return re.exec('abcd') != null;\n});\n\nexports.BROKEN_CARET = fails(function () {\n // https://bugzilla.mozilla.org/show_bug.cgi?id=773687\n var re = RE('^r', 'gy');\n re.lastIndex = 2;\n return re.exec('str') != null;\n});\n","'use strict';\nvar regexpFlags = require('./regexp-flags');\nvar stickyHelpers = require('./regexp-sticky-helpers');\n\nvar nativeExec = RegExp.prototype.exec;\n// This always refers to the native implementation, because the\n// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,\n// which loads this file before patching the method.\nvar nativeReplace = String.prototype.replace;\n\nvar patchedExec = nativeExec;\n\nvar UPDATES_LAST_INDEX_WRONG = (function () {\n var re1 = /a/;\n var re2 = /b*/g;\n nativeExec.call(re1, 'a');\n nativeExec.call(re2, 'a');\n return re1.lastIndex !== 0 || re2.lastIndex !== 0;\n})();\n\nvar UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y || stickyHelpers.BROKEN_CARET;\n\n// nonparticipating capturing group, copied from es5-shim's String#split patch.\nvar NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;\n\nvar PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y;\n\nif (PATCH) {\n patchedExec = function exec(str) {\n var re = this;\n var lastIndex, reCopy, match, i;\n var sticky = UNSUPPORTED_Y && re.sticky;\n var flags = regexpFlags.call(re);\n var source = re.source;\n var charsAdded = 0;\n var strCopy = str;\n\n if (sticky) {\n flags = flags.replace('y', '');\n if (flags.indexOf('g') === -1) {\n flags += 'g';\n }\n\n strCopy = String(str).slice(re.lastIndex);\n // Support anchored sticky behavior.\n if (re.lastIndex > 0 && (!re.multiline || re.multiline && str[re.lastIndex - 1] !== '\\n')) {\n source = '(?: ' + source + ')';\n strCopy = ' ' + strCopy;\n charsAdded++;\n }\n // ^(? + rx + ) is needed, in combination with some str slicing, to\n // simulate the 'y' flag.\n reCopy = new RegExp('^(?:' + source + ')', flags);\n }\n\n if (NPCG_INCLUDED) {\n reCopy = new RegExp('^' + source + '$(?!\\\\s)', flags);\n }\n if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;\n\n match = nativeExec.call(sticky ? reCopy : re, strCopy);\n\n if (sticky) {\n if (match) {\n match.input = match.input.slice(charsAdded);\n match[0] = match[0].slice(charsAdded);\n match.index = re.lastIndex;\n re.lastIndex += match[0].length;\n } else re.lastIndex = 0;\n } else if (UPDATES_LAST_INDEX_WRONG && match) {\n re.lastIndex = re.global ? match.index + match[0].length : lastIndex;\n }\n if (NPCG_INCLUDED && match && match.length > 1) {\n // Fix browsers whose `exec` methods don't consistently return `undefined`\n // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/\n nativeReplace.call(match[0], reCopy, function () {\n for (i = 1; i < arguments.length - 2; i++) {\n if (arguments[i] === undefined) match[i] = undefined;\n }\n });\n }\n\n return match;\n };\n}\n\nmodule.exports = patchedExec;\n","'use strict';\nvar $ = require('../internals/export');\nvar exec = require('../internals/regexp-exec');\n\n$({ target: 'RegExp', proto: true, forced: /./.exec !== exec }, {\n exec: exec\n});\n","'use strict';\nvar redefine = require('../internals/redefine');\nvar anObject = require('../internals/an-object');\nvar fails = require('../internals/fails');\nvar flags = require('../internals/regexp-flags');\n\nvar TO_STRING = 'toString';\nvar RegExpPrototype = RegExp.prototype;\nvar nativeToString = RegExpPrototype[TO_STRING];\n\nvar NOT_GENERIC = fails(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; });\n// FF44- RegExp#toString has a wrong name\nvar INCORRECT_NAME = nativeToString.name != TO_STRING;\n\n// `RegExp.prototype.toString` method\n// https://tc39.github.io/ecma262/#sec-regexp.prototype.tostring\nif (NOT_GENERIC || INCORRECT_NAME) {\n redefine(RegExp.prototype, TO_STRING, function toString() {\n var R = anObject(this);\n var p = String(R.source);\n var rf = R.flags;\n var f = String(rf === undefined && R instanceof RegExp && !('flags' in RegExpPrototype) ? flags.call(R) : rf);\n return '/' + p + '/' + f;\n }, { unsafe: true });\n}\n","'use strict';\n// TODO: Remove from `core-js@4` since it's moved to entry points\nrequire('../modules/es.regexp.exec');\nvar redefine = require('../internals/redefine');\nvar fails = require('../internals/fails');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar regexpExec = require('../internals/regexp-exec');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\n\nvar SPECIES = wellKnownSymbol('species');\n\nvar REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {\n // #replace needs built-in support for named groups.\n // #match works fine because it just return the exec results, even if it has\n // a \"grops\" property.\n var re = /./;\n re.exec = function () {\n var result = [];\n result.groups = { a: '7' };\n return result;\n };\n return ''.replace(re, '$') !== '7';\n});\n\n// IE <= 11 replaces $0 with the whole match, as if it was $&\n// https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0\nvar REPLACE_KEEPS_$0 = (function () {\n return 'a'.replace(/./, '$0') === '$0';\n})();\n\nvar REPLACE = wellKnownSymbol('replace');\n// Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string\nvar REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () {\n if (/./[REPLACE]) {\n return /./[REPLACE]('a', '$0') === '';\n }\n return false;\n})();\n\n// Chrome 51 has a buggy \"split\" implementation when RegExp#exec !== nativeExec\n// Weex JS has frozen built-in prototypes, so use try / catch wrapper\nvar SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {\n var re = /(?:)/;\n var originalExec = re.exec;\n re.exec = function () { return originalExec.apply(this, arguments); };\n var result = 'ab'.split(re);\n return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';\n});\n\nmodule.exports = function (KEY, length, exec, sham) {\n var SYMBOL = wellKnownSymbol(KEY);\n\n var DELEGATES_TO_SYMBOL = !fails(function () {\n // String methods call symbol-named RegEp methods\n var O = {};\n O[SYMBOL] = function () { return 7; };\n return ''[KEY](O) != 7;\n });\n\n var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {\n // Symbol-named RegExp methods call .exec\n var execCalled = false;\n var re = /a/;\n\n if (KEY === 'split') {\n // We can't use real regex here since it causes deoptimization\n // and serious performance degradation in V8\n // https://github.com/zloirock/core-js/issues/306\n re = {};\n // RegExp[@@split] doesn't call the regex's exec method, but first creates\n // a new one. We need to return the patched regex when creating the new one.\n re.constructor = {};\n re.constructor[SPECIES] = function () { return re; };\n re.flags = '';\n re[SYMBOL] = /./[SYMBOL];\n }\n\n re.exec = function () { execCalled = true; return null; };\n\n re[SYMBOL]('');\n return !execCalled;\n });\n\n if (\n !DELEGATES_TO_SYMBOL ||\n !DELEGATES_TO_EXEC ||\n (KEY === 'replace' && !(\n REPLACE_SUPPORTS_NAMED_GROUPS &&\n REPLACE_KEEPS_$0 &&\n !REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE\n )) ||\n (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)\n ) {\n var nativeRegExpMethod = /./[SYMBOL];\n var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {\n if (regexp.exec === regexpExec) {\n if (DELEGATES_TO_SYMBOL && !forceStringMethod) {\n // The native String method already delegates to @@method (this\n // polyfilled function), leasing to infinite recursion.\n // We avoid it by directly calling the native @@method method.\n return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };\n }\n return { done: true, value: nativeMethod.call(str, regexp, arg2) };\n }\n return { done: false };\n }, {\n REPLACE_KEEPS_$0: REPLACE_KEEPS_$0,\n REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE: REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE\n });\n var stringMethod = methods[0];\n var regexMethod = methods[1];\n\n redefine(String.prototype, KEY, stringMethod);\n redefine(RegExp.prototype, SYMBOL, length == 2\n // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n ? function (string, arg) { return regexMethod.call(string, this, arg); }\n // 21.2.5.6 RegExp.prototype[@@match](string)\n // 21.2.5.9 RegExp.prototype[@@search](string)\n : function (string) { return regexMethod.call(string, this); }\n );\n }\n\n if (sham) createNonEnumerableProperty(RegExp.prototype[SYMBOL], 'sham', true);\n};\n","var requireObjectCoercible = require('../internals/require-object-coercible');\n\n// `ToObject` abstract operation\n// https://tc39.github.io/ecma262/#sec-toobject\nmodule.exports = function (argument) {\n return Object(requireObjectCoercible(argument));\n};\n","var toInteger = require('../internals/to-integer');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\n\n// `String.prototype.{ codePointAt, at }` methods implementation\nvar createMethod = function (CONVERT_TO_STRING) {\n return function ($this, pos) {\n var S = String(requireObjectCoercible($this));\n var position = toInteger(pos);\n var size = S.length;\n var first, second;\n if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;\n first = S.charCodeAt(position);\n return first < 0xD800 || first > 0xDBFF || position + 1 === size\n || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF\n ? CONVERT_TO_STRING ? S.charAt(position) : first\n : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;\n };\n};\n\nmodule.exports = {\n // `String.prototype.codePointAt` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.codepointat\n codeAt: createMethod(false),\n // `String.prototype.at` method\n // https://github.com/mathiasbynens/String.prototype.at\n charAt: createMethod(true)\n};\n","'use strict';\nvar charAt = require('../internals/string-multibyte').charAt;\n\n// `AdvanceStringIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-advancestringindex\nmodule.exports = function (S, index, unicode) {\n return index + (unicode ? charAt(S, index).length : 1);\n};\n","var classof = require('./classof-raw');\nvar regexpExec = require('./regexp-exec');\n\n// `RegExpExec` abstract operation\n// https://tc39.github.io/ecma262/#sec-regexpexec\nmodule.exports = function (R, S) {\n var exec = R.exec;\n if (typeof exec === 'function') {\n var result = exec.call(R, S);\n if (typeof result !== 'object') {\n throw TypeError('RegExp exec method returned something other than an Object or null');\n }\n return result;\n }\n\n if (classof(R) !== 'RegExp') {\n throw TypeError('RegExp#exec called on incompatible receiver');\n }\n\n return regexpExec.call(R, S);\n};\n\n","'use strict';\nvar fixRegExpWellKnownSymbolLogic = require('../internals/fix-regexp-well-known-symbol-logic');\nvar anObject = require('../internals/an-object');\nvar toObject = require('../internals/to-object');\nvar toLength = require('../internals/to-length');\nvar toInteger = require('../internals/to-integer');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\nvar advanceStringIndex = require('../internals/advance-string-index');\nvar regExpExec = require('../internals/regexp-exec-abstract');\n\nvar max = Math.max;\nvar min = Math.min;\nvar floor = Math.floor;\nvar SUBSTITUTION_SYMBOLS = /\\$([$&'`]|\\d\\d?|<[^>]*>)/g;\nvar SUBSTITUTION_SYMBOLS_NO_NAMED = /\\$([$&'`]|\\d\\d?)/g;\n\nvar maybeToString = function (it) {\n return it === undefined ? it : String(it);\n};\n\n// @@replace logic\nfixRegExpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative, reason) {\n var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = reason.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE;\n var REPLACE_KEEPS_$0 = reason.REPLACE_KEEPS_$0;\n var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';\n\n return [\n // `String.prototype.replace` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.replace\n function replace(searchValue, replaceValue) {\n var O = requireObjectCoercible(this);\n var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];\n return replacer !== undefined\n ? replacer.call(searchValue, O, replaceValue)\n : nativeReplace.call(String(O), searchValue, replaceValue);\n },\n // `RegExp.prototype[@@replace]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace\n function (regexp, replaceValue) {\n if (\n (!REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE && REPLACE_KEEPS_$0) ||\n (typeof replaceValue === 'string' && replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1)\n ) {\n var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);\n if (res.done) return res.value;\n }\n\n var rx = anObject(regexp);\n var S = String(this);\n\n var functionalReplace = typeof replaceValue === 'function';\n if (!functionalReplace) replaceValue = String(replaceValue);\n\n var global = rx.global;\n if (global) {\n var fullUnicode = rx.unicode;\n rx.lastIndex = 0;\n }\n var results = [];\n while (true) {\n var result = regExpExec(rx, S);\n if (result === null) break;\n\n results.push(result);\n if (!global) break;\n\n var matchStr = String(result[0]);\n if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n }\n\n var accumulatedResult = '';\n var nextSourcePosition = 0;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n var matched = String(result[0]);\n var position = max(min(toInteger(result.index), S.length), 0);\n var captures = [];\n // NOTE: This is equivalent to\n // captures = result.slice(1).map(maybeToString)\n // but for some reason `nativeSlice.call(result, 1, result.length)` (called in\n // the slice polyfill when slicing native arrays) \"doesn't work\" in safari 9 and\n // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.\n for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));\n var namedCaptures = result.groups;\n if (functionalReplace) {\n var replacerArgs = [matched].concat(captures, position, S);\n if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);\n var replacement = String(replaceValue.apply(undefined, replacerArgs));\n } else {\n replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);\n }\n if (position >= nextSourcePosition) {\n accumulatedResult += S.slice(nextSourcePosition, position) + replacement;\n nextSourcePosition = position + matched.length;\n }\n }\n return accumulatedResult + S.slice(nextSourcePosition);\n }\n ];\n\n // https://tc39.github.io/ecma262/#sec-getsubstitution\n function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {\n var tailPos = position + matched.length;\n var m = captures.length;\n var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;\n if (namedCaptures !== undefined) {\n namedCaptures = toObject(namedCaptures);\n symbols = SUBSTITUTION_SYMBOLS;\n }\n return nativeReplace.call(replacement, symbols, function (match, ch) {\n var capture;\n switch (ch.charAt(0)) {\n case '$': return '$';\n case '&': return matched;\n case '`': return str.slice(0, position);\n case \"'\": return str.slice(tailPos);\n case '<':\n capture = namedCaptures[ch.slice(1, -1)];\n break;\n default: // \\d\\d?\n var n = +ch;\n if (n === 0) return match;\n if (n > m) {\n var f = floor(n / 10);\n if (f === 0) return match;\n if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);\n return match;\n }\n capture = captures[n - 1];\n }\n return capture === undefined ? '' : capture;\n });\n }\n});\n","const luckysheetConfigsetting = {\r\n autoFormatw: false,\r\n accuracy: undefined,\r\n total: 0,\r\n\r\n allowCopy: true,\r\n showtoolbar: true,\r\n showinfobar: true,\r\n showsheetbar: true,\r\n showstatisticBar: true,\r\n pointEdit: false,\r\n pointEditUpdate: null,\r\n pointEditZoom: 1,\r\n\r\n userInfo: false,\r\n userMenuItem: [],\r\n myFolderUrl: null,\r\n functionButton: null,\r\n\r\n showConfigWindowResize: true,\r\n enableAddRow: true,\r\n enableAddBackTop: true,\r\n enablePage: true,\r\n pageInfo: null,\r\n \r\n \r\n editMode: false,\r\n beforeCreateDom: null,\r\n workbookCreateBefore: null,\r\n workbookCreateAfter: null,\r\n fireMousedown: null,\r\n plugins:[],\r\n forceCalculation:false,//强制刷新公式,公式较多会有性能问题,慎用\r\n\r\n defaultColWidth:73,\r\n defaultRowHeight:19,\r\n\r\n defaultTextColor: '#000',\r\n defaultCellColor: '#fff',\r\n}\r\n\r\nexport default luckysheetConfigsetting;","const Store = {\r\n container: null, \r\n luckysheetfile: null, \r\n defaultcolumnNum: 60, \r\n defaultrowNum: 84, \r\n fullscreenmode: true,\r\n devicePixelRatio: 1,\r\n\r\n currentSheetIndex: 0,\r\n calculateSheetIndex: 0,\r\n\tflowdata: [],\r\n config: {},\r\n\r\n visibledatarow: [],\r\n visibledatacolumn: [],\r\n ch_width: 0,\r\n rh_height: 0,\r\n\r\n cellmainWidth: 0,\r\n cellmainHeight: 0,\r\n toolbarHeight: 0,\r\n infobarHeight: 0,\r\n calculatebarHeight: 0,\r\n rowHeaderWidth: 46,\r\n columnHeaderHeight: 20,\r\n cellMainSrollBarSize: 12,\r\n sheetBarHeight: 31,\r\n statisticBarHeight: 23,\r\n luckysheetTableContentHW: [0, 0], \r\n\r\n defaultcollen: 73,\r\n defaultrowlen: 19,\r\n\r\n jfcountfuncTimeout: null, \r\n jfautoscrollTimeout: null,\r\n\r\n luckysheet_select_status: false,\r\n luckysheet_select_save: [{ \"row\": [0, 0], \"column\": [0, 0] }],\r\n luckysheet_selection_range: [],\r\n\r\n luckysheet_copy_save: {}, //复制粘贴\r\n luckysheet_paste_iscut: false,\r\n\r\n filterchage: true, //筛选\r\n luckysheet_filter_save: { \"row\": [], \"column\": [] },\r\n\r\n luckysheet_sheet_move_status: false,\r\n luckysheet_sheet_move_data: [],\r\n luckysheet_scroll_status: false,\r\n\r\n luckysheetisrefreshdetail: true,\r\n luckysheetisrefreshtheme: true,\r\n luckysheetcurrentisPivotTable: false,\r\n\r\n luckysheet_rows_selected_status: false, //行列标题相关参\r\n luckysheet_cols_selected_status: false, \r\n luckysheet_rows_change_size: false,\r\n luckysheet_rows_change_size_start: [],\r\n luckysheet_cols_change_size: false,\r\n luckysheet_cols_change_size_start: [],\r\n luckysheet_cols_dbclick_timeout: null,\r\n luckysheet_cols_dbclick_times: 0,\r\n\r\n luckysheetCellUpdate: [],\r\n \r\n luckysheet_shiftpositon: null,\r\n\r\n iscopyself: true,\r\n\r\n orderbyindex: 0, //排序下标\r\n\r\n luckysheet_model_move_state: false, //模态框拖动\r\n luckysheet_model_xy: [0, 0],\r\n luckysheet_model_move_obj: null,\r\n\r\n luckysheet_cell_selected_move: false, //选区拖动替换\r\n luckysheet_cell_selected_move_index: [],\r\n\r\n luckysheet_cell_selected_extend: false, //选区下拉\r\n luckysheet_cell_selected_extend_index: [],\r\n luckysheet_cell_selected_extend_time: null,\r\n\r\n clearjfundo: true,\r\n jfundo: [],\r\n jfredo: [],\r\n lang: 'en', //language\r\n createChart: '',\r\n highlightChart: '',\r\n zIndex: 15,\r\n chartparam: {\r\n luckysheetCurrentChart: null, //current chart_id\r\n luckysheetCurrentChartActive: false,\r\n luckysheetCurrentChartMove: null, // Debounce state\r\n luckysheetCurrentChartMoveTimeout: null,//拖动图表框的节流定时器\r\n luckysheetCurrentChartMoveObj: null, //chart DOM object\r\n luckysheetCurrentChartMoveXy: null, //上一次操作结束的图表信息,x,y: chart框位置,scrollLeft1,scrollTop1: 滚动条位置\r\n luckysheetCurrentChartMoveWinH: null, //左右滚动条滑动距离\r\n luckysheetCurrentChartMoveWinW: null, //上下滚动条滑动距离\r\n luckysheetCurrentChartResize: null,\r\n luckysheetCurrentChartResizeObj: null,\r\n luckysheetCurrentChartResizeXy: null,\r\n luckysheetCurrentChartResizeWinH: null,\r\n luckysheetCurrentChartResizeWinW: null,\r\n luckysheetInsertChartTosheetChange: true, // 正在执行撤销\r\n luckysheetCurrentChartZIndexRank : 100,\r\n luckysheet_chart_redo_click:false, //撤销重做时标识\r\n luckysheetCurrentChartMaxState: false, //图表全屏状态\r\n jfrefreshchartall: '',\r\n changeChartCellData: '',\r\n renderChart: '',\r\n getChartJson: ''\r\n },\r\n functionList:null, //function list explanation\r\n luckysheet_function:null,\r\n chart_selection: {},\r\n currentChart: '',\r\n scrollRefreshSwitch:true,\r\n\r\n measureTextCache:{},\r\n measureTextCellInfoCache:{},\r\n measureTextCacheTimeOut:null,\r\n cellOverflowMapCache:{},\r\n\r\n zoomRatio:1,\r\n\r\n visibledatacolumn_unique:null,\r\n visibledatarow_unique:null,\r\n\r\n showGridLines:true,\r\n\r\n toobarObject: {}, //toolbar constant\r\n inlineStringEditCache:null,\r\n inlineStringEditRange:null,\r\n\r\n fontList:[],\r\n defaultFontSize: 10,\r\n\r\n currentSheetView:\"viewNormal\",\r\n\r\n // cooperative editing\r\n cooperativeEdit:{\r\n usernameTimeout:{\r\n\r\n },\r\n changeCollaborationSize:[], //改变行高或者列宽时,协同提示框需要跟随改变所需数据\r\n allDataColumnlen:[],//列宽发生过改变的列\r\n merge_range:{},//合并时单元格信息\r\n checkoutData:[],//切换表格页时所需数据\r\n },\r\n\r\n // Resources that currently need to be loaded asynchronously, especially plugins. 'Core' marks the core rendering process.\r\n asyncLoad:['core'],\r\n\r\n}\r\n\r\nexport default Store;","import luckysheetConfigsetting from '../controllers/luckysheetConfigsetting';\r\nimport Store from '../store';\r\n\r\nexport const error = {\r\n v: \"#VALUE!\", //错误的参数或运算符\r\n n: \"#NAME?\", //公式名称错误\r\n na: \"#N/A\", //函数或公式中没有可用数值\r\n r: \"#REF!\", //删除了由其他公式引用的单元格\r\n d: \"#DIV/0!\", //除数是0或空单元格\r\n nm: \"#NUM!\", //当公式或函数中某个数字有问题时\r\n nl: \"#NULL!\", //交叉运算符(空格)使用不正确\r\n sp: \"#SPILL!\" //数组范围有其它值\r\n}\r\n\r\n//是否是空值\r\nfunction isRealNull(val) {\r\n if(val == null || val.toString().replace(/\\s/g, \"\") == \"\"){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n}\r\n\r\n//是否是纯数字\r\nfunction isRealNum(val) {\r\n if(val == null || val.toString().replace(/\\s/g, \"\") === \"\"){\r\n return false;\r\n }\r\n\r\n if(typeof val == \"boolean\"){\r\n return false;\r\n }\r\n\r\n if(!isNaN(val)){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n}\r\n\r\n//是否是错误类型\r\nfunction valueIsError(value) {\r\n let isError = false;\r\n\r\n for(let x in error){\r\n if(value == error[x]){\r\n isError = true;\r\n break;\r\n }\r\n }\r\n\r\n return isError;\r\n}\r\n\r\n//是否有中文\r\nfunction hasChinaword(s) {\r\n let patrn = /[\\u4E00-\\u9FA5]|[\\uFE30-\\uFFA0]/gi;\r\n \r\n if (!patrn.exec(s)) {\r\n return false;\r\n }\r\n else {\r\n return true;\r\n }\r\n}\r\n\r\n//是否为非编辑模式\r\nfunction isEditMode() {\r\n if(luckysheetConfigsetting.editMode){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n}\r\n\r\n//范围是否只包含部分合并单元格\r\nfunction hasPartMC(cfg, r1, r2, c1, c2) {\r\n let hasPartMC = false;\r\n\r\n for(let x in Store.config[\"merge\"]){\r\n let mc = cfg[\"merge\"][x];\r\n\r\n if(r1 < mc.r){\r\n if(r2 >= mc.r && r2 < (mc.r + mc.rs - 1)){\r\n if(c1 >= mc.c && c1 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c2 >= mc.c && c2 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 < mc.c && c2 > (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n }\r\n else if(r2 >= mc.r && r2 == (mc.r + mc.rs - 1)){\r\n if(c1 > mc.c && c1 < (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c2 > mc.c && c2 < (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 == mc.c && c2 < (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 > mc.c && c2 == (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n }\r\n else if(r2 > (mc.r + mc.rs - 1)){\r\n if(c1 > mc.c && c1 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c2 >= mc.c && c2 < (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 == mc.c && c2 < (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 > mc.c && c2 == (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n }\r\n }\r\n else if(r1 == mc.r){\r\n if(r2 < (mc.r + mc.rs - 1)){\r\n if(c1 >= mc.c && c1 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c2 >= mc.c && c2 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 < mc.c && c2 > (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n }\r\n else if(r2 >= (mc.r + mc.rs - 1)){\r\n if(c1 > mc.c && c1 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c2 >= mc.c && c2 < (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 == mc.c && c2 < (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 > mc.c && c2 == (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n }\r\n }\r\n else if(r1 <= (mc.r + mc.rs - 1)){\r\n if(c1 >= mc.c && c1 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c2 >= mc.c && c2 <= (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n else if(c1 < mc.c && c2 > (mc.c + mc.cs - 1)){\r\n hasPartMC = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return hasPartMC;\r\n}\r\n\r\n//获取单个字符的字节数\r\nfunction checkWordByteLength(value) {\r\n return Math.ceil(value.charCodeAt().toString(2).length / 8);\r\n }\r\n \r\n\r\nexport {\r\n isRealNull,\r\n isRealNum,\r\n valueIsError,\r\n hasChinaword,\r\n isEditMode,\r\n hasPartMC,\r\n checkWordByteLength\r\n}","import { isRealNum } from '../global/validate';\r\n\r\n/*\r\n * 判断obj是否为一个整数\r\n */\r\nfunction isInteger(obj) {\r\n return Math.floor(obj) === obj;\r\n}\r\n\r\n/*\r\n * 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100\r\n * @param floatNum {number} 小数\r\n * @return {object}\r\n * {times:100, num: 314}\r\n */\r\nfunction toInteger(floatNum) {\r\n var ret = { times: 1, num: 0 };\r\n\r\n if (isInteger(floatNum)) {\r\n ret.num = floatNum;\r\n return ret;\r\n }\r\n\r\n var strfi = floatNum + '';\r\n var dotPos = strfi.indexOf('.');\r\n var len = strfi.substr(dotPos + 1).length;\r\n var times = Math.pow(10, len);\r\n var intNum = parseInt(floatNum * times + 0.5, 10);\r\n\r\n ret.times = times;\r\n ret.num = intNum;\r\n\r\n return ret;\r\n}\r\n\r\n/*\r\n * 核心方法,实现加减乘除运算,确保不丢失精度\r\n * 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除)\r\n *\r\n * @param a {number} 运算数1\r\n * @param b {number} 运算数2\r\n * @param digits {number} 精度,保留的小数点数,比如 2, 即保留为两位小数\r\n * @param op {string} 运算类型,有加减乘除(add/subtract/multiply/divide)\r\n *\r\n */\r\nfunction operation(a, b, op) {\r\n var o1 = toInteger(a);\r\n var o2 = toInteger(b);\r\n var n1 = o1.num;\r\n var n2 = o2.num;\r\n var t1 = o1.times;\r\n var t2 = o2.times;\r\n var max = t1 > t2 ? t1 : t2;\r\n var result = null;\r\n\r\n switch (op) {\r\n case 'add':\r\n if (t1 === t2) { // 两个小数位数相同\r\n result = n1 + n2;\r\n }\r\n else if (t1 > t2) { // o1 小数位 大于 o2\r\n result = n1 + n2 * (t1 / t2);\r\n }\r\n else { // o1 小数位 小于 o2\r\n result = n1 * (t2 / t1) + n2;\r\n }\r\n\r\n return result / max;\r\n case 'subtract':\r\n if (t1 === t2) {\r\n result = n1 - n2;\r\n }\r\n else if (t1 > t2) {\r\n result = n1 - n2 * (t1 / t2);\r\n }\r\n else {\r\n result = n1 * (t2 / t1) - n2;\r\n }\r\n\r\n return result / max;\r\n case 'multiply':\r\n result = (n1 * n2) / (t1 * t2);\r\n\r\n return result;\r\n case 'divide':\r\n return result = function () {\r\n var r1 = n1 / n2;\r\n var r2 = t2 / t1;\r\n return operation(r1, r2, 'multiply');\r\n }();\r\n }\r\n}\r\n/**\r\n * 做小数点的四舍五入计算\r\n * @param {*} num\r\n * @param {*} precision\r\n */\r\nfunction fixed(num, precision) {\r\n if (!precision) {\r\n precision = 2;\r\n }\r\n if (!isRealNum(num)) return num;\r\n let s = num.toFixed(precision);\r\n let index = s.indexOf('.');\r\n let prefix = s.substring(0, index);\r\n let suffix = s.substring(index + 1, s.length);\r\n if (suffix) {\r\n for (let i = suffix.length - 1; i != 0; i--) {\r\n //最末位不为0,直接break;\r\n if (suffix.charAt(i) != '0' && i == suffix.length - 1) {\r\n break;\r\n } else {\r\n suffix = suffix.substring(0, i);\r\n }\r\n }\r\n }\r\n return Number(prefix + '.' + suffix);\r\n}\r\n\r\n\r\n/**\r\n * Calculation +-/* Solve the problem of js accuracy\r\n */\r\nNumber.prototype.add = function (value) {\r\n let number = parseFloat(value);\r\n if (typeof number !== 'number' || Number.isNaN(number)) {\r\n throw new Error('请输入数字或者数字字符串~');\r\n };\r\n return operation(this, number, 'add');\r\n};\r\nNumber.prototype.subtract = function (value) {\r\n let number = parseFloat(value);\r\n if (typeof number !== 'number' || Number.isNaN(number)) {\r\n throw new Error('请输入数字或者数字字符串~');\r\n }\r\n return operation(this, number, 'subtract');\r\n};\r\nNumber.prototype.multiply = function (value) {\r\n let number = parseFloat(value);\r\n if (typeof number !== 'number' || Number.isNaN(number)) {\r\n throw new Error('请输入数字或者数字字符串~');\r\n }\r\n return operation(this, number, 'multiply');\r\n};\r\nNumber.prototype.divide = function (value) {\r\n let number = parseFloat(value);\r\n if (typeof number !== 'number' || Number.isNaN(number)) {\r\n throw new Error('请输入数字或者数字字符串~');\r\n }\r\n return operation(this, number, 'divide');\r\n};\r\nNumber.prototype.tofixed = function (value) {\r\n let precision = parseFloat(value);\r\n if (typeof precision !== 'number' || Number.isNaN(precision)) {\r\n throw new Error('请输入数字或者数字字符串~');\r\n }\r\n return fixed(this, precision);\r\n};","var global = require('../internals/global');\nvar userAgent = require('../internals/engine-user-agent');\n\nvar process = global.process;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8;\nvar match, version;\n\nif (v8) {\n match = v8.split('.');\n version = match[0] + match[1];\n} else if (userAgent) {\n match = userAgent.match(/Edge\\/(\\d+)/);\n if (!match || match[1] >= 74) {\n match = userAgent.match(/Chrome\\/(\\d+)/);\n if (match) version = match[1];\n }\n}\n\nmodule.exports = version && +version;\n","/**\r\n * The default luckysheet config object.\r\n */\r\nexport default {\r\n container: \"luckysheet\", //容器的ID\r\n column: 60, //空表格默认的列数量\r\n row: 84, //空表格默认的行数据量\r\n allowCopy: true, //是否允许拷贝\r\n showtoolbar: true, //是否第二列显示工具栏\r\n showinfobar: true, //是否显示顶部名称栏\r\n showsheetbar: true, //是否显示底部表格名称区域\r\n showstatisticBar: true, //是否显示底部计数栏\r\n pointEdit: false, //是否是编辑器插入表格模式\r\n pointEditUpdate: null, //编辑器表格更新函数\r\n pointEditZoom: 1, //编辑器表格编辑时缩放比例\r\n // menu: \"undo|redo|freezenrow|freezencolumn|download|share|chart|pivot\",\r\n data: [{ \"name\": \"Sheet1\", color: \"\", \"status\": \"1\", \"order\": \"0\", \"data\": [], \"config\": {}, \"index\":0 }, { \"name\": \"Sheet2\", color: \"\", \"status\": \"0\", \"order\": \"1\", \"data\": [], \"config\": {}, \"index\":1 }, { \"name\": \"Sheet3\", color: \"\", \"status\": \"0\", \"order\": \"2\", \"data\": [], \"config\": {}, \"index\":2 }], //客户端sheet数据[shee1, sheet2, sheet3]\r\n title: \"Luckysheet Demo\", //表格的名称\r\n userInfo:false,// 右上角的用户信息展示样式,支持 1. boolean类型:false:不展示,ture:展示默认 ' rabbit' ,2. HTML模板字符串或者普通字符串,如:' Lucky'或者'用户名', 3. 对象格式,设置 userImage:用户头像地址 和 userName:用户名 4. 不设置或者设置undefined同设置false\r\n userMenuItem: [{url:\"www.baidu.com\", \"icon\":'', \"name\":\"我的表格\"}, {url:\"www.baidu.com\", \"icon\":'', \"name\":\"退出登陆\"}], //点击右上角的用户信息弹出的菜单\r\n myFolderUrl: \"www.baidu.com\", //左上角<返回按钮的链接\r\n config: {}, //表格行高、列宽、合并单元格、公式等设置\r\n fullscreenmode: true, //是否全屏模式,非全屏模式下,标记框不会强制选中。\r\n devicePixelRatio: window.devicePixelRatio, //设备比例,比例越大表格分标率越高\r\n allowEdit: true, //是否允许前台编辑\r\n loadUrl: \"\", // 配置loadUrl的地址,luckysheet会通过ajax请求表格数据,默认载入status为1的sheet数据中的所有data,其余的sheet载入除data字段外的所有字段\r\n loadSheetUrl: \"\", //配置loadSheetUrl的地址,参数为gridKey(表格主键) 和 index(sheet主键合集,格式为[1,2,3]),返回的数据为sheet的data字段数据集合\r\n gridKey: \"\", // 表格唯一标识符\r\n updateUrl: \"\", //表格数据的更新地址\r\n updateImageUrl: \"\", //缩略图的更新地址\r\n allowUpdate: false, //是否允许编辑后的后台更新\r\n functionButton: \"\", //右上角功能按钮,例如' '\r\n showConfigWindowResize: true, //图表和数据透视表的配置会在右侧弹出,设置弹出后表格是否会自动缩进\r\n enableAddRow: true,//允许添加行\r\n enableAddBackTop: true,//允许回到顶部\r\n // enablePage: false,//允许加载下一页\r\n autoFormatw: false, //自动格式化超过4位数的数字为 亿万格式 例:true or \"true\" or \"TRUE\"\r\n accuracy: undefined, //设置传输来的数值的精确位数,小数点后n位 传参数为数字或数字字符串,例: \"0\" 或 0\r\n pageInfo:{\r\n 'queryExps':'',\r\n 'reportId':'',\r\n 'fields':'',\r\n 'mobile':'',\r\n 'frezon':'',\r\n 'currentPage':'',\r\n \"totalPage\":10,\r\n \"pageUrl\":\"\",\r\n },\r\n editMode: false, //是否为编辑模式\r\n beforeCreateDom: null,//表格创建之前的方法\r\n fireMousedown: null, //单元格数据下钻\r\n lang: 'en', //language\r\n plugins: [], //plugins, e.g. ['chart']\r\n forceCalculation:false,//强制刷新公式,公式较多会有性能问题,慎用\r\n rowHeaderWidth: 46,\r\n columnHeaderHeight: 20,\r\n defaultColWidth:73,\r\n defaultRowHeight:19,\r\n defaultFontSize:10,\r\n limitSheetNameLength:true, //是否限制工作表名的长度\r\n defaultSheetNameMaxLength:31, //默认工作表名称的最大长度\r\n sheetFormulaBar:true, //是否显示公式栏\r\n showtoolbarConfig:{}, //自定义工具栏\r\n showsheetbarConfig:{}, //自定义底部sheet页\r\n showstatisticBarConfig:{}, //自定义计数栏\r\n cellRightClickConfig:{}, //自定义单元格右键菜单\r\n sheetRightClickConfig:{}, //自定义底部sheet页右击菜单\r\n}","var classof = require('../internals/classof-raw');\n\n// `IsArray` abstract operation\n// https://tc39.github.io/ecma262/#sec-isarray\nmodule.exports = Array.isArray || function isArray(arg) {\n return classof(arg) == 'Array';\n};\n","'use strict';\nvar toPrimitive = require('../internals/to-primitive');\nvar definePropertyModule = require('../internals/object-define-property');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\nmodule.exports = function (object, key, value) {\n var propertyKey = toPrimitive(key);\n if (propertyKey in object) definePropertyModule.f(object, propertyKey, createPropertyDescriptor(0, value));\n else object[propertyKey] = value;\n};\n","var isObject = require('../internals/is-object');\nvar isArray = require('../internals/is-array');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar SPECIES = wellKnownSymbol('species');\n\n// `ArraySpeciesCreate` abstract operation\n// https://tc39.github.io/ecma262/#sec-arrayspeciescreate\nmodule.exports = function (originalArray, length) {\n var C;\n if (isArray(originalArray)) {\n C = originalArray.constructor;\n // cross-realm fallback\n if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;\n else if (isObject(C)) {\n C = C[SPECIES];\n if (C === null) C = undefined;\n }\n } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);\n};\n","var getBuiltIn = require('../internals/get-built-in');\n\nmodule.exports = getBuiltIn('navigator', 'userAgent') || '';\n","var fails = require('../internals/fails');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar V8_VERSION = require('../internals/engine-v8-version');\n\nvar SPECIES = wellKnownSymbol('species');\n\nmodule.exports = function (METHOD_NAME) {\n // We can't use this feature detection in V8 since it causes\n // deoptimization and serious performance degradation\n // https://github.com/zloirock/core-js/issues/677\n return V8_VERSION >= 51 || !fails(function () {\n var array = [];\n var constructor = array.constructor = {};\n constructor[SPECIES] = function () {\n return { foo: 1 };\n };\n return array[METHOD_NAME](Boolean).foo !== 1;\n });\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar fails = require('../internals/fails');\nvar isArray = require('../internals/is-array');\nvar isObject = require('../internals/is-object');\nvar toObject = require('../internals/to-object');\nvar toLength = require('../internals/to-length');\nvar createProperty = require('../internals/create-property');\nvar arraySpeciesCreate = require('../internals/array-species-create');\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar V8_VERSION = require('../internals/engine-v8-version');\n\nvar IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');\nvar MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;\nvar MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded';\n\n// We can't use this feature detection in V8 since it causes\n// deoptimization and serious performance degradation\n// https://github.com/zloirock/core-js/issues/679\nvar IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION >= 51 || !fails(function () {\n var array = [];\n array[IS_CONCAT_SPREADABLE] = false;\n return array.concat()[0] !== array;\n});\n\nvar SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');\n\nvar isConcatSpreadable = function (O) {\n if (!isObject(O)) return false;\n var spreadable = O[IS_CONCAT_SPREADABLE];\n return spreadable !== undefined ? !!spreadable : isArray(O);\n};\n\nvar FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT;\n\n// `Array.prototype.concat` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.concat\n// with adding support of @@isConcatSpreadable and @@species\n$({ target: 'Array', proto: true, forced: FORCED }, {\n concat: function concat(arg) { // eslint-disable-line no-unused-vars\n var O = toObject(this);\n var A = arraySpeciesCreate(O, 0);\n var n = 0;\n var i, k, length, len, E;\n for (i = -1, length = arguments.length; i < length; i++) {\n E = i === -1 ? O : arguments[i];\n if (isConcatSpreadable(E)) {\n len = toLength(E.length);\n if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);\n for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);\n } else {\n if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);\n createProperty(A, n++, E);\n }\n }\n A.length = n;\n return A;\n }\n});\n","module.exports = function (it) {\n if (typeof it != 'function') {\n throw TypeError(String(it) + ' is not a function');\n } return it;\n};\n","var aFunction = require('../internals/a-function');\n\n// optional / simple context binding\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 0: return function () {\n return fn.call(that);\n };\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n","var bind = require('../internals/function-bind-context');\nvar IndexedObject = require('../internals/indexed-object');\nvar toObject = require('../internals/to-object');\nvar toLength = require('../internals/to-length');\nvar arraySpeciesCreate = require('../internals/array-species-create');\n\nvar push = [].push;\n\n// `Array.prototype.{ forEach, map, filter, some, every, find, findIndex }` methods implementation\nvar createMethod = function (TYPE) {\n var IS_MAP = TYPE == 1;\n var IS_FILTER = TYPE == 2;\n var IS_SOME = TYPE == 3;\n var IS_EVERY = TYPE == 4;\n var IS_FIND_INDEX = TYPE == 6;\n var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;\n return function ($this, callbackfn, that, specificCreate) {\n var O = toObject($this);\n var self = IndexedObject(O);\n var boundFunction = bind(callbackfn, that, 3);\n var length = toLength(self.length);\n var index = 0;\n var create = specificCreate || arraySpeciesCreate;\n var target = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;\n var value, result;\n for (;length > index; index++) if (NO_HOLES || index in self) {\n value = self[index];\n result = boundFunction(value, index, O);\n if (TYPE) {\n if (IS_MAP) target[index] = result; // map\n else if (result) switch (TYPE) {\n case 3: return true; // some\n case 5: return value; // find\n case 6: return index; // findIndex\n case 2: push.call(target, value); // filter\n } else if (IS_EVERY) return false; // every\n }\n }\n return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.forEach` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.foreach\n forEach: createMethod(0),\n // `Array.prototype.map` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.map\n map: createMethod(1),\n // `Array.prototype.filter` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.filter\n filter: createMethod(2),\n // `Array.prototype.some` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.some\n some: createMethod(3),\n // `Array.prototype.every` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.every\n every: createMethod(4),\n // `Array.prototype.find` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.find\n find: createMethod(5),\n // `Array.prototype.findIndex` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex\n findIndex: createMethod(6)\n};\n","var wellKnownSymbol = require('../internals/well-known-symbol');\nvar create = require('../internals/object-create');\nvar definePropertyModule = require('../internals/object-define-property');\n\nvar UNSCOPABLES = wellKnownSymbol('unscopables');\nvar ArrayPrototype = Array.prototype;\n\n// Array.prototype[@@unscopables]\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\nif (ArrayPrototype[UNSCOPABLES] == undefined) {\n definePropertyModule.f(ArrayPrototype, UNSCOPABLES, {\n configurable: true,\n value: create(null)\n });\n}\n\n// add a key to Array.prototype[@@unscopables]\nmodule.exports = function (key) {\n ArrayPrototype[UNSCOPABLES][key] = true;\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar $find = require('../internals/array-iteration').find;\nvar addToUnscopables = require('../internals/add-to-unscopables');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar FIND = 'find';\nvar SKIPS_HOLES = true;\n\nvar USES_TO_LENGTH = arrayMethodUsesToLength(FIND);\n\n// Shouldn't skip holes\nif (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES = false; });\n\n// `Array.prototype.find` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.find\n$({ target: 'Array', proto: true, forced: SKIPS_HOLES || !USES_TO_LENGTH }, {\n find: function find(callbackfn /* , that = undefined */) {\n return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables(FIND);\n","'use strict';\nvar $forEach = require('../internals/array-iteration').forEach;\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar STRICT_METHOD = arrayMethodIsStrict('forEach');\nvar USES_TO_LENGTH = arrayMethodUsesToLength('forEach');\n\n// `Array.prototype.forEach` method implementation\n// https://tc39.github.io/ecma262/#sec-array.prototype.foreach\nmodule.exports = (!STRICT_METHOD || !USES_TO_LENGTH) ? function forEach(callbackfn /* , thisArg */) {\n return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n} : [].forEach;\n","'use strict';\nvar $ = require('../internals/export');\nvar forEach = require('../internals/array-for-each');\n\n// `Array.prototype.forEach` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.foreach\n$({ target: 'Array', proto: true, forced: [].forEach != forEach }, {\n forEach: forEach\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar IndexedObject = require('../internals/indexed-object');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\n\nvar nativeJoin = [].join;\n\nvar ES3_STRINGS = IndexedObject != Object;\nvar STRICT_METHOD = arrayMethodIsStrict('join', ',');\n\n// `Array.prototype.join` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.join\n$({ target: 'Array', proto: true, forced: ES3_STRINGS || !STRICT_METHOD }, {\n join: function join(separator) {\n return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar isObject = require('../internals/is-object');\nvar isArray = require('../internals/is-array');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar toLength = require('../internals/to-length');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar createProperty = require('../internals/create-property');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('slice');\nvar USES_TO_LENGTH = arrayMethodUsesToLength('slice', { ACCESSORS: true, 0: 0, 1: 2 });\n\nvar SPECIES = wellKnownSymbol('species');\nvar nativeSlice = [].slice;\nvar max = Math.max;\n\n// `Array.prototype.slice` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.slice\n// fallback for not array-like ES3 strings and DOM objects\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT || !USES_TO_LENGTH }, {\n slice: function slice(start, end) {\n var O = toIndexedObject(this);\n var length = toLength(O.length);\n var k = toAbsoluteIndex(start, length);\n var fin = toAbsoluteIndex(end === undefined ? length : end, length);\n // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible\n var Constructor, result, n;\n if (isArray(O)) {\n Constructor = O.constructor;\n // cross-realm fallback\n if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {\n Constructor = undefined;\n } else if (isObject(Constructor)) {\n Constructor = Constructor[SPECIES];\n if (Constructor === null) Constructor = undefined;\n }\n if (Constructor === Array || Constructor === undefined) {\n return nativeSlice.call(O, k, fin);\n }\n }\n result = new (Constructor === undefined ? Array : Constructor)(max(fin - k, 0));\n for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);\n result.length = n;\n return result;\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar $some = require('../internals/array-iteration').some;\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar STRICT_METHOD = arrayMethodIsStrict('some');\nvar USES_TO_LENGTH = arrayMethodUsesToLength('some');\n\n// `Array.prototype.some` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.some\n$({ target: 'Array', proto: true, forced: !STRICT_METHOD || !USES_TO_LENGTH }, {\n some: function some(callbackfn /* , thisArg */) {\n return $some(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar toInteger = require('../internals/to-integer');\nvar toLength = require('../internals/to-length');\nvar toObject = require('../internals/to-object');\nvar arraySpeciesCreate = require('../internals/array-species-create');\nvar createProperty = require('../internals/create-property');\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('splice');\nvar USES_TO_LENGTH = arrayMethodUsesToLength('splice', { ACCESSORS: true, 0: 0, 1: 2 });\n\nvar max = Math.max;\nvar min = Math.min;\nvar MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;\nvar MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded';\n\n// `Array.prototype.splice` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.splice\n// with adding support of @@species\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT || !USES_TO_LENGTH }, {\n splice: function splice(start, deleteCount /* , ...items */) {\n var O = toObject(this);\n var len = toLength(O.length);\n var actualStart = toAbsoluteIndex(start, len);\n var argumentsLength = arguments.length;\n var insertCount, actualDeleteCount, A, k, from, to;\n if (argumentsLength === 0) {\n insertCount = actualDeleteCount = 0;\n } else if (argumentsLength === 1) {\n insertCount = 0;\n actualDeleteCount = len - actualStart;\n } else {\n insertCount = argumentsLength - 2;\n actualDeleteCount = min(max(toInteger(deleteCount), 0), len - actualStart);\n }\n if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER) {\n throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);\n }\n A = arraySpeciesCreate(O, actualDeleteCount);\n for (k = 0; k < actualDeleteCount; k++) {\n from = actualStart + k;\n if (from in O) createProperty(A, k, O[from]);\n }\n A.length = actualDeleteCount;\n if (insertCount < actualDeleteCount) {\n for (k = actualStart; k < len - actualDeleteCount; k++) {\n from = k + actualDeleteCount;\n to = k + insertCount;\n if (from in O) O[to] = O[from];\n else delete O[to];\n }\n for (k = len; k > len - actualDeleteCount + insertCount; k--) delete O[k - 1];\n } else if (insertCount > actualDeleteCount) {\n for (k = len - actualDeleteCount; k > actualStart; k--) {\n from = k + actualDeleteCount - 1;\n to = k + insertCount - 1;\n if (from in O) O[to] = O[from];\n else delete O[to];\n }\n }\n for (k = 0; k < insertCount; k++) {\n O[k + actualStart] = arguments[k + 2];\n }\n O.length = len - actualDeleteCount + insertCount;\n return A;\n }\n});\n","var fails = require('../internals/fails');\n\nmodule.exports = !fails(function () {\n function F() { /* empty */ }\n F.prototype.constructor = null;\n return Object.getPrototypeOf(new F()) !== F.prototype;\n});\n","var has = require('../internals/has');\nvar toObject = require('../internals/to-object');\nvar sharedKey = require('../internals/shared-key');\nvar CORRECT_PROTOTYPE_GETTER = require('../internals/correct-prototype-getter');\n\nvar IE_PROTO = sharedKey('IE_PROTO');\nvar ObjectPrototype = Object.prototype;\n\n// `Object.getPrototypeOf` method\n// https://tc39.github.io/ecma262/#sec-object.getprototypeof\nmodule.exports = CORRECT_PROTOTYPE_GETTER ? Object.getPrototypeOf : function (O) {\n O = toObject(O);\n if (has(O, IE_PROTO)) return O[IE_PROTO];\n if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectPrototype : null;\n};\n","var $ = require('../internals/export');\nvar anObject = require('../internals/an-object');\nvar isObject = require('../internals/is-object');\nvar has = require('../internals/has');\nvar fails = require('../internals/fails');\nvar definePropertyModule = require('../internals/object-define-property');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\n\n// `Reflect.set` method\n// https://tc39.github.io/ecma262/#sec-reflect.set\nfunction set(target, propertyKey, V /* , receiver */) {\n var receiver = arguments.length < 4 ? target : arguments[3];\n var ownDescriptor = getOwnPropertyDescriptorModule.f(anObject(target), propertyKey);\n var existingDescriptor, prototype;\n if (!ownDescriptor) {\n if (isObject(prototype = getPrototypeOf(target))) {\n return set(prototype, propertyKey, V, receiver);\n }\n ownDescriptor = createPropertyDescriptor(0);\n }\n if (has(ownDescriptor, 'value')) {\n if (ownDescriptor.writable === false || !isObject(receiver)) return false;\n if (existingDescriptor = getOwnPropertyDescriptorModule.f(receiver, propertyKey)) {\n if (existingDescriptor.get || existingDescriptor.set || existingDescriptor.writable === false) return false;\n existingDescriptor.value = V;\n definePropertyModule.f(receiver, propertyKey, existingDescriptor);\n } else definePropertyModule.f(receiver, propertyKey, createPropertyDescriptor(0, V));\n return true;\n }\n return ownDescriptor.set === undefined ? false : (ownDescriptor.set.call(receiver, V), true);\n}\n\n// MS Edge 17-18 Reflect.set allows setting the property to object\n// with non-writable property on the prototype\nvar MS_EDGE_BUG = fails(function () {\n var object = definePropertyModule.f({}, 'a', { configurable: true });\n // eslint-disable-next-line no-undef\n return Reflect.set(getPrototypeOf(object), 'a', 1, object) !== false;\n});\n\n$({ target: 'Reflect', stat: true, forced: MS_EDGE_BUG }, {\n set: set\n});\n","'use strict';\nvar fixRegExpWellKnownSymbolLogic = require('../internals/fix-regexp-well-known-symbol-logic');\nvar anObject = require('../internals/an-object');\nvar toLength = require('../internals/to-length');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\nvar advanceStringIndex = require('../internals/advance-string-index');\nvar regExpExec = require('../internals/regexp-exec-abstract');\n\n// @@match logic\nfixRegExpWellKnownSymbolLogic('match', 1, function (MATCH, nativeMatch, maybeCallNative) {\n return [\n // `String.prototype.match` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.match\n function match(regexp) {\n var O = requireObjectCoercible(this);\n var matcher = regexp == undefined ? undefined : regexp[MATCH];\n return matcher !== undefined ? matcher.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));\n },\n // `RegExp.prototype[@@match]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match\n function (regexp) {\n var res = maybeCallNative(nativeMatch, regexp, this);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n\n if (!rx.global) return regExpExec(rx, S);\n\n var fullUnicode = rx.unicode;\n rx.lastIndex = 0;\n var A = [];\n var n = 0;\n var result;\n while ((result = regExpExec(rx, S)) !== null) {\n var matchStr = String(result[0]);\n A[n] = matchStr;\n if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n n++;\n }\n return n === 0 ? null : A;\n }\n ];\n});\n","var isObject = require('../internals/is-object');\nvar classof = require('../internals/classof-raw');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar MATCH = wellKnownSymbol('match');\n\n// `IsRegExp` abstract operation\n// https://tc39.github.io/ecma262/#sec-isregexp\nmodule.exports = function (it) {\n var isRegExp;\n return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classof(it) == 'RegExp');\n};\n","var anObject = require('../internals/an-object');\nvar aFunction = require('../internals/a-function');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar SPECIES = wellKnownSymbol('species');\n\n// `SpeciesConstructor` abstract operation\n// https://tc39.github.io/ecma262/#sec-speciesconstructor\nmodule.exports = function (O, defaultConstructor) {\n var C = anObject(O).constructor;\n var S;\n return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? defaultConstructor : aFunction(S);\n};\n","'use strict';\nvar fixRegExpWellKnownSymbolLogic = require('../internals/fix-regexp-well-known-symbol-logic');\nvar isRegExp = require('../internals/is-regexp');\nvar anObject = require('../internals/an-object');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\nvar speciesConstructor = require('../internals/species-constructor');\nvar advanceStringIndex = require('../internals/advance-string-index');\nvar toLength = require('../internals/to-length');\nvar callRegExpExec = require('../internals/regexp-exec-abstract');\nvar regexpExec = require('../internals/regexp-exec');\nvar fails = require('../internals/fails');\n\nvar arrayPush = [].push;\nvar min = Math.min;\nvar MAX_UINT32 = 0xFFFFFFFF;\n\n// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError\nvar SUPPORTS_Y = !fails(function () { return !RegExp(MAX_UINT32, 'y'); });\n\n// @@split logic\nfixRegExpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {\n var internalSplit;\n if (\n 'abbc'.split(/(b)*/)[1] == 'c' ||\n 'test'.split(/(?:)/, -1).length != 4 ||\n 'ab'.split(/(?:ab)*/).length != 2 ||\n '.'.split(/(.?)(.?)/).length != 4 ||\n '.'.split(/()()/).length > 1 ||\n ''.split(/.?/).length\n ) {\n // based on es5-shim implementation, need to rework it\n internalSplit = function (separator, limit) {\n var string = String(requireObjectCoercible(this));\n var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n if (lim === 0) return [];\n if (separator === undefined) return [string];\n // If `separator` is not a regex, use native split\n if (!isRegExp(separator)) {\n return nativeSplit.call(string, separator, lim);\n }\n var output = [];\n var flags = (separator.ignoreCase ? 'i' : '') +\n (separator.multiline ? 'm' : '') +\n (separator.unicode ? 'u' : '') +\n (separator.sticky ? 'y' : '');\n var lastLastIndex = 0;\n // Make `global` and avoid `lastIndex` issues by working with a copy\n var separatorCopy = new RegExp(separator.source, flags + 'g');\n var match, lastIndex, lastLength;\n while (match = regexpExec.call(separatorCopy, string)) {\n lastIndex = separatorCopy.lastIndex;\n if (lastIndex > lastLastIndex) {\n output.push(string.slice(lastLastIndex, match.index));\n if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));\n lastLength = match[0].length;\n lastLastIndex = lastIndex;\n if (output.length >= lim) break;\n }\n if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop\n }\n if (lastLastIndex === string.length) {\n if (lastLength || !separatorCopy.test('')) output.push('');\n } else output.push(string.slice(lastLastIndex));\n return output.length > lim ? output.slice(0, lim) : output;\n };\n // Chakra, V8\n } else if ('0'.split(undefined, 0).length) {\n internalSplit = function (separator, limit) {\n return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);\n };\n } else internalSplit = nativeSplit;\n\n return [\n // `String.prototype.split` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.split\n function split(separator, limit) {\n var O = requireObjectCoercible(this);\n var splitter = separator == undefined ? undefined : separator[SPLIT];\n return splitter !== undefined\n ? splitter.call(separator, O, limit)\n : internalSplit.call(String(O), separator, limit);\n },\n // `RegExp.prototype[@@split]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split\n //\n // NOTE: This cannot be properly polyfilled in engines that don't support\n // the 'y' flag.\n function (regexp, limit) {\n var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n var C = speciesConstructor(rx, RegExp);\n\n var unicodeMatching = rx.unicode;\n var flags = (rx.ignoreCase ? 'i' : '') +\n (rx.multiline ? 'm' : '') +\n (rx.unicode ? 'u' : '') +\n (SUPPORTS_Y ? 'y' : 'g');\n\n // ^(? + rx + ) is needed, in combination with some S slicing, to\n // simulate the 'y' flag.\n var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);\n var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n if (lim === 0) return [];\n if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];\n var p = 0;\n var q = 0;\n var A = [];\n while (q < S.length) {\n splitter.lastIndex = SUPPORTS_Y ? q : 0;\n var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));\n var e;\n if (\n z === null ||\n (e = min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p\n ) {\n q = advanceStringIndex(S, q, unicodeMatching);\n } else {\n A.push(S.slice(p, q));\n if (A.length === lim) return A;\n for (var i = 1; i <= z.length - 1; i++) {\n A.push(z[i]);\n if (A.length === lim) return A;\n }\n q = p = e;\n }\n }\n A.push(S.slice(p));\n return A;\n }\n ];\n}, !SUPPORTS_Y);\n","// iterable DOM collections\n// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods\nmodule.exports = {\n CSSRuleList: 0,\n CSSStyleDeclaration: 0,\n CSSValueList: 0,\n ClientRectList: 0,\n DOMRectList: 0,\n DOMStringList: 0,\n DOMTokenList: 1,\n DataTransferItemList: 0,\n FileList: 0,\n HTMLAllCollection: 0,\n HTMLCollection: 0,\n HTMLFormElement: 0,\n HTMLSelectElement: 0,\n MediaList: 0,\n MimeTypeArray: 0,\n NamedNodeMap: 0,\n NodeList: 1,\n PaintRequestList: 0,\n Plugin: 0,\n PluginArray: 0,\n SVGLengthList: 0,\n SVGNumberList: 0,\n SVGPathSegList: 0,\n SVGPointList: 0,\n SVGStringList: 0,\n SVGTransformList: 0,\n SourceBufferList: 0,\n StyleSheetList: 0,\n TextTrackCueList: 0,\n TextTrackList: 0,\n TouchList: 0\n};\n","var global = require('../internals/global');\nvar DOMIterables = require('../internals/dom-iterables');\nvar forEach = require('../internals/array-for-each');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\n\nfor (var COLLECTION_NAME in DOMIterables) {\n var Collection = global[COLLECTION_NAME];\n var CollectionPrototype = Collection && Collection.prototype;\n // some Chrome versions have non-configurable methods on DOMTokenList\n if (CollectionPrototype && CollectionPrototype.forEach !== forEach) try {\n createNonEnumerableProperty(CollectionPrototype, 'forEach', forEach);\n } catch (error) {\n CollectionPrototype.forEach = forEach;\n }\n}\n","'use strict';\nvar $ = require('../internals/export');\nvar $every = require('../internals/array-iteration').every;\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar STRICT_METHOD = arrayMethodIsStrict('every');\nvar USES_TO_LENGTH = arrayMethodUsesToLength('every');\n\n// `Array.prototype.every` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.every\n$({ target: 'Array', proto: true, forced: !STRICT_METHOD || !USES_TO_LENGTH }, {\n every: function every(callbackfn /* , thisArg */) {\n return $every(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar $filter = require('../internals/array-iteration').filter;\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter');\n// Edge 14- issue\nvar USES_TO_LENGTH = arrayMethodUsesToLength('filter');\n\n// `Array.prototype.filter` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.filter\n// with adding support of @@species\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT || !USES_TO_LENGTH }, {\n filter: function filter(callbackfn /* , thisArg */) {\n return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar aFunction = require('../internals/a-function');\nvar toObject = require('../internals/to-object');\nvar fails = require('../internals/fails');\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\n\nvar test = [];\nvar nativeSort = test.sort;\n\n// IE8-\nvar FAILS_ON_UNDEFINED = fails(function () {\n test.sort(undefined);\n});\n// V8 bug\nvar FAILS_ON_NULL = fails(function () {\n test.sort(null);\n});\n// Old WebKit\nvar STRICT_METHOD = arrayMethodIsStrict('sort');\n\nvar FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD;\n\n// `Array.prototype.sort` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.sort\n$({ target: 'Array', proto: true, forced: FORCED }, {\n sort: function sort(comparefn) {\n return comparefn === undefined\n ? nativeSort.call(toObject(this))\n : nativeSort.call(toObject(this), aFunction(comparefn));\n }\n});\n","'use strict';\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fails = require('../internals/fails');\nvar objectKeys = require('../internals/object-keys');\nvar getOwnPropertySymbolsModule = require('../internals/object-get-own-property-symbols');\nvar propertyIsEnumerableModule = require('../internals/object-property-is-enumerable');\nvar toObject = require('../internals/to-object');\nvar IndexedObject = require('../internals/indexed-object');\n\nvar nativeAssign = Object.assign;\nvar defineProperty = Object.defineProperty;\n\n// `Object.assign` method\n// https://tc39.github.io/ecma262/#sec-object.assign\nmodule.exports = !nativeAssign || fails(function () {\n // should have correct order of operations (Edge bug)\n if (DESCRIPTORS && nativeAssign({ b: 1 }, nativeAssign(defineProperty({}, 'a', {\n enumerable: true,\n get: function () {\n defineProperty(this, 'b', {\n value: 3,\n enumerable: false\n });\n }\n }), { b: 2 })).b !== 1) return true;\n // should work with symbols and should have deterministic property order (V8 bug)\n var A = {};\n var B = {};\n // eslint-disable-next-line no-undef\n var symbol = Symbol();\n var alphabet = 'abcdefghijklmnopqrst';\n A[symbol] = 7;\n alphabet.split('').forEach(function (chr) { B[chr] = chr; });\n return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;\n}) ? function assign(target, source) { // eslint-disable-line no-unused-vars\n var T = toObject(target);\n var argumentsLength = arguments.length;\n var index = 1;\n var getOwnPropertySymbols = getOwnPropertySymbolsModule.f;\n var propertyIsEnumerable = propertyIsEnumerableModule.f;\n while (argumentsLength > index) {\n var S = IndexedObject(arguments[index++]);\n var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);\n var length = keys.length;\n var j = 0;\n var key;\n while (length > j) {\n key = keys[j++];\n if (!DESCRIPTORS || propertyIsEnumerable.call(S, key)) T[key] = S[key];\n }\n } return T;\n} : nativeAssign;\n","var $ = require('../internals/export');\nvar assign = require('../internals/object-assign');\n\n// `Object.assign` method\n// https://tc39.github.io/ecma262/#sec-object.assign\n$({ target: 'Object', stat: true, forced: Object.assign !== assign }, {\n assign: assign\n});\n","var DESCRIPTORS = require('../internals/descriptors');\nvar objectKeys = require('../internals/object-keys');\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar propertyIsEnumerable = require('../internals/object-property-is-enumerable').f;\n\n// `Object.{ entries, values }` methods implementation\nvar createMethod = function (TO_ENTRIES) {\n return function (it) {\n var O = toIndexedObject(it);\n var keys = objectKeys(O);\n var length = keys.length;\n var i = 0;\n var result = [];\n var key;\n while (length > i) {\n key = keys[i++];\n if (!DESCRIPTORS || propertyIsEnumerable.call(O, key)) {\n result.push(TO_ENTRIES ? [key, O[key]] : O[key]);\n }\n }\n return result;\n };\n};\n\nmodule.exports = {\n // `Object.entries` method\n // https://tc39.github.io/ecma262/#sec-object.entries\n entries: createMethod(true),\n // `Object.values` method\n // https://tc39.github.io/ecma262/#sec-object.values\n values: createMethod(false)\n};\n","var $ = require('../internals/export');\nvar $values = require('../internals/object-to-array').values;\n\n// `Object.values` method\n// https://tc39.github.io/ecma262/#sec-object.values\n$({ target: 'Object', stat: true }, {\n values: function values(O) {\n return $values(O);\n }\n});\n","var requireObjectCoercible = require('../internals/require-object-coercible');\n\nvar quot = /\"/g;\n\n// B.2.3.2.1 CreateHTML(string, tag, attribute, value)\n// https://tc39.github.io/ecma262/#sec-createhtml\nmodule.exports = function (string, tag, attribute, value) {\n var S = String(requireObjectCoercible(string));\n var p1 = '<' + tag;\n if (attribute !== '') p1 += ' ' + attribute + '=\"' + String(value).replace(quot, '"') + '\"';\n return p1 + '>' + S + '';\n};\n","var fails = require('../internals/fails');\n\n// check the existence of a method, lowercase\n// of a tag and escaping quotes in arguments\nmodule.exports = function (METHOD_NAME) {\n return fails(function () {\n var test = ''[METHOD_NAME]('\"');\n return test !== test.toLowerCase() || test.split('\"').length > 3;\n });\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar createHTML = require('../internals/create-html');\nvar forcedStringHTMLMethod = require('../internals/string-html-forced');\n\n// `String.prototype.bold` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.bold\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('bold') }, {\n bold: function bold() {\n return createHTML(this, 'b', '', '');\n }\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar createHTML = require('../internals/create-html');\nvar forcedStringHTMLMethod = require('../internals/string-html-forced');\n\n// `String.prototype.link` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.link\n$({ target: 'String', proto: true, forced: forcedStringHTMLMethod('link') }, {\n link: function link(url) {\n return createHTML(this, 'a', 'href', url);\n }\n});\n","import en from './en'\r\nimport zh from './zh'\r\nimport es from './es'\r\nimport zh_tw from './zh_tw'\r\nimport Store from '../store';\r\n\r\nconst localeObj = {en,zh,es,zh_tw}\r\n\r\nfunction locale(){\r\n return localeObj[Store.lang];\r\n}\r\n\r\nexport default locale;","export default {\r\n functionlist:[{\r\n \"n\": \"SUMIF\",\r\n \"t\": 0,\r\n \"d\": \"Returns a conditional sum across a range.\",\r\n \"a\": \"A conditional sum across a range.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range which is tested against `criterion`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion\",\r\n \"detail\": \"The pattern or test to apply to `range`.\",\r\n \"example\": \"\\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"sum_range\",\r\n \"detail\": \"The range to be summed, if different from `range`.\",\r\n \"example\": \"B1:B10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"TAN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the tangent of an angle provided in radians.\",\r\n \"a\": \"Tangent of an angle provided in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to find the tangent of, in radians.\",\r\n \"example\": \"45*PI()/180\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TANH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the hyperbolic tangent of any real number.\",\r\n \"a\": \"Hyperbolic tangent of any real number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Any real value to calculate the hyperbolic tangent of.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CEILING\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number up to the nearest integer multiple of specified significance `factor`.\",\r\n \"a\": \"Rounds number up to nearest multiple of a factor.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round up to the nearest integer multiple of `factor`.\",\r\n \"example\": \"23.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The number to whose multiples `value` will be rounded.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ATAN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse tangent of a value, in radians.\",\r\n \"a\": \"Inverse tangent of a value, in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse tangent.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ASINH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse hyperbolic sine of a number.\",\r\n \"a\": \"Inverse hyperbolic sine of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse hyperbolic sine.\",\r\n \"example\": \"0.9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ABS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the absolute value of a number.\",\r\n \"a\": \"Absolute value of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number of which to return the absolute value.\",\r\n \"example\": \"-2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ACOS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse cosine of a value, in radians.\",\r\n \"a\": \"Inverse cosine of a value, in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse cosine. Must be between `-1` and `1`, inclusive.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ACOSH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse hyperbolic cosine of a number.\",\r\n \"a\": \"Inverse hyperbolic cosine of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse hyperbolic cosine. Must be greater than or equal to `1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MULTINOMIAL\",\r\n \"t\": 0,\r\n \"d\": \"Returns the factorial of the sum of values divided by the product of the values' factorials.\",\r\n \"a\": \"Multinomial distribution function.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ATANH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse hyperbolic tangent of a number.\",\r\n \"a\": \"Inverse hyperbolic tangent of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse hyperbolic tangent. Must be between -1 and 1, exclusive.\",\r\n \"example\": \"0.9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ATAN2\",\r\n \"t\": 0,\r\n \"d\": \"Returns the angle between the x-axis and a line segment from the origin (0,0) to specified coordinate pair (`x`,`y`), in radians.\",\r\n \"a\": \"Arctangent of a value.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The x coordinate of the endpoint of the line segment for which to calculate the angle from the x-axis.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"y\",\r\n \"detail\": \"The y coordinate of the endpoint of the line segment for which to calculate the angle from the x-axis.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTBLANK\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of empty values in a list of values and ranges.\",\r\n \"a\": \"Number of empty values.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range in which to count the number of blanks.\",\r\n \"example\": \"A2:C100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"COSH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the hyperbolic cosine of any real number.\",\r\n \"a\": \"Hyperbolic cosine of any real number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Any real value to calculate the hyperbolic cosine of.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"INT\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number down to the nearest integer that is less than or equal to it.\",\r\n \"a\": \"Rounds number down to nearest integer.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round down to the nearest integer.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISEVEN\",\r\n \"t\": 0,\r\n \"d\": \"Checks whether the provided value is even.\",\r\n \"a\": \"Whether the provided value is even.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as even.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISODD\",\r\n \"t\": 0,\r\n \"d\": \"Checks whether the provided value is odd.\",\r\n \"a\": \"Whether the provided value is odd.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as odd.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LCM\",\r\n \"t\": 0,\r\n \"d\": \"Returns the least common multiple of one or more integers.\",\r\n \"a\": \"Least common multiple of one or more integers.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range whose factors to consider in a calculation to find the least common multiple.\",\r\n \"example\": \"A2:A5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges whose factors to consider to find the least common multiple.\",\r\n \"example\": \"3\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the logarithm of a number, base e (Euler's number).\",\r\n \"a\": \"The logarithm of a number, base e (euler's number).\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the logarithm, base e.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOG\",\r\n \"t\": 0,\r\n \"d\": \"Returns the logarithm of a number with respect to a base.\",\r\n \"a\": \"The logarithm of a number with respect to a base.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the logarithm.\",\r\n \"example\": \"128\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"base\",\r\n \"detail\": \"The base to use for calculation of the logarithm.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOG10\",\r\n \"t\": 0,\r\n \"d\": \"Returns the logarithm of a number, base 10.\",\r\n \"a\": \"The logarithm of a number, base 10.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the logarithm, base 10.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MOD\",\r\n \"t\": 0,\r\n \"d\": \"Returns the result of the modulo operator, the remainder after a division operation.\",\r\n \"a\": \"Modulo (remainder) operator.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The number to be divided to find the remainder.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The number to divide by.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MROUND\",\r\n \"t\": 0,\r\n \"d\": \"Rounds one number to the nearest integer multiple of another.\",\r\n \"a\": \"Rounds a number to the nearest integer multiple.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number to round to the nearest integer multiple of another.\",\r\n \"example\": \"21\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The number to whose multiples `value` will be rounded.\",\r\n \"example\": \"14\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ODD\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number up to the nearest odd integer.\",\r\n \"a\": \"Rounds a number up to the nearest odd integer.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to the next greatest odd number.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMSQ\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sum of the squares of a series of numbers and/or cells.\",\r\n \"a\": \"Sum of squares.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first number or range whose squares to add together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional numbers or ranges whose squares to add to the square(s) of `value1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COMBIN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the number of ways to choose some number of objects from a pool of a given size of objects.\",\r\n \"a\": \"Number of combinations from a set of objects.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"n\",\r\n \"detail\": \"The size of the pool of objects to choose from.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"k\",\r\n \"detail\": \"The number of objects to choose.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUM\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sum of a series of numbers and/or cells.\",\r\n \"a\": \"Sum of a series of numbers and/or cells.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first number or range to add together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional numbers or ranges to add to `value1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SUBTOTAL\",\r\n \"t\": 0,\r\n \"d\": \"Returns a subtotal for a vertical range of cells using a specified aggregation function.\",\r\n \"a\": \"Subtotal for a range using a specific function.\",\r\n \"m\": [2, 256],\r\n \"p\": [{\r\n \"name\": \"function_code\",\r\n \"detail\": \"The function to use in subtotal aggregation.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"range1\",\r\n \"detail\": \"The first range over which to calculate a subtotal.\",\r\n \"example\": \"A2:A5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"range2\",\r\n \"detail\": \"Additional ranges over which to calculate subtotals.\",\r\n \"example\": \"B2:B8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"ASIN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse sine of a value, in radians.\",\r\n \"a\": \"Inverse sine of a value, in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse sine. Must be between `-1` and `1`, inclusive.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTIF\",\r\n \"t\": 1,\r\n \"d\": \"Returns a conditional count across a range.\",\r\n \"a\": \"A conditional count across a range.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range that is tested against `criterion`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion\",\r\n \"detail\": \"The pattern or test to apply to `range`.\",\r\n \"example\": \"\\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RADIANS\",\r\n \"t\": 0,\r\n \"d\": \"Converts an angle value in degrees to radians.\",\r\n \"a\": \"Converts an angle value in degrees to radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to convert from degrees to radians.\",\r\n \"example\": \"180\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RAND\",\r\n \"t\": 0,\r\n \"d\": \"Returns a random number between 0 inclusive and 1 exclusive.\",\r\n \"a\": \"A random number between 0 inclusive and 1 exclusive.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"COUNTUNIQUE\",\r\n \"t\": 0,\r\n \"d\": \"Counts the number of unique values in a list of specified values and ranges.\",\r\n \"a\": \"Counts number of unique values in a range.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider for uniqueness.\",\r\n \"example\": \"A1:C100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider for uniqueness.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DEGREES\",\r\n \"t\": 0,\r\n \"d\": \"Converts an angle value in radians to degrees.\",\r\n \"a\": \"Converts an angle value in radians to degrees.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to convert from radians to degrees.\",\r\n \"example\": \"PI()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ERFC\",\r\n \"t\": 9,\r\n \"d\": \"Returns the complementary Gauss error function of a value.\",\r\n \"a\": \"Complementary gauss error function of a value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"z\",\r\n \"detail\": \"The number for which to calculate the complementary Gauss error function.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EVEN\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number up to the nearest even integer.\",\r\n \"a\": \"Rounds a number up to the nearest even integer.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to the next greatest even number.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EXP\",\r\n \"t\": 0,\r\n \"d\": \"Returns Euler's number, e (~2.718) raised to a power.\",\r\n \"a\": \"Euler's number, e (~2.718) raised to a power.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"exponent\",\r\n \"detail\": \"The exponent to raise e to.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FACT\",\r\n \"t\": 0,\r\n \"d\": \"Returns the factorial of a number.\",\r\n \"a\": \"Factorial of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number or reference to a number whose factorial will be calculated and returned.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FACTDOUBLE\",\r\n \"t\": 0,\r\n \"d\": \"Returns the \\\"double factorial\\\" of a number.\",\r\n \"a\": \"\\\"double factorial\\\" of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number or reference to a number whose double factorial will be calculated and returned.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PI\",\r\n \"t\": 0,\r\n \"d\": \"Returns the value of Pi to 14 decimal places.\",\r\n \"a\": \"The number pi.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"FLOOR\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number down to the nearest integer multiple of specified significance `factor`.\",\r\n \"a\": \"Rounds number down to nearest multiple of a factor.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round down to the nearest integer multiple of `factor`.\",\r\n \"example\": \"23.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The number to whose multiples `value` will be rounded.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GCD\",\r\n \"t\": 0,\r\n \"d\": \"Returns the greatest common divisor of one or more integers.\",\r\n \"a\": \"Greatest common divisor of one or more integers.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range whose factors to consider in a calculation to find the greatest common divisor.\",\r\n \"example\": \"A2:A5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges whose factors to consider to find the greatest common divisor.\",\r\n \"example\": \"96\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANDBETWEEN\",\r\n \"t\": 0,\r\n \"d\": \"Returns a uniformly random integer between two values, inclusive.\",\r\n \"a\": \"Random integer between two values, inclusive.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"low\",\r\n \"detail\": \"The low end of the random range.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"high\",\r\n \"detail\": \"The high end of the random range.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ROUND\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number to a certain number of decimal places according to standard rules.\",\r\n \"a\": \"Rounds a number according to standard rules.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to `places` number of places.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of decimal places to which to round.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ROUNDDOWN\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number to a certain number of decimal places, always rounding down to the next valid increment.\",\r\n \"a\": \"Rounds down a number.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to `places` number of places, always rounding down.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of decimal places to which to round.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ROUNDUP\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number to a certain number of decimal places, always rounding up to the next valid increment.\",\r\n \"a\": \"Rounds up a number.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to `places` number of places, always rounding up.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of decimal places to which to round.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SERIESSUM\",\r\n \"t\": 0,\r\n \"d\": \"Given parameters `x`, `n`, `m`, and `a`, returns the power series sum a\",\r\n \"a\": \"Sum of a power series.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the power series. Varies depending on the type of approximation, may be angle, exponent, or some other value.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"n\",\r\n \"detail\": \"The initial power to which to raise `x` in the power series.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"m\",\r\n \"detail\": \"The additive increment by which to increase `x`.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"a\",\r\n \"detail\": \"The array or range containing the coefficients of the power series.\",\r\n \"example\": \"{FACT(0)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SIGN\",\r\n \"t\": 0,\r\n \"d\": \"Given an input number, returns `-1` if it is negative, `1` if positive, and `0` if it is zero.\",\r\n \"a\": \"Sign of a provided number (+/-/0).\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose sign will be evaluated.\",\r\n \"example\": \"-42\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SIN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sine of an angle provided in radians.\",\r\n \"a\": \"Sine of an angle provided in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to find the sine of, in radians.\",\r\n \"example\": \"PI()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SINH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the hyperbolic sine of any real number.\",\r\n \"a\": \"Hyperbolic sine of any real number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Any real value to calculate the hyperbolic sine of.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SQRT\",\r\n \"t\": 0,\r\n \"d\": \"Returns the positive square root of a positive number.\",\r\n \"a\": \"Positive square root of a positive number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number for which to calculate the positive square root.\",\r\n \"example\": \"9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SQRTPI\",\r\n \"t\": 0,\r\n \"d\": \"Returns the positive square root of the product of Pi and the given positive number.\",\r\n \"a\": \"Square root of the product of pi and number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number which will be multiplied by Pi and have the product's square root returned\",\r\n \"example\": \"9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GAMMALN\",\r\n \"t\": 1,\r\n \"d\": \"Returns the logarithm of a specified Gamma function, base e (Euler's number).\",\r\n \"a\": \"Logarithm of gamma function.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The input to the Gamma function. The natural logarithm of Gamma(`value`) will be returned.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the cosine of an angle provided in radians.\",\r\n \"a\": \"Cosine of an angle provided in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to find the cosine of, in radians.\",\r\n \"example\": \"PI()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TRUNC\",\r\n \"t\": 0,\r\n \"d\": \"Truncates a number to a certain number of significant digits by omitting less significant digits.\",\r\n \"a\": \"Truncates a number.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be truncated.\",\r\n \"example\": \"3.141592654\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of significant digits to the right of the decimal point to retain.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"QUOTIENT\",\r\n \"t\": 0,\r\n \"d\": \"Returns one number divided by another.\",\r\n \"a\": \"One number divided by another.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The number to be divided.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The number to divide by.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"POWER\",\r\n \"t\": 0,\r\n \"d\": \"Returns a number raised to a power.\",\r\n \"a\": \"A number raised to a power.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"base\",\r\n \"detail\": \"The number to raise to the `exponent` power.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"exponent\",\r\n \"detail\": \"The exponent to raise `base` to.\",\r\n \"example\": \"0.5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMIFS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sum of a range depending on multiple criteria.\",\r\n \"a\": \"Sums a range depending on multiple criteria.\",\r\n \"m\": [3, 257],\r\n \"p\": [{\r\n \"name\": \"sum_range\",\r\n \"detail\": \"The range to sum.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criteria_range1\",\r\n \"detail\": \"The range to check against criterion1.\",\r\n \"example\": \" B1:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion1\",\r\n \"detail\": \"The pattern or test to apply to criteria_range1.\",\r\n \"example\": \" \\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range2\",\r\n \"detail\": \"Additional ranges to check.\",\r\n \"example\": \" C1:C10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTIFS\",\r\n \"t\": 1,\r\n \"d\": \"Returns the count of a range depending on multiple criteria.\",\r\n \"a\": \"Count values depending on multiple criteria.\",\r\n \"m\": [2, 256],\r\n \"p\": [{\r\n \"name\": \"criteria_range1\",\r\n \"detail\": \"The range to check against `criterion1`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion1\",\r\n \"detail\": \"The pattern or test to apply to `criteria_range1`.\",\r\n \"example\": \" \\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range2\",\r\n \"detail\": \"Additional ranges to check.\",\r\n \"example\": \" B1:B10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PRODUCT\",\r\n \"t\": 0,\r\n \"d\": \"Returns the result of multiplying a series of numbers together.\",\r\n \"a\": \"Result of multiplying a series of numbers together.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"factor1\",\r\n \"detail\": \"The first number or range to calculate for the product.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor2\",\r\n \"detail\": \"More numbers or ranges to calculate for the product.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HARMEAN\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the harmonic mean of a dataset.\",\r\n \"a\": \"The harmonic mean of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HYPGEOMDIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability of drawing a certain number of successes in a certain number of tries given a population of a certain size containing a certain number of successes, without replacement of draws.\",\r\n \"a\": \"Hypergeometric distribution probability.\",\r\n \"m\": [5, 5],\r\n \"p\": [{\r\n \"name\": \"num_successes\",\r\n \"detail\": \"The desired number of successes.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"num_draws\",\r\n \"detail\": \"The number of permitted draws.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"successes_in_pop\",\r\n \"detail\": \"The total number of successes in the population.\",\r\n \"example\": \"20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"pop_size\",\r\n \"detail\": \"The total size of the population\",\r\n \"example\": \"40\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf cumulative is TRUE(), HYPGEOM.DIST returns the cumulative distribution function;\\n\\nif FALSE(), it returns the probability density function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"INTERCEPT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the y-value at which the line resulting from linear regression of a dataset will intersect the y-axis (x=0).\",\r\n \"a\": \"Y-intercept of line derived via linear regression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"KURT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the kurtosis of a dataset, which describes the shape, and in particular the \\\"peakedness\\\" of that dataset.\",\r\n \"a\": \"Kurtosis of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the dataset.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the dataset.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LARGE\",\r\n \"t\": 1,\r\n \"d\": \"Returns the nth largest element from a data set, where n is user-defined.\",\r\n \"a\": \"Nth largest element from a data set.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"Array or range containing the dataset to consider.\",\r\n \"example\": \"A2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"n\",\r\n \"detail\": \"The rank from largest to smallest of the element to return.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STDEVA\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the standard deviation based on a sample, setting text to the value `0`.\",\r\n \"a\": \"Standard deviation of sample (text as 0).\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STDEVP\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the standard deviation based on an entire population.\",\r\n \"a\": \"Standard deviation of an entire population.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GEOMEAN\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the geometric mean of a dataset.\",\r\n \"a\": \"The geometric mean of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANK_EQ\",\r\n \"t\": 1,\r\n \"d\": \"Returns the rank of a specified value in a dataset. If there is more than one entry of the same value in the dataset, the top rank of the entries will be returned.\",\r\n \"a\": \"Top rank of a specified value in a dataset.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose rank will be determined.\",\r\n \"example\": \"A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"is_ascending\",\r\n \"detail\": \"Whether to consider the values in `data` in descending or ascending order. If omitted, the default is descending (FALSE).\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANK_AVG\",\r\n \"t\": 1,\r\n \"d\": \"Returns the rank of a specified value in a dataset. If there is more than one entry of the same value in the dataset, the average rank of the entries will be returned.\",\r\n \"a\": \"Average rank of a specified value in a dataset.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose rank will be determined.\",\r\n \"example\": \"A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"is_ascending\",\r\n \"detail\": \"Whether to consider the values in `data` in descending or ascending order. If omitted, the default is descending (FALSE).\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTRANK_EXC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the percentage rank (percentile) from 0 to 1 exclusive of a specified value in a dataset.\",\r\n \"a\": \"Percentage rank (percentile) from 0 to 1 exclusive.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose percentage rank will be determined.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant figures to use in the calculation. Default is 3.\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTRANK_INC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the percentage rank (percentile) from 0 to 1 inclusive of a specified value in a dataset.\",\r\n \"a\": \"Percentage rank (percentile) from 0 to 1 inclusive.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose percentage rank will be determined.\",\r\n \"example\": \" A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant figures to use in the calculation. Default is 3.\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FORECAST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the expected y-value for a specified x based on a linear regression of a dataset.\",\r\n \"a\": \"Expected y-value based of linear regression.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The value on the x-axis to forecast.\",\r\n \"example\": \"A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FISHERINV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the inverse Fisher transformation of a specified value.\",\r\n \"a\": \"Inverse fisher transformation of a specified value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse Fisher transformation.\",\r\n \"example\": \"0.962\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FISHER\",\r\n \"t\": 1,\r\n \"d\": \"Returns the Fisher transformation of a specified value.\",\r\n \"a\": \"Fisher transformation of a specified value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the Fisher transformation.\",\r\n \"example\": \"0.962\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MODE_SNGL\",\r\n \"t\": 1,\r\n \"d\": \"Returns the most commonly occurring value in a dataset.\",\r\n \"a\": \"Most commonly occurring value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating mode.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating mode.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"WEIBULL_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the Weibull distribution function (or Weibull cumulative distribution function) for a specified shape and scale.\",\r\n \"a\": \"Weibull distribution function.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the Weibull distribution function.\",\r\n \"example\": \"2.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"shape\",\r\n \"detail\": \"The shape parameter of the Weibull distribution function.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"scale\",\r\n \"detail\": \"The scale parameter of the Weibull distribution function.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the cumulative distribution function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COUNT\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of numeric values in a dataset.\",\r\n \"a\": \"The number of numeric values in dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when counting.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when counting.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of values in a dataset.\",\r\n \"a\": \"The number of values in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when counting.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when counting.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVEDEV\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the average of the magnitudes of deviations of data from a dataset's mean.\",\r\n \"a\": \"Average magnitude of deviations from mean.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGE\",\r\n \"t\": 1,\r\n \"d\": \"Returns the numerical average value in a dataset, ignoring text.\",\r\n \"a\": \"Numerical average value in a dataset, ignoring text.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the average value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the average value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGEA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the numerical average value in a dataset.\",\r\n \"a\": \"Numerical average value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the average value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the average value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BINOM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability of drawing a certain number of successes (or a maximum number of successes) in a certain number of tries given a population of a certain size containing a certain number of successes, with replacement of draws.\",\r\n \"a\": \"Binomial distribution probability.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"num_successes\",\r\n \"detail\": \"The number of successes for which to calculate the probability in `num_trials` trials.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"num_trials\",\r\n \"detail\": \"The number of independent trials.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"prob_success\",\r\n \"detail\": \"The probability of success in any given trial.\",\r\n \"example\": \"0.005\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the binomial cumulative distribution.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BINOM_INV\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the smallest value for which the cumulative binomial distribution is greater than or equal to a specified criteria.\",\r\n \"a\": \"Inverse cumulative binomial distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"num_trials\",\r\n \"detail\": \"The number of independent trials.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"prob_success\",\r\n \"detail\": \"The probability of success in any given trial.\",\r\n \"example\": \"0.005\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"target_prob\",\r\n \"detail\": \"The desired threshold probability.\",\r\n \"example\": \"0.8\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CONFIDENCE_NORM\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the width of half the confidence interval for a normal distribution.\",\r\n \"a\": \"Confidence interval for a normal distribution.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"alpha\",\r\n \"detail\": \"One minus the desired confidence level. E.g. `0.1` for `0.9`, or 90%, confidence.\",\r\n \"example\": \"0.05\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation of the population.\",\r\n \"example\": \"1.6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"pop_size\",\r\n \"detail\": \"The size of the population.\",\r\n \"example\": \"250\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CORREL\",\r\n \"t\": 1,\r\n \"d\": \"Calculates r, the Pearson product-moment correlation coefficient of a dataset.\",\r\n \"a\": \"Pearson Product-Moment Correlation Coefficient.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COVARIANCE_P\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the covariance of a dataset.\",\r\n \"a\": \"The covariance of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COVARIANCE_S\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the sample covariance of a dataset.\",\r\n \"a\": \"The sample covariance of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEVSQ\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the sum of squares of deviations based on a sample.\",\r\n \"a\": \"The sum of squares of deviations based on a sample.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EXPON_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the exponential distribution function with a specified lambda at a specified value.\",\r\n \"a\": \"Exponential distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the exponential distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"lambda\",\r\n \"detail\": \"The lambda to specify the exponential distribution function.\",\r\n \"example\": \"0.5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the exponential cumulative distribution.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGEIF\",\r\n \"t\": 1,\r\n \"d\": \"Returns the average of a range depending on criteria.\",\r\n \"a\": \"Average of values depending on criteria.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"criteria_range\",\r\n \"detail\": \"The range to check against `criterion`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criterion\",\r\n \"detail\": \"The pattern or test to apply to `criteria_range`.\",\r\n \"example\": \"\\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"average_range\",\r\n \"detail\": \"The range to average. If not included, `criteria_range` is used for the average instead.\",\r\n \"example\": \"B1:B10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGEIFS\",\r\n \"t\": 1,\r\n \"d\": \"Returns the average of a range depending on multiple criteria.\",\r\n \"a\": \"Average of values depending on multiple criteria.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"average_range\",\r\n \"detail\": \"The range to average.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range1\",\r\n \"detail\": \"The range to check against `criterion1`.\",\r\n \"example\": \" B1:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criterion1\",\r\n \"detail\": \"The pattern or test to apply to `criteria_range1`.\",\r\n \"example\": \" \\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range2\",\r\n \"detail\": \"Additional ranges to check.\",\r\n \"example\": \" C1:C10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PERMUT\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of ways to choose some number of objects from a pool of a given size of objects, considering order.\",\r\n \"a\": \"Number of permutations from a number of objects.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"n\",\r\n \"detail\": \"The size of the pool of objects to choose from.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"k\",\r\n \"detail\": \"The number of objects to choose.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TRIMMEAN\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the mean of a dataset excluding some proportion of data from the high and low ends of the dataset.\",\r\n \"a\": \"Mean of a dataset excluding high/low ends.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"Array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"exclude_proportion\",\r\n \"detail\": \"The proportion of the dataset to exclude, from the extremities of the set.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTILE_EXC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value at a given percentile of a dataset exclusive of 0 and 1.\",\r\n \"a\": \"Value at a given percentile of a dataset exclusive of 0 and 1.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"percentile\",\r\n \"detail\": \"The percentile, exclusive of 0 and 1, whose value within 'data' will be calculated and returned.\",\r\n \"example\": \"0.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTILE_INC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value at a given percentile of a dataset.\",\r\n \"a\": \"Value at a given percentile of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"percentile\",\r\n \"detail\": \"The percentile whose value within `data` will be calculated and returned.`\",\r\n \"example\": \"0.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PEARSON\",\r\n \"t\": 1,\r\n \"d\": \"Calculates r, the Pearson product-moment correlation coefficient of a dataset.\",\r\n \"a\": \"Pearson Product-Moment Correlation Coefficient.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_S_INV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the inverse standard normal distribution function for a specified value.\",\r\n \"a\": \"Inverse standard normal distribution function.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the inverse standard normal distribution function.\",\r\n \"example\": \"0.75\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_S_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the standard normal cumulative distribution function for a specified value.\",\r\n \"a\": \"Standard normal cumulative distribution function.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the standard normal cumulative distribution function.\",\r\n \"example\": \"2.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf TRUE(), it returns the cumulative distribution function;\\n\\nIf it is FALSE(), it returns the probability density function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_INV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the inverse normal distribution function for a specified value, mean, and standard deviation.\",\r\n \"a\": \"Inverse normal distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the inverse normal distribution function.\",\r\n \"example\": \"0.75\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the normal distribution function.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the normal distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the normal distribution function (or normal cumulative distribution function) for a specified value, mean, and standard deviation.\",\r\n \"a\": \"Normal distribution function.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the normal distribution function.\",\r\n \"example\": \"2.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the normal distribution function.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the normal distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the normal cumulative distribution function rather than the distribution function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NEGBINOM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability of drawing a certain number of failures before a certain number of successes given a probability of success in independent trials.\",\r\n \"a\": \"Negative binomial distribution probability.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"num_failures\",\r\n \"detail\": \"The number of failures to model.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"num_successes\",\r\n \"detail\": \"The number of successes to model.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"prob_success\",\r\n \"detail\": \"The probability of success in any given trial.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf TRUE(), it returns the cumulative distribution function;\\n\\nIf it is FALSE(), it returns the probability density function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"MINA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the minimum numeric value in a dataset.\",\r\n \"a\": \"Minimum numeric value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the minimum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the minimum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MIN\",\r\n \"t\": 1,\r\n \"d\": \"Returns the minimum value in a numeric dataset.\",\r\n \"a\": \"Minimum value in a numeric dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the minimum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the minimum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MEDIAN\",\r\n \"t\": 1,\r\n \"d\": \"Returns the median value in a numeric dataset.\",\r\n \"a\": \"Median value in a numeric dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the median value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the median value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MAXA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the maximum numeric value in a dataset.\",\r\n \"a\": \"Maximum numeric value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the maximum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the maximum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MAX\",\r\n \"t\": 1,\r\n \"d\": \"Returns the maximum value in a numeric dataset.\",\r\n \"a\": \"Maximum value in a numeric dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the maximum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the maximum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOGNORM_INV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the inverse log-normal cumulative distribution with given mean and standard deviation at a specified value.\",\r\n \"a\": \"Inverse log-normal cumulative distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the inverse log-normal cumulative distribution function.\",\r\n \"example\": \"0.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the inverse log-normal cumulative distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the inverse log-normal cumulative distribution function.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOGNORM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the log-normal cumulative distribution with given mean and standard deviation at a specified value.\",\r\n \"a\": \"Log-normal cumulative distribution probability.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the log-normal cumulative distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the log-normal cumulative distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the log-normal cumulative distribution function.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf TRUE(), it returns the cumulative distribution function;\\n\\nIf it is FALSE(), it returns the probability density function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"Z_TEST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the one-tailed p-value of a Z-test with standard distribution.\",\r\n \"a\": \"One-tailed p-value of a z-test.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"value\",\r\n \"detail\": \"The test statistic to use in the Z-test.\",\r\n \"example\": \"B2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation to assume for the Z-test. If this is not provided, the standard deviation of the data will be used.\",\r\n \"example\": \"3\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PROB\",\r\n \"t\": 1,\r\n \"d\": \"Given a set of values and corresponding probabilities, calculates the probability that a value chosen at random falls between two limits.\",\r\n \"a\": \"Probability values lie in a range.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"Array or range containing the dataset to consider.\",\r\n \"example\": \"A3:A6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"probabilities\",\r\n \"detail\": \"Array or range containing probabilities corresponding to `data`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"low_limit\",\r\n \"detail\": \"The lower bound on the value range for which to calculate the probability.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"high_limit\",\r\n \"detail\": \"The upper bound on the value range for which to calculate the probability.\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"QUARTILE_EXC\",\r\n \"t\": 1,\r\n \"d\": \"Returns a value nearest to a specified quartile of a dataset exclusive of 0 and 4.\",\r\n \"a\": \"Value nearest to a specific quartile of a dataset exclusive of 0 and 4.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"quartile_number\",\r\n \"detail\": \"Which quartile to return.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"QUARTILE_INC\",\r\n \"t\": 1,\r\n \"d\": \"Returns a value nearest to a specified quartile of a dataset.\",\r\n \"a\": \"Value nearest to a specific quartile of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"quartile_number\",\r\n \"detail\": \"Which quartile value to return.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"POISSON_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the Poisson distribution function (or Poisson cumulative distribution function) for a specified value and mean.\",\r\n \"a\": \"Poisson distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the Poisson distribution function.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the Poisson distribution function.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the Poisson cumulative distribution function rather than the distribution function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RSQ\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the square of r, the Pearson product-moment correlation coefficient of a dataset.\",\r\n \"a\": \"Square of the correlation coefficient.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the left tail probability for a Student's t-distribution with a given input (x).\",\r\n \"a\": \"The left-tailed Student's t-distribution\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the t-distribution function.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"30\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"If cumulative is TRUE, T.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"T_DIST_2T\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability for two tailed Student's t-distribution with a given input (x).\",\r\n \"a\": \"The two tailed Student's t-distribution\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the t-distribution function.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"30\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_DIST_RT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the right tail probability for a Student's t-distribution with a given input (x).\",\r\n \"a\": \"The right-tailed Student's t-distribution\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the t-distribution function.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"30\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_INV\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the negative inverse of the one-tailed TDIST function.\",\r\n \"a\": \"T.INV\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"probability\",\r\n \"detail\": \"The probability associated with the two-tailed t-distribution.\",\r\n \"example\": \"0.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_INV_2T\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the inverse of the two-tailed TDIST function.\",\r\n \"a\": \"T.INV.2T\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"probability\",\r\n \"detail\": \"The probability associated with the two-tailed t-distribution.\",\r\n \"example\": \"0.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_TEST\",\r\n \"t\": 1,\r\n \"d\": \"t-test. Returns the probability associated with Student's t-test. Determines whether two samples are likely to have come from the same two underlying populations that have the same mean.\",\r\n \"a\": \"Returns the probability associated with t-test.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"range1\",\r\n \"detail\": \"The first sample of data or group of cells to consider for the t-test.\",\r\n \"example\": \"A1:A4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"range2\",\r\n \"detail\": \"The second sample of data or group of cells to consider for the t-test.\",\r\n \"example\": \"B1:B4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"tails\",\r\n \"detail\": \"Specifies the number of distribution tails.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"type\",\r\n \"detail\": \"Specifies the type of t-test.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"F_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the left-tailed F probability distribution (degree of diversity) for two data sets with given input x. Alternately called Fisher-Snedecor distribution or Snedecor's F distribution.\",\r\n \"a\": \"F probability distribution (left-tailed).\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the F probability distribution function. The value at which to evaluate the function.\",\r\n \"example\": \"15.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom1\",\r\n \"detail\": \"The numerator of the number of degrees of freedom.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom2\",\r\n \"detail\": \"The denominator of the number of degrees of freedom.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Logical value that determines the form of the function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"F_DIST_RT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the right-tailed F probability distribution (degree of diversity) for two data sets with given input x. Alternately called Fisher-Snedecor distribution or Snedecor's F distribution.\",\r\n \"a\": \"F probability distribution.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the F probability distribution function. The value at which to evaluate the function.\",\r\n \"example\": \"15.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom1\",\r\n \"detail\": \"The numerator of the number of degrees of freedom.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom2\",\r\n \"detail\": \"The denominator of the number of degrees of freedom.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VAR_P\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on an entire population.\",\r\n \"a\": \"Variance of entire population.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VAR_S\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on a sample.\",\r\n \"a\": \"Variance.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VARA\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on a sample, setting text to the value `0`.\",\r\n \"a\": \"Variance of sample (text as 0).\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VARPA\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on an entire population, setting text to the value `0`.\",\r\n \"a\": \"Variance of entire population (text as 0).\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STEYX\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the standard error of the predicted y-value for each x in the regression of a dataset.\",\r\n \"a\": \"Standard error of predicted y-values in regression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STANDARDIZE\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the normalized equivalent of a random variable given mean and standard deviation of the distribution.\",\r\n \"a\": \"Normalized equivalent of a random variable.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value of the random variable to normalize.\",\r\n \"example\": \"96\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean of the distribution.\",\r\n \"example\": \"80\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation of the distribution.\",\r\n \"example\": \"6.7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SMALL\",\r\n \"t\": 1,\r\n \"d\": \"Returns the nth smallest element from a data set, where n is user-defined.\",\r\n \"a\": \"Nth smallest element in a data set.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"n\",\r\n \"detail\": \"The rank from smallest to largest of the element to return.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SLOPE\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the slope of the line resulting from linear regression of a dataset.\",\r\n \"a\": \"Slope of line from linear regression of data.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SKEW\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the skewness of a dataset, which describes the symmetry of that dataset about the mean.\",\r\n \"a\": \"Skewness of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the dataset.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the dataset.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SKEW_P\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the skewness of a dataset, which describes the symmetry of that dataset about the mean. This assumes the dataset is for the population.\",\r\n \"a\": \"Skewness of a population's dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the dataset.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the dataset.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"VLOOKUP\",\r\n \"t\": 2,\r\n \"d\": \"Vertical lookup. Searches down the first column of a range for a key and returns the value of a specified cell in the row found.\",\r\n \"a\": \"Vertical lookup.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"10003\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"range\",\r\n \"detail\": \"The range to consider for the search. The first column in the range is searched for the key specified in `search_key`.\",\r\n \"example\": \"A2:B26\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"index\",\r\n \"detail\": \"The column index of the value to be returned, where the first column in `range` is numbered 1.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"is_sorted\",\r\n \"detail\": \"Indicates whether the column to be searched (the first column of the specified range) is sorted, in which case the closest match for `search_key` will be returned.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HLOOKUP\",\r\n \"t\": 2,\r\n \"d\": \"Horizontal lookup. Searches across the first row of a range for a key and returns the value of a specified cell in the column found.\",\r\n \"a\": \"Horizontal lookup\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"10003\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"range\",\r\n \"detail\": \"The range to consider for the search. The first row in the range is searched for the key specified in `search_key`.\",\r\n \"example\": \"A2:Z6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"index\",\r\n \"detail\": \"The row index of the value to be returned, where the first row in `range` is numbered 1.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"is_sorted\",\r\n \"detail\": \"Indicates whether the row to be searched (the first row of the specified range) is sorted.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LOOKUP\",\r\n \"t\": 2,\r\n \"d\": \"Looks through a sorted row or column for a key and returns the value of the cell in a result range located in the same position as the search row or column.\",\r\n \"a\": \"Look up a value.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for in the row or column. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"10003\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"search_range|search_result_array\",\r\n \"detail\": \"One method of using this function is to provide a single sorted row or column `search_range` to look through for the `search_key` with a second argument `result_range`. The other way is to combine these two arguments into one `search_result_array` where the first row or column is searched and a value is returned from the last row or column in the array. If `search_key` is not found, a non-exact match may be returned.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"result_range\",\r\n \"detail\": \"The range from which to return a result. The value returned corresponds to the location where `search_key` is found in `search_range`. This range must be only a single row or column and should not be used if using the `search_result_array` method.\",\r\n \"example\": \"B1:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ADDRESS\",\r\n \"t\": 2,\r\n \"d\": \"Returns a cell reference as a string.\",\r\n \"a\": \"Cell reference as a string.\",\r\n \"m\": [2, 5],\r\n \"p\": [{\r\n \"name\": \"row\",\r\n \"detail\": \"The row number of the cell reference\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"column\",\r\n \"detail\": \"The column number (not name) of the cell reference. `A` is column number `1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"absolute_relative_mode\",\r\n \"detail\": \"An indicator of whether the reference is row/column absolute. `1` is row and column absolute (e.g. $A$1), `2` is row absolute and column relative (e.g. A$1), `3` is row relative and column absolute (e.g. $A1), and `4` is row and column relative (e.g. A1).\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"use_a1_notation\",\r\n \"detail\": \"A boolean indicating whether to use `A1` style notation (TRUE) or `R1C1` style notation (FALSE).\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"sheet\",\r\n \"detail\": \"Text indicating the name of the sheet into which the address points.\",\r\n \"example\": \"\\\"Sheet2\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"INDIRECT\",\r\n \"t\": 2,\r\n \"d\": \"Returns a cell reference specified by a string.\",\r\n \"a\": \"A cell reference specified by a string.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"cell_reference_as_string\",\r\n \"detail\": \"A cell reference, written as a string with surrounding quotation marks.\",\r\n \"example\": \"\\\"Sheet2!\\\"&B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"is_A1_notation\",\r\n \"detail\": \"Indicates if the cell reference is in A1 notation (TRUE) or R1C1 notation (FALSE).\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ROW\",\r\n \"t\": 2,\r\n \"d\": \"Returns the row number of a specified cell.\",\r\n \"a\": \"Row number of a specified cell.\",\r\n \"m\": [0, 1],\r\n \"p\": [{\r\n \"name\": \"cell_reference\",\r\n \"detail\": \"The cell whose row number will be returned.\",\r\n \"example\": \"A9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ROWS\",\r\n \"t\": 2,\r\n \"d\": \"Returns the number of rows in a specified array or range.\",\r\n \"a\": \"Number of rows in a specified array or range.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range whose row count will be returned.\",\r\n \"example\": \"A9:A62\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COLUMN\",\r\n \"t\": 2,\r\n \"d\": \"Returns the column number of a specified cell, with `A=1`.\",\r\n \"a\": \"Column number of a specified cell.\",\r\n \"m\": [0, 1],\r\n \"p\": [{\r\n \"name\": \"cell_reference\",\r\n \"detail\": \"The cell whose column number will be returned. Column `A` corresponds to `1`.\",\r\n \"example\": \"A9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COLUMNS\",\r\n \"t\": 2,\r\n \"d\": \"Returns the number of columns in a specified array or range.\",\r\n \"a\": \"Number of columns in a specified array or range.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range whose column count will be returned.\",\r\n \"example\": \"A9:W62\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"OFFSET\",\r\n \"t\": 2,\r\n \"d\": \"Returns a range reference shifted a specified number of rows and columns from a starting cell reference.\",\r\n \"a\": \"A range reference offset relative to a cell.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"cell_reference\",\r\n \"detail\": \"The starting point from which to count the offset rows and columns.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"offset_rows\",\r\n \"detail\": \"The number of rows to offset by.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"offset_columns\",\r\n \"detail\": \"The number of columns to offset by.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"height\",\r\n \"detail\": \"The height of the range to return starting at the offset target.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"width\",\r\n \"detail\": \"The width of the range to return starting at the offset target.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MATCH\",\r\n \"t\": 2,\r\n \"d\": \"Returns the relative position of an item in a range that matches a specified value.\",\r\n \"a\": \"Position of item in range that matches value.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"\\\"Sunday\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"range\",\r\n \"detail\": \"The one-dimensional array to be searched.\",\r\n \"example\": \"A2:A9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"search_type\",\r\n \"detail\": \"The search method. `1` (default) finds the largest value less than or equal to `search_key` when `range` is sorted in ascending order. `0` finds the exact value when `range` is unsorted. `-1` finds the smallest value greater than or equal to `search_key` when `range` is sorted in descending order.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"INDEX\",\r\n \"t\": 2,\r\n \"d\": \"Returns the content of a cell, specified by row and column offset.\",\r\n \"a\": \"Content of cell specified by row and column offset.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"reference\",\r\n \"detail\": \"The array of cells to be offset into.\",\r\n \"example\": \"A1:C20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"row\",\r\n \"detail\": \"The number of offset rows.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"column\",\r\n \"detail\": \"The number of offset columns.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GETPIVOTDATA\",\r\n \"t\": 2,\r\n \"d\": \"Extracts an aggregated value from a pivot table that corresponds to the specified row and column headings.\",\r\n \"a\": \"Extracts an aggregated value from a pivot table that corresponds to the specified row and column headings.\",\r\n \"m\": [2, 254],\r\n \"p\": [{\r\n \"name\": \"value_name\",\r\n \"detail\": \"The name of the value in the pivot table for which you want to get data.\",\r\n \"example\": \"\\\"SUM of number of units\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"any_pivot_table_cell\",\r\n \"detail\": \"Any reference to a cell in the desired pivot table (top corner recommended).\",\r\n \"example\": \"'Pivot table'!A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"original_column\",\r\n \"detail\": \"The name of the column in the original data set (not the pivot table).\",\r\n \"example\": \"\\\"division\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"pivot_item\",\r\n \"detail\": \"The name of the row or column shown in the pivot table corresponding to *original_column* that you want to retrieve.\",\r\n \"example\": \"\\\"east\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CHOOSE\",\r\n \"t\": 2,\r\n \"d\": \"Returns an element from a list of choices based on index.\",\r\n \"a\": \"An element from a list of choices based on index.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"index\",\r\n \"detail\": \"Which choice (of the up to 30 provided) to return.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"choice1\",\r\n \"detail\": \"A potential value to return. Required. May be a reference to a cell or an individual value.\",\r\n \"example\": \"\\\"A\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"choice2\",\r\n \"detail\": \"Additional values among which to choose.\",\r\n \"example\": \"\\\"B\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HYPERLINK\",\r\n \"t\": 2,\r\n \"d\": \"Creates a hyperlink inside a cell.\",\r\n \"a\": \"Creates a hyperlink inside a cell.\",\r\n \"p\": [{\r\n \"name\": \"url\",\r\n \"detail\": \"The full URL of the link location enclosed in quotation marks, or a reference to a cell containing such a URL.\",\r\n \"example\": \"\\\"http://www.luckysheet.com/\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"link_label\",\r\n \"detail\": \"The text to display in the cell as the link, enclosed in quotation marks, or a reference to a cell containing such a label.\",\r\n \"example\": \"\\\"luckysheet\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TIME\",\r\n \"t\": 6,\r\n \"d\": \"Converts a provided hour, minute, and second into a time.\",\r\n \"a\": \"Converts hour/minute/second into a time.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"hour\",\r\n \"detail\": \"The hour component of the time.\",\r\n \"example\": \"11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"minute\",\r\n \"detail\": \"The minute component of the time.\",\r\n \"example\": \"40\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"second\",\r\n \"detail\": \"The second component of the time.\",\r\n \"example\": \"59\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TIMEVALUE\",\r\n \"t\": 6,\r\n \"d\": \"Returns the fraction of a 24-hour day the time represents.\",\r\n \"a\": \"Converts a time string into its serial number representation.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time_string\",\r\n \"detail\": \"The string that holds the time representation.\",\r\n \"example\": \"\\\"2:15 PM\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EOMONTH\",\r\n \"t\": 6,\r\n \"d\": \"Returns a date on the last day of a month that falls a specified number of months before or after another date.\",\r\n \"a\": \"Last day of a month before or after a date.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to calculate the result.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"months\",\r\n \"detail\": \"The number of months before (negative) or after (positive) 'start_date' to consider.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EDATE\",\r\n \"t\": 6,\r\n \"d\": \"Returns a date a specified number of months before or after another date.\",\r\n \"a\": \"Date a number of months before/after another date.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to calculate the result.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"months\",\r\n \"detail\": \"The number of months before (negative) or after (positive) 'start_date' to calculate.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SECOND\",\r\n \"t\": 6,\r\n \"d\": \"Returns the second component of a specific time, in numeric format.\",\r\n \"a\": \"Second component of a specific time.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time\",\r\n \"detail\": \"The time from which to calculate the second component\",\r\n \"example\": \"TIME(11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"MINUTE\",\r\n \"t\": 6,\r\n \"d\": \"Returns the minute component of a specific time, in numeric format.\",\r\n \"a\": \"Minute component of a specific time.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time\",\r\n \"detail\": \"The time from which to calculate the minute component.\",\r\n \"example\": \"TIME(11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HOUR\",\r\n \"t\": 6,\r\n \"d\": \"Returns the hour component of a specific time, in numeric format.\",\r\n \"a\": \"Hour component of a specific time.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time\",\r\n \"detail\": \"The time from which to calculate the hour component.\",\r\n \"example\": \"TIME(11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NOW\",\r\n \"t\": 6,\r\n \"d\": \"Returns the current date and time as a date value.\",\r\n \"a\": \"Current date and time as a date value.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"NETWORKDAYS\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of net working days between two provided days.\",\r\n \"a\": \"Net working days between two provided days.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the date serial numbers to consider holidays.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NETWORKDAYS_INTL\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of net working days between two provided days excluding specified weekend days and holidays.\",\r\n \"a\": \"Net working days between two dates (specifying weekends).\",\r\n \"m\": [2, 4],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"weekend\",\r\n \"detail\": \"A number or string representing which days of the week are considered weekends.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the dates to consider as holidays.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISOWEEKNUM\",\r\n \"t\": 6,\r\n \"d\": \"Returns a number representing the ISO week of the year where the provided date falls.\",\r\n \"a\": \"ISO week number of the year.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date for which to determine the ISO week number. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"WEEKNUM\",\r\n \"t\": 6,\r\n \"d\": \"Returns a number representing the week of the year where the provided date falls.\",\r\n \"a\": \"Week number of the year.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date for which to determine the week number. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"type\",\r\n \"detail\": \"A number representing the day that a week starts on. Sunday = 1.\",\r\n \"example\": \"7\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"WEEKDAY\",\r\n \"t\": 6,\r\n \"d\": \"Returns a number representing the day of the week of the date provided.\",\r\n \"a\": \"Day of the week of the date provided (as number).\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date for which to determine the day of the week. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"type\",\r\n \"detail\": \"A number indicating which numbering system to use to represent weekdays. By default, counts starting with Sunday = 1.\",\r\n \"example\": \"7\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DAY\",\r\n \"t\": 6,\r\n \"d\": \"Returns the day of the month that a specific date falls on, in numeric format.\",\r\n \"a\": \"Day of the month that a specific date falls on.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date from which to extract the day.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DAYS\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of days between two dates.\",\r\n \"a\": \"Number of days between two dates.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end of the date range.\",\r\n \"example\": \"2011-3-15\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start of the date range.\",\r\n \"example\": \"2011-2-1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DAYS360\",\r\n \"t\": 6,\r\n \"d\": \"Returns the difference between two days based on the 360 day year used in some financial interest calculations.\",\r\n \"a\": \"Days between two dates on a 360-day year.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"method\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DATE\",\r\n \"t\": 6,\r\n \"d\": \"Converts a provided year, month, and day into a date.\",\r\n \"a\": \"Converts year/month/day into a date.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"year\",\r\n \"detail\": \"The year component of the date.\",\r\n \"example\": \"1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"month\",\r\n \"detail\": \"The month component of the date.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day\",\r\n \"detail\": \"The day component of the date.\",\r\n \"example\": \"20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATEVALUE\",\r\n \"t\": 6,\r\n \"d\": \"Converts a provided date string in a known format to a date value.\",\r\n \"a\": \"Converts a date string to a date value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date_string\",\r\n \"detail\": \"The string representing the date.\",\r\n \"example\": \"\\\"1969-7-20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DATEDIF\",\r\n \"t\": 6,\r\n \"d\": \"Calculates the number of days, months, or years between two dates.\",\r\n \"a\": \"Date Difference.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"unit\",\r\n \"detail\": \"A string abbreviation for unit of time. For example, \\\"M\\\" for month. Accepted values are \\\"Y\\\",\\\"M\\\",\\\"D\\\",\\\"MD\\\",\\\"YM\\\",\\\"YD\\\".\",\r\n \"example\": \"16)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"WORKDAY\",\r\n \"t\": 6,\r\n \"d\": \"Calculates the date after a number of working days from a specified start date.\",\r\n \"a\": \"Number of working days from start date.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to begin counting.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"num_days\",\r\n \"detail\": \"The number of working days to advance from `start_date`. If negative, counts backwards.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the dates to consider holidays.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"WORKDAY_INTL\",\r\n \"t\": 6,\r\n \"d\": \"Calculates the date after a specified number of workdays excluding specified weekend days and holidays.\",\r\n \"a\": \"Date after a number of workdays (specifying weekends).\",\r\n \"m\": [2, 4],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to begin counting.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"num_days\",\r\n \"detail\": \"The number of working days to advance from `start_date`. If negative, counts backwards.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"weekend\",\r\n \"detail\": \"A number or string representing which days of the week are considered weekends.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the dates to consider holidays.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"YEAR\",\r\n \"t\": 6,\r\n \"d\": \"Returns the year specified by a given date.\",\r\n \"a\": \"Year specified by a given date.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date from which to extract the year.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"YEARFRAC\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of years, including fractional years, between two dates using a specified day count convention.\",\r\n \"a\": \"Exact number of years between two dates.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TODAY\",\r\n \"t\": 6,\r\n \"d\": \"Returns the current date as a date value.\",\r\n \"a\": \"Current date as a date value.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"MONTH\",\r\n \"t\": 6,\r\n \"d\": \"Returns the month of the year a specific date falls in, in numeric format.\",\r\n \"a\": \"Month of the year a specific date falls in.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date from which to extract the month.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EFFECT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual effective interest rate given the nominal rate and number of compounding periods per year.\",\r\n \"a\": \"Annual effective interest rate.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"nominal_rate\",\r\n \"detail\": \"The nominal interest rate per year.\",\r\n \"example\": \"0.99\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"periods_per_year\",\r\n \"detail\": \"The number of compounding periods per year.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DOLLAR\",\r\n \"t\": 12,\r\n \"d\": \"Formats a number into the currency specific to your spreadsheet locale.\",\r\n \"a\": \"Formats a number as currency specific to your spreadsheet locale.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The value to be formatted.\",\r\n \"example\": \"1.2351\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_places\",\r\n \"detail\": \"The number of decimal places to display.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DOLLARDE\",\r\n \"t\": 8,\r\n \"d\": \"Converts a price quotation given as a decimal fraction into a decimal value.\",\r\n \"a\": \"Converts a decimal fraction to decimal value.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"fractional_price\",\r\n \"detail\": \"The price quotation given using fractional decimal conventions.\",\r\n \"example\": \"100.10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"unit\",\r\n \"detail\": \"The units of the fraction, e.g. `8` for 1/8ths or `32` for 1/32nds.\",\r\n \"example\": \"32\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DOLLARFR\",\r\n \"t\": 8,\r\n \"d\": \"Converts a price quotation given as a decimal value into a decimal fraction.\",\r\n \"a\": \"Converts a decimal value to decimal fraction.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_price\",\r\n \"detail\": \"The price quotation given as a decimal value.\",\r\n \"example\": \"100.125\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"unit\",\r\n \"detail\": \"The units of the desired fraction, e.g. `8` for 1/8ths or `32` for 1/32nds.\",\r\n \"example\": \"32\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DB\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for a specified period using the arithmetic declining balance method.\",\r\n \"a\": \"Depreciation via declining balance method.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"50\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The single period within `life` for which to calculate depreciation.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"month\",\r\n \"detail\": \"The number of months in the first year of depreciation.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DDB\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for a specified period using the double-declining balance method.\",\r\n \"a\": \"Depreciation via double-declining balance method.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"50\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The single period within `life` for which to calculate depreciation.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The factor by which depreciation decreases.\",\r\n \"example\": \"2.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RATE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the interest rate of an annuity investment based on constant-amount periodic payments and the assumption of a constant interest rate.\",\r\n \"a\": \"Interest rate of an annuity investment.\",\r\n \"m\": [3, 6],\r\n \"p\": [{\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_per_period\",\r\n \"detail\": \"The amount per period to be paid.\",\r\n \"example\": \"-100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"400\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"rate_guess\",\r\n \"detail\": \"An estimate for what the interest rate will be.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CUMPRINC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the cumulative principal paid over a range of payment periods for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Cumulative principal paid over a set of periods.\",\r\n \"m\": [6, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"first_period\",\r\n \"detail\": \"The number of the payment period to begin the cumulative calculation.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"last_period\",\r\n \"detail\": \"The number of the payment period to end the cumulative calculation.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPNUM\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of coupons, or interest payments, between the settlement date and the maturity date of the investment.\",\r\n \"a\": \"Number of coupons between settlement and maturity.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"02\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SYD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for a specified period using the sum of years digits method.\",\r\n \"a\": \"Depreciation via sum of years digits method.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"50\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The single period within `life` for which to calculate depreciation.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TBILLEQ\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the equivalent annualized rate of return of a US Treasury Bill based on discount rate.\",\r\n \"a\": \"Equivalent rate of return for a Treasury bill.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the bill at time of purchase.\",\r\n \"example\": \"2)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TBILLYIELD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the yield of a US Treasury Bill based on price.\",\r\n \"a\": \"The yield of a us treasury bill based on price.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"95\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TBILLPRICE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a US Treasury Bill based on discount rate.\",\r\n \"a\": \"Price of US treasury bill.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the bill at time of purchase.\",\r\n \"example\": \"0.09\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the present value of an annuity investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Present value of an annuity investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_amount\",\r\n \"detail\": \"The amount per period to be paid.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"D2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ACCRINT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the accrued interest of a security that has periodic payments.\",\r\n \"a\": \"Accrued interest of security with periodic payments.\",\r\n \"m\": [6, 8],\r\n \"p\": [{\r\n \"name\": \"issue\",\r\n \"detail\": \"The date the security was initially issued.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"first_payment\",\r\n \"detail\": \"The first date interest will be paid.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"10000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"calc_method\",\r\n \"detail\": \"[Optional-defaults to TRUE()] - A logical value that specifies the method used to calculate the total accrued interest when the settlement date is later than the first interest accrual date. \\n\\nIf the value is TRUE, the total accrued interest from the issue date to the settlement date is returned. \\n\\nIf the value is FALSE, return the accrued interest from the first interest accrual date to the settlement date.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ACCRINTM\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the accrued interest of a security that pays interest at maturity.\",\r\n \"a\": \"Accrued interest of security paying at maturity.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"issue\",\r\n \"detail\": \"The date the security was initially issued.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity date of the security.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"1000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPDAYBS\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of days from the first coupon, or interest payment, until settlement.\",\r\n \"a\": \"Number of days from first coupon to settlement.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPDAYS\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of days in the coupon, or interest payment, period that contains the specified settlement date.\",\r\n \"a\": \"Days in coupon period containing settlement date.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPDAYSNC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of days from the settlement date until the next coupon, or interest payment.\",\r\n \"a\": \"Days from settlement until next coupon.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPNCD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates next coupon, or interest payment, date after the settlement date.\",\r\n \"a\": \"Next coupon date after the settlement date.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"01)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"DATE(2019\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPPCD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates last coupon, or interest payment, date before the settlement date.\",\r\n \"a\": \"Last coupon date before settlement date.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"01)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"DATE(2019\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the future value of an annuity investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Future value of an annuity investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_amount\",\r\n \"detail\": \"The amount per period to be paid.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"400\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FVSCHEDULE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the future value of some principal based on a specified series of potentially varying interest rates.\",\r\n \"a\": \"Future value of principal from series of rates.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"principal\",\r\n \"detail\": \"The amount of initial capital or value to compound against.\",\r\n \"example\": \"10000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"rate_schedule\",\r\n \"detail\": \"A series of interest rates to compound against the `principal`.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"YIELD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual yield of a security paying periodic interest, such as a US Treasury Bond, based on price.\",\r\n \"a\": \"Annual yield of a security paying periodic interest.\",\r\n \"m\": [6, 7],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.057\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"95\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"YIELDDISC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual yield of a discount (non-interest-bearing) security, based on price.\",\r\n \"a\": \"Annual yield of a discount security.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"95\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NOMINAL\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual nominal interest rate given the effective rate and number of compounding periods per year.\",\r\n \"a\": \"Annual nominal interest rate.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"effective_rate\",\r\n \"detail\": \"The effective interest rate per year.\",\r\n \"example\": \"0.85\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"periods_per_year\",\r\n \"detail\": \"The number of compounding periods per year.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"XIRR\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the internal rate of return of an investment based on a specified series of potentially irregularly spaced cash flows.\",\r\n \"a\": \"Internal rate of return given non-periodic cashflows.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"An array or range containing the income or payments associated with the investment.\",\r\n \"example\": \"B2:B25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"cashflow_dates\",\r\n \"detail\": \"An array or range with dates corresponding to the cash flows in `cashflow_amounts`.\",\r\n \"example\": \"C2:C25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"rate_guess\",\r\n \"detail\": \"An estimate for what the internal rate of return will be.\",\r\n \"example\": \"250\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MIRR\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the modified internal rate of return on an investment based on a series of periodic cash flows and the difference between the interest rate paid on financing versus the return received on reinvested income.\",\r\n \"a\": \"Modified internal rate of return.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"An array or range containing the income or payments associated with the investment.\",\r\n \"example\": \"A2:A25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"financing_rate\",\r\n \"detail\": \"The interest rate paid on funds invested.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"reinvestment_return_rate\",\r\n \"detail\": \"The return (as a percentage) earned on reinvestment of income received from the investment.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"IRR\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the internal rate of return on an investment based on a series of periodic cash flows.\",\r\n \"a\": \"Internal rate of return given periodic cashflows.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"An array or range containing the income or payments associated with the investment.\",\r\n \"example\": \"A2:A25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"rate_guess\",\r\n \"detail\": \"An estimate for what the internal rate of return will be.\",\r\n \"example\": \"200\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NPV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the net present value of an investment based on a series of periodic cash flows and a discount rate.\",\r\n \"a\": \"The net present value of an investment based on a series of periodic cash flows and a discount rate.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the investment over one period.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cashflow1\",\r\n \"detail\": \"The first future cash flow.\",\r\n \"example\": \"200\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"cashflow2\",\r\n \"detail\": \"Additional future cash flows.\",\r\n \"example\": \"250\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"XNPV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the net present value of an investment based on a specified series of potentially irregularly spaced cash flows and a discount rate.\",\r\n \"a\": \"Net present value given non-periodic cashflows.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the investment over one period.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"A range of cells containing the income or payments associated with the investment.\",\r\n \"example\": \"B2:B25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"cashflow_dates\",\r\n \"detail\": \"A range of cells with dates corresponding to the cash flows in `cashflow_amounts`.\",\r\n \"example\": \"C2:C25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"CUMIPMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the cumulative interest over a range of payment periods for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Cumulative interest paid over a set of periods.\",\r\n \"m\": [6, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"first_period\",\r\n \"detail\": \"The number of the payment period to begin the cumulative calculation.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"last_period\",\r\n \"detail\": \"The number of the payment period to end the cumulative calculation.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the periodic payment for an annuity investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Periodic payment for an annuity investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.08\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \" 100000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"D2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"IPMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the payment on interest for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Payment on interest for an investment.\",\r\n \"m\": [4, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The amortization period, in terms of number of periods.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"80000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"E2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PPMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the payment on the principal of an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Payment on the principal of an investment.\",\r\n \"m\": [4, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The amortization period, in terms of number of periods.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"3*12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"100000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"INTRATE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the effective interest rate generated when an investment is purchased at one price and sold at another with no interest or dividends generated by the investment itself.\",\r\n \"a\": \"Calculates effective interest rate.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"buy_date\",\r\n \"detail\": \"The date of purchase of the investment.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"sell_date\",\r\n \"detail\": \"The date of sale of the investment.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"buy_price\",\r\n \"detail\": \"The price at which the investment was purchased.\",\r\n \"example\": \"100000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"sell_price\",\r\n \"detail\": \"The price at which the investment was sold.\",\r\n \"example\": \"101200\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PRICE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a security paying periodic interest, such as a US Treasury Bond, based on expected yield.\",\r\n \"a\": \"Price of a security paying periodic interest.\",\r\n \"m\": [6, 7],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.057\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.065\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PRICEDISC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a discount (non-interest-bearing) security, based on expected yield.\",\r\n \"a\": \"Price of a discount security.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the security at time of purchase.\",\r\n \"example\": \"0.0525\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PRICEMAT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a security paying interest at maturity, based on expected yield.\",\r\n \"a\": \"Price of security paying interest at maturity.\",\r\n \"m\": [5, 6],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"issue\",\r\n \"detail\": \"The date the security was initially issued.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.061\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.061\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RECEIVED\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the amount received at maturity for an investment in fixed-income securities purchased on a given date.\",\r\n \"a\": \"Amount received at maturity for a security.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"investment\",\r\n \"detail\": \"The amount invested (irrespective of face value of each security).\",\r\n \"example\": \"10000000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the security invested in.\",\r\n \"example\": \"0.0575\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DISC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the discount rate of a security based on price.\",\r\n \"a\": \"The discount rate of a security based on price.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"97.975\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NPER\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of payment periods for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Number of payment periods for an investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_amount\",\r\n \"detail\": \"The amount of each payment made.\",\r\n \"example\": \"500\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"40000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SLN\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for one period using the straight-line method.\",\r\n \"a\": \"Depreciation of asset using the straight-line method.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"300000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"75000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DURATION\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of compounding periods required for an investment of a specified present value appreciating at a given rate to reach a target value.\",\r\n \"a\": \"Number of periods for an investment to reach a value.\",\r\n \"m\": [5, 6],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.08\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.09\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MDURATION\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the modified Macaulay duration of a security paying periodic interest, such as a US Treasury Bond, based on expected yield.\",\r\n \"a\": \"Modified Macaulay duration.\",\r\n \"m\": [5, 6],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.08\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.09\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"BIN2DEC\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed binary number to decimal format.\",\r\n \"a\": \"Converts a signed binary number to decimal format.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"signed_binary_number\",\r\n \"detail\": \"The signed 10-bit binary value to be converted to decimal, provided as a string.\",\r\n \"example\": \"101\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BIN2HEX\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed binary number to signed hexadecimal format.\",\r\n \"a\": \"Converts a binary number to hexadecimal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_binary_number\",\r\n \"detail\": \"The signed 10-bit binary value to be converted to signed hexademical, provided as a string.\",\r\n \"example\": \"101\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"BIN2OCT\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed binary number to signed octal format.\",\r\n \"a\": \"Converts a binary number to octal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_binary_number\",\r\n \"detail\": \"The signed 10-bit binary value to be converted to signed octal, provided as a string.\",\r\n \"example\": \"101\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEC2BIN\",\r\n \"t\": 9,\r\n \"d\": \"Converts a decimal number to signed binary format.\",\r\n \"a\": \"Converts a decimal number to signed binary format.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_number\",\r\n \"detail\": \"The decimal value to be converted to signed binary, provided as a string.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEC2HEX\",\r\n \"t\": 9,\r\n \"d\": \"Converts a decimal number to signed hexadecimal format.\",\r\n \"a\": \"Converts a decimal number to hexadecimal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_number\",\r\n \"detail\": \"The decimal value to be converted to signed hexadecimal, provided as a string.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEC2OCT\",\r\n \"t\": 9,\r\n \"d\": \"Converts a decimal number to signed octal format.\",\r\n \"a\": \"Converts a decimal number to signed octal format.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_number\",\r\n \"detail\": \"The decimal value to be converted to signed octal, provided as a string.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HEX2BIN\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed hexadecimal number to signed binary format.\",\r\n \"a\": \"Converts a hexadecimal number to binary.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_hexadecimal_number\",\r\n \"detail\": \"The signed 40-bit hexadecimal value to be converted to signed binary, provided as a string.\",\r\n \"example\": \"\\\"f3\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HEX2DEC\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed hexadecimal number to decimal format.\",\r\n \"a\": \"Converts a hexadecimal number to decimal.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"signed_hexadecimal_number\",\r\n \"detail\": \"The signed 40-bit hexadecimal value to be converted to decimal, provided as a string.\",\r\n \"example\": \"\\\"f3\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HEX2OCT\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed hexadecimal number to signed octal format.\",\r\n \"a\": \"Converts a hexadecimal number to octal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_hexadecimal_number\",\r\n \"detail\": \"The signed 40-bit hexadecimal value to be converted to signed octal, provided as a string.\",\r\n \"example\": \"\\\"f3\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"OCT2BIN\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed octal number to signed binary format.\",\r\n \"a\": \"Converts an octal number to binary.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_octal_number\",\r\n \"detail\": \"The signed 30-bit octal value to be converted to signed binary, provided as a string.\",\r\n \"example\": \"37\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"OCT2DEC\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed octal number to decimal format.\",\r\n \"a\": \"Converts a signed octal number to decimal format.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"signed_octal_number\",\r\n \"detail\": \"The signed 30-bit octal value to be converted to decimal, provided as a string.\",\r\n \"example\": \"37\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"OCT2HEX\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed octal number to signed hexadecimal format.\",\r\n \"a\": \"Converts an octal number to hexadecimal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_octal_number\",\r\n \"detail\": \"The signed 30-bit octal value to be converted to signed hexadecimal, provided as a string.\",\r\n \"example\": \"37\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COMPLEX\",\r\n \"t\": 9,\r\n \"d\": \"Creates a complex number given real and imaginary coefficients.\",\r\n \"a\": \"Creates a complex number.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"real_part\",\r\n \"detail\": \"The real coefficient.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"imaginary_part\",\r\n \"detail\": \"The imaginary coefficient.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"suffix\",\r\n \"detail\": \"The suffix for the imaginary coefficient, can only be 'i' or 'j'. If omitted, 'i' will be used.\",\r\n \"example\": \"\\\"j\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangestring\"\r\n }]\r\n }, {\r\n \"n\": \"IMREAL\",\r\n \"t\": 9,\r\n \"d\": \"Returns the real coefficient of a complex number.\",\r\n \"a\": \"The real coefficient of a complex number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"complex_number\",\r\n \"detail\": \"The complex number, in the a+bi or a+bj format.\",\r\n \"example\": \"\\\"4+5i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMAGINARY\",\r\n \"t\": 9,\r\n \"d\": \"Returns the imaginary coefficient of a complex number.\",\r\n \"a\": \"The imaginary coefficient of a complex number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"complex_number\",\r\n \"detail\": \"The complex number, in the a+bi or a+bj format.\",\r\n \"example\": \"\\\"4+5i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMCONJUGATE\",\r\n \"t\": 9,\r\n \"d\": \"Returns the complex conjugate of a number.\",\r\n \"a\": \"The complex conjugate of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The complex number to calculate the conjugate for.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMABS\",\r\n \"t\": 9,\r\n \"d\": \"Returns absolute value (or modulus) of a complex number.\",\r\n \"a\": \"The absolute value of a complex number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The complex number to calculate the absolute value of.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DELTA\",\r\n \"t\": 9,\r\n \"d\": \"Compare two numeric values, returning 1 if they're equal.\",\r\n \"a\": \"Compare two numeric values.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"number1\",\r\n \"detail\": \"The first number to compare.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number2\",\r\n \"detail\": \"The second number to compare.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"IMSUM\",\r\n \"t\": 9,\r\n \"d\": \"Returns the sum of a series of complex numbers.\",\r\n \"a\": \"Sum of a series of complex numbers.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first complex number or range to add together.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional complex numbers or ranges to add to `value1`.\",\r\n \"example\": \"\\\"5-3i\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMSUB\",\r\n \"t\": 9,\r\n \"d\": \"Returns the difference between two complex numbers.\",\r\n \"a\": \"The difference between two complex numbers.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"first_number\",\r\n \"detail\": \"The complex number to subtract second_number from.\",\r\n \"example\": \"\\\"6+5i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"second_number\",\r\n \"detail\": \"The complex number to subtract from first_number.\",\r\n \"example\": \"\\\"2+3i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMPRODUCT\",\r\n \"t\": 9,\r\n \"d\": \"Returns the result of multiplying a series of complex numbers together.\",\r\n \"a\": \"Result of multiplying a series of complex numbers together.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"factor1\",\r\n \"detail\": \"The first number or range to calculate for the product.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"factor2\",\r\n \"detail\": \"Additional complex numbers or ranges to calculate for the product.\",\r\n \"example\": \"\\\"5-3i\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMDIV\",\r\n \"t\": 9,\r\n \"d\": \"Returns one complex number divided by another.\",\r\n \"a\": \"One complex number divided by another.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The complex number to be divided.\",\r\n \"example\": \"\\\"11+16i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The complex number to divide by.\",\r\n \"example\": \"\\\"3+2i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NOT\",\r\n \"t\": 10,\r\n \"d\": \"Returns the opposite of a logical value - `NOT(TRUE)` returns `FALSE`; `NOT(FALSE)` returns `TRUE`.\",\r\n \"a\": \"Returns opposite of provided logical value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"logical_expression\",\r\n \"detail\": \"An expression or reference to a cell holding an expression that represents some logical value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TRUE\",\r\n \"t\": 10,\r\n \"d\": \"Returns the logical value `TRUE`.\",\r\n \"a\": \"Logical value `true`.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"FALSE\",\r\n \"t\": 10,\r\n \"d\": \"Returns the logical value `FALSE`.\",\r\n \"a\": \"Logical value `false`.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"AND\",\r\n \"t\": 10,\r\n \"d\": \"Returns true if all of the provided arguments are logically true, and false if any of the provided arguments are logically false.\",\r\n \"a\": \"Logical `and` operator.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"logical_expression1\",\r\n \"detail\": \"An expression or reference to a cell containing an expression that represents some logical value, i.e. `TRUE` or `FALSE`, or an expression that can be coerced to a logical value.\",\r\n \"example\": \"A2 = \\\"foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"logical_expression2\",\r\n \"detail\": \"More expressions that represent logical values.\",\r\n \"example\": \"A3 = \\\"bar\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IFERROR\",\r\n \"t\": 10,\r\n \"d\": \"Returns the first argument if it is not an error value, otherwise returns the second argument if present, or a blank if the second argument is absent.\",\r\n \"a\": \"Value if it is not an error, otherwise 2nd argument.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to return if `value` itself is not an error.\",\r\n \"example\": \"A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_if_error\",\r\n \"detail\": \"The value the function returns if `value` is an error.\",\r\n \"example\": \"\\\"Error in cell A1\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IF\",\r\n \"t\": 10,\r\n \"d\": \"Returns one value if a logical expression is `TRUE` and another if it is `FALSE`.\",\r\n \"a\": \"Returns value depending on logical expression.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"logical_expression\",\r\n \"detail\": \"An expression or reference to a cell containing an expression that represents some logical value, i.e. `TRUE` or `FALSE`.\",\r\n \"example\": \"A2 = \\\"foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_if_true\",\r\n \"detail\": \"The value the function returns if `logical_expression` is `TRUE`.\",\r\n \"example\": \"\\\"A2 is foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_if_false\",\r\n \"detail\": \"The value the function returns if `logical_expression` is `FALSE`.\",\r\n \"example\": \"\\\"A2 was false\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"OR\",\r\n \"t\": 10,\r\n \"d\": \"Returns true if any of the provided arguments are logically true, and false if all of the provided arguments are logically false.\",\r\n \"a\": \"Logical `or` operator.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"logical_expression1\",\r\n \"detail\": \"An expression or reference to a cell containing an expression that represents some logical value, i.e. `TRUE` or `FALSE`, or an expression that can be coerced to a logical value.\",\r\n \"example\": \"A2 = \\\"foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"logical_expression2\",\r\n \"detail\": \"More expressions that evaluate to logical values.\",\r\n \"example\": \" A3 = \\\"bar\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NE\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if two specified values are not equal and `FALSE` otherwise. Equivalent to the `!=` operator.\",\r\n \"a\": \"Not equal.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The value to test against `value1` for inequality.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EQ\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if two specified values are equal and `FALSE` otherwise. Equivalent to the `==` operator.\",\r\n \"a\": \"Equal.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The value to test against `value1` for equality.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"GT\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is strictly greater than the second, and `FALSE` otherwise. Equivalent to the `>` operator.\",\r\n \"a\": \"Strictly greater than.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being greater than `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"GTE\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is greater than or equal to the second, and `FALSE` otherwise. Equivalent to the `>=` operator.\",\r\n \"a\": \"Greater than or equal to.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being greater than or equal to `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LT\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is strictly less than the second, and `FALSE` otherwise. Equivalent to the `<` operator.\",\r\n \"a\": \"Less than.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being less than `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LTE\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is less than or equal to the second, and `FALSE` otherwise. Equivalent to the `<=` operator.\",\r\n \"a\": \"Less than or equal to.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being less than or equal to `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ADD\",\r\n \"t\": 11,\r\n \"d\": \"Returns the sum of two numbers. Equivalent to the `+` operator.\",\r\n \"a\": \"Sum of two numbers\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first addend.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second addend.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MINUS\",\r\n \"t\": 11,\r\n \"d\": \"Returns the difference of two numbers. Equivalent to the `-` operator.\",\r\n \"a\": \"Difference of two numbers\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The minuend, or number to be subtracted from.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The subtrahend, or number to subtract from `value1`.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MULTIPLY\",\r\n \"t\": 11,\r\n \"d\": \"Returns the product of two numbers. Equivalent to the `*` operator.\",\r\n \"a\": \"Product of two numbers\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"factor1\",\r\n \"detail\": \"The first multiplicand.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor2\",\r\n \"detail\": \"The second multiplicand.\",\r\n \"example\": \"B2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DIVIDE\",\r\n \"t\": 11,\r\n \"d\": \"Returns one number divided by another. Equivalent to the `/` operator.\",\r\n \"a\": \"One number divided by another\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The number to be divided.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The number to divide by.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CONCAT\",\r\n \"t\": 11,\r\n \"d\": \"Returns the concatenation of two values. Equivalent to the `&` operator.\",\r\n \"a\": \"Concatenation of two values\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to which `value2` will be appended.\",\r\n \"example\": \"\\\"de\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The value to append to `value1`.\",\r\n \"example\": \"\\\"mystify\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"UNARY_PERCENT\",\r\n \"t\": 11,\r\n \"d\": \"Returns a value interpreted as a percentage; that is, `UNARY_PERCENT(100)` equals `1`.\",\r\n \"a\": \"Value interpreted as a percentage.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"percentage\",\r\n \"detail\": \"The value to interpret as a percentage.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CONCATENATE\",\r\n \"t\": 12,\r\n \"d\": \"Appends strings to one another.\",\r\n \"a\": \"Appends strings to one another.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"string1\",\r\n \"detail\": \"The initial string.\",\r\n \"example\": \"\\\"Super\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"string2\",\r\n \"detail\": \"More strings to append in sequence.\",\r\n \"example\": \"\\\"calla\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CODE\",\r\n \"t\": 12,\r\n \"d\": \"Returns the numeric Unicode map value of the first character in the string provided.\",\r\n \"a\": \"Numeric unicode map value of character.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string whose first character's Unicode map value will be returned.\",\r\n \"example\": \"\\\"a\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CHAR\",\r\n \"t\": 12,\r\n \"d\": \"Convert a number into a character according to the current Unicode table.\",\r\n \"a\": \"Gets character associated with number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"table_number\",\r\n \"detail\": \"The number of the character to look up from the current Unicode table in decimal format.\",\r\n \"example\": \"97\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ARABIC\",\r\n \"t\": 12,\r\n \"d\": \"Computes the value of a Roman numeral.\",\r\n \"a\": \"Computes the value of a roman numeral.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"roman_numeral\",\r\n \"detail\": \"The Roman numeral to format, whose value must be between 1 and 3999, inclusive.\",\r\n \"example\": \"\\\"XIV\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ROMAN\",\r\n \"t\": 12,\r\n \"d\": \"Formats a number in Roman numerals.\",\r\n \"a\": \"Formats a number in Roman numerals.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The number to format, between 1 and 3999, inclusive.\",\r\n \"example\": \"499\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"REGEXEXTRACT\",\r\n \"t\": 12,\r\n \"d\": \"Extracts matching substrings according to a regular expression.\",\r\n \"a\": \"Extracts matching substrings with regular expression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The input text.\",\r\n \"example\": \"\\\"Needle in a haystack\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"regular_expression\",\r\n \"detail\": \"The first part of `text` that matches this expression will be returned.\",\r\n \"example\": \"\\\".e{2}dle\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REGEXMATCH\",\r\n \"t\": 12,\r\n \"d\": \"Whether a piece of text matches a regular expression.\",\r\n \"a\": \"Whether a piece of text matches regular expression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text to be tested against the regular expression.\",\r\n \"example\": \"\\\"Spreadsheets\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"regular_expression\",\r\n \"detail\": \"The regular expression to test the text against.\",\r\n \"example\": \"\\\"S.r\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REGEXREPLACE\",\r\n \"t\": 12,\r\n \"d\": \"Replaces part of a text string with a different text string using regular expressions.\",\r\n \"a\": \"Replaces text with regular expressions.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text, a part of which will be replaced.\",\r\n \"example\": \"\\\"Spreadsheets\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"regular_expression\",\r\n \"detail\": \"The regular expression. All matching instances in `text` will be replaced.\",\r\n \"example\": \"\\\"S.*d\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"replacement\",\r\n \"detail\": \"The text which will be inserted into the original text.\",\r\n \"example\": \"\\\"Bed\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"T\",\r\n \"t\": 12,\r\n \"d\": \"Returns string arguments as text, or the empty string if the value is not text.\",\r\n \"a\": \"String arguments as text.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument to be converted to text.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FIXED\",\r\n \"t\": 12,\r\n \"d\": \"Formats a number with a fixed number of decimal places.\",\r\n \"a\": \"Formats number with fixed number of decimal places.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The number to format.\",\r\n \"example\": \"3.141592653\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_places\",\r\n \"detail\": \"The number of decimal places to display in the result.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"suppress_separator\",\r\n \"detail\": \"Whether or not to suppress the thousands separator used in some locales (e.g. `1,000` becomes `1000`). Separators will be present if this value is 0 or omitted, and absent otherwise.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FIND\",\r\n \"t\": 12,\r\n \"d\": \"Returns the position at which a string is first found within text where the capitalization of letters matters. Returns `#VALUE!` if the string is not found.\",\r\n \"a\": \"First position of string found in text, case-sensitive.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to look for within `text_to_search`.\",\r\n \"example\": \"\\\"n\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text to search for the first occurrence of `search_for`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The character within `text_to_search` at which to start the search.\",\r\n \"example\": \"14\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FINDB\",\r\n \"t\": 12,\r\n \"d\": \"Returns the position at which a string is first found within text counting each double-character as 2.\",\r\n \"a\": \"Position at which a string is first found within text (binary).\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to look for within `text_to_search`.\",\r\n \"example\": \"\\\"new\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text to search for the first occurrence of `search_for`.\",\r\n \"example\": \"\\\"new year\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The character within `text_to_search` at which to start the search.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"JOIN\",\r\n \"t\": 12,\r\n \"d\": \"Concatenates the elements of one or more one-dimensional arrays using a specified delimiter.\",\r\n \"a\": \"Concatenates elements of arrays with delimiter.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"delimiter\",\r\n \"detail\": \"The character or string to place between each concatenated value.\",\r\n \"example\": \"\\\" and-a \\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_or_array1\",\r\n \"detail\": \"The value or values to be appended using `delimiter`.\",\r\n \"example\": \"{1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_or_array2\",\r\n \"detail\": \"More values to be appended using `delimiter`.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LEFT\",\r\n \"t\": 12,\r\n \"d\": \"Returns a substring from the beginning of a specified string.\",\r\n \"a\": \"Substring from beginning of specified string.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string from which the left portion will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"number_of_characters\",\r\n \"detail\": \"The number of characters to return from the left side of `string`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RIGHT\",\r\n \"t\": 12,\r\n \"d\": \"Returns a substring from the end of a specified string.\",\r\n \"a\": \"A substring from the end of a specified string.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string from which the right portion will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"number_of_characters\",\r\n \"detail\": \"The number of characters to return from the right side of `string`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MID\",\r\n \"t\": 12,\r\n \"d\": \"Returns a segment of a string.\",\r\n \"a\": \"A segment of a string.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string to extract a segment from.\",\r\n \"example\": \"\\\"get this\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The index from the left of `string` from which to begin extracting. The first character in `string` has the index 1.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"extract_length\",\r\n \"detail\": \"The length of the segment to extract.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LEN\",\r\n \"t\": 12,\r\n \"d\": \"Returns the length of a string.\",\r\n \"a\": \"Length of a string.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string whose length will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LENB\",\r\n \"t\": 12,\r\n \"d\": \"Returns the length of a string in bytes.\",\r\n \"a\": \"Length of a string in bytes.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string whose length will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LOWER\",\r\n \"t\": 12,\r\n \"d\": \"Converts a specified string to lowercase.\",\r\n \"a\": \"Converts a specified string to lowercase.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string to convert to lowercase.\",\r\n \"example\": \"\\\"LOREM IPSUM\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"UPPER\",\r\n \"t\": 12,\r\n \"d\": \"Converts a specified string to uppercase.\",\r\n \"a\": \"Converts a specified string to uppercase.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string to convert to uppercase.\",\r\n \"example\": \"\\\"lorem ipsum\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EXACT\",\r\n \"t\": 12,\r\n \"d\": \"Tests whether two strings are identical.\",\r\n \"a\": \"Tests whether two strings are identical.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"string1\",\r\n \"detail\": \"The first string to compare\",\r\n \"example\": \"A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"string2\",\r\n \"detail\": \"The second string to compare\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REPLACE\",\r\n \"t\": 12,\r\n \"d\": \"Replaces part of a text string with a different text string.\",\r\n \"a\": \"Replaces part of a text string with different text.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text, a part of which will be replaced.\",\r\n \"example\": \"\\\"Spreadsheets\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"position\",\r\n \"detail\": \"The position where the replacement will begin (starting from 1).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"length\",\r\n \"detail\": \"The number of characters in the text to be replaced.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"new_text\",\r\n \"detail\": \"The text which will be inserted into the original text.\",\r\n \"example\": \"\\\"Bed\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REPT\",\r\n \"t\": 12,\r\n \"d\": \"Returns specified text repeated a number of times.\",\r\n \"a\": \"Specified text repeated a number of times.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"text_to_repeat\",\r\n \"detail\": \"The character or string to repeat.\",\r\n \"example\": \"\\\"ha\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"number_of_repetitions\",\r\n \"detail\": \"The number of times `text_to_repeat` should appear in the value returned.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SEARCH\",\r\n \"t\": 12,\r\n \"d\": \"Returns the position at which a string is first found within text and ignores capitalization of letters. Returns `#VALUE!` if the string is not found.\",\r\n \"a\": \"First position of string found in text, ignoring case.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to look for within `text_to_search`.\",\r\n \"example\": \"\\\"n\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text to search for the first occurrence of `search_for`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The character within `text_to_search` at which to start the search.\",\r\n \"example\": \"14\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUBSTITUTE\",\r\n \"t\": 12,\r\n \"d\": \"Replaces existing text with new text in a string.\",\r\n \"a\": \"Replaces existing text with new text in a string.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text within which to search and replace.\",\r\n \"example\": \"\\\"search for it\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to search for within `text_to_search`.\",\r\n \"example\": \"\\\"search for\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"replace_with\",\r\n \"detail\": \"The string that will replace `search_for`.\",\r\n \"example\": \"\\\"Google\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"occurrence_number\",\r\n \"detail\": \"The instance of `search_for` within `text_to_search` to replace with `replace_with`. By default, all occurrences of `search_for` are replaced; however, if `occurrence_number` is specified, only the indicated instance of `search_for` is replaced.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CLEAN\",\r\n \"t\": 12,\r\n \"d\": \"Returns the text with the non-printable ASCII characters removed.\",\r\n \"a\": \"Removes non-printable characters from a piece of text.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text whose non-printable characters are to be removed.\",\r\n \"example\": \"\\\"AF\\\"&CHAR(31)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TEXT\",\r\n \"t\": 12,\r\n \"d\": \"Converts a number into text according to a specified format.\",\r\n \"a\": \"Formats a number into text.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The number, date, or time to format.\",\r\n \"example\": \"1.23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"format\",\r\n \"detail\": \"The pattern by which to format the number, enclosed in quotation marks.\",\r\n \"example\": \"\\\"$0.00\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TRIM\",\r\n \"t\": 12,\r\n \"d\": \"Removes leading, trailing, and repeated spaces in text.\",\r\n \"a\": \"Removes space characters.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text or reference to a cell containing text to be trimmed.\",\r\n \"example\": \"\\\" lorem ipsum\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"VALUE\",\r\n \"t\": 12,\r\n \"d\": \"Converts a string in any of the date, time or number formats that Google Sheets understands into a number.\",\r\n \"a\": \"Converts a date/time/number string into a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string containing the value to be converted.\",\r\n \"example\": \"\\\"123\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PROPER\",\r\n \"t\": 12,\r\n \"d\": \"Capitalizes each word in a specified string.\",\r\n \"a\": \"Capitalizes each word in a specified string.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text_to_capitalize\",\r\n \"detail\": \"The text which will be returned with the first letter of each word in uppercase and all other letters in lowercase.\",\r\n \"example\": \"\\\"united states\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CONVERT\",\r\n \"t\": 13,\r\n \"d\": \"Converts a numeric value to a different unit of measure.\",\r\n \"a\": \"Unit conversion for numbers.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The numeric value in `start_unit` to convert to `end_unit`.\",\r\n \"example\": \"5.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"start_unit\",\r\n \"detail\": \"The starting unit, the unit currently assigned to `value`.\",\r\n \"example\": \"\\\"g\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_unit\",\r\n \"detail\": \"The unit of measure into which to convert the argument, `value`.\",\r\n \"example\": \"\\\"kg\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SUMX2MY2\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the differences of the squares of values in two arrays.\",\r\n \"a\": \"Sum of the differences of squares.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"array_x\",\r\n \"detail\": \"The array or range of values whose squares will be reduced by the squares of corresponding entries in `array_y` and added together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array_y\",\r\n \"detail\": \"The array or range of values whose squares will be subtracted from the squares of corresponding entries in `array_x` and added together.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMX2PY2\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the sums of the squares of values in two arrays.\",\r\n \"a\": \"Sum of the sums of squares.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"array_x\",\r\n \"detail\": \"The array or range of values whose squares will be added to the squares of corresponding entries in `array_y` and added together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array_y\",\r\n \"detail\": \"The array or range of values whose squares will be added to the squares of corresponding entries in `array_x` and added together.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMXMY2\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the squares of differences of values in two arrays.\",\r\n \"a\": \"Sum of the squares of differences.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"array_x\",\r\n \"detail\": \"The array or range of values that will be reduced by corresponding entries in `array_y`, squared, and added together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array_y\",\r\n \"detail\": \"The array or range of values that will be subtracted from corresponding entries in `array_x`, the result squared, and all such results added together.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TRANSPOSE\",\r\n \"t\": 14,\r\n \"d\": \"Transposes the rows and columns of an array or range of cells.\",\r\n \"a\": \"Transposes the rows and columns of an array.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"array_or_range\",\r\n \"detail\": \"The array or range whose rows and columns will be swapped.\",\r\n \"example\": \"{1,2}\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"TREND\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about a linear trend, fits an ideal linear trend using the least squares method and/or predicts further values.\",\r\n \"a\": \"Fits points to linear trend derived via least-squares.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal linear trend.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"new_data_x\",\r\n \"detail\": \"The data points to return the `y` values for on the ideal curve fit.\",\r\n \"example\": \"A11:A13\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"b\",\r\n \"detail\": \"Given a general linear form of `y = m*x+b` for a curve fit, calculates `b` if `TRUE` or forces `b` to be `0` and only calculates the `m` values if `FALSE`, i.e. forces the curve fit to pass through the origin.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FREQUENCY\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the frequency distribution of a one-column array into specified classes.\",\r\n \"a\": \"The frequency distribution of array.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the values to be counted.\",\r\n \"example\": \"A2:A40\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"classes\",\r\n \"detail\": \"The array or range containing the set of classes.\",\r\n \"example\": \"B2:B5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GROWTH\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about an exponential growth trend, fits an ideal exponential growth trend and/or predicts further values.\",\r\n \"a\": \"Fits points to exponential growth trend.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal exponential growth curve.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"new_data_x\",\r\n \"detail\": \"The data points to return the `y` values for on the ideal curve fit.\",\r\n \"example\": \"A11:A13\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"b\",\r\n \"detail\": \"Given a general exponential form of `y = b*m^x` for a curve fit, calculates `b` if `TRUE` or forces `b` to be `1` and only calculates the `m` values if `FALSE`.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LINEST\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about a linear trend, calculates various parameters about the ideal linear trend using the least-squares method.\",\r\n \"a\": \"Best-fit linear trend via least-squares.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal linear trend.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"calculate_b\",\r\n \"detail\": \"Given a linear form of `y = m*x+b`, calculates the y-intercept (`b`) if `TRUE`. Otherwise, forces `b` to be `0` and only calculates the `m` values if `FALSE`, i.e. forces the curve fit to pass through the origin.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"verbose\",\r\n \"detail\": \"A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept (default).\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LOGEST\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about an exponential growth curve, calculates various parameters about the best fit ideal exponential growth curve.\",\r\n \"a\": \"Best-fit exponential growth curve.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal exponential growth curve.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"b\",\r\n \"detail\": \"Given a general exponential form of `y = b*m^x` for a curve fit, calculates `b` if `TRUE` or forces `b` to be `1` and only calculates the `m` values if `FALSE`.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"verbose\",\r\n \"detail\": \"A flag specifying whether to return additional regression statistics or only the calculated coefficient and exponents.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"MDETERM\",\r\n \"t\": 14,\r\n \"d\": \"Returns the matrix determinant of a square matrix specified as an array or range.\",\r\n \"a\": \"Matrix determinant of a square matrix.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"square_matrix\",\r\n \"detail\": \"An array or range with an equal number of rows and columns representing a matrix whose determinant will be calculated.\",\r\n \"example\": \"A1:D4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MINVERSE\",\r\n \"t\": 14,\r\n \"d\": \"Returns the multiplicative inverse of a square matrix specified as an array or range.\",\r\n \"a\": \"Multiplicative inverse of square matrix.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"square_matrix\",\r\n \"detail\": \"An array or range with an equal number of rows and columns representing a matrix whose multiplicative inverse will be calculated.\",\r\n \"example\": \"A1:D4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MMULT\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the matrix product of two matrices specified as arrays or ranges.\",\r\n \"a\": \"The matrix product of two matrices.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"matrix1\",\r\n \"detail\": \"The first matrix in the matrix multiplication operation, represented as an array or range.\",\r\n \"example\": \"A1:B3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"matrix2\",\r\n \"detail\": \"The second matrix in the matrix multiplication operation, represented as an array or range.\",\r\n \"example\": \"C1:F2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMPRODUCT\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the products of corresponding entries in two equal-sized arrays or ranges.\",\r\n \"a\": \"Sum of products of elements in two arrays.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"array1\",\r\n \"detail\": \"The first array or range whose entries will be multiplied with corresponding entries in the second such array or range.\",\r\n \"example\": \"A2:C5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array2\",\r\n \"detail\": \"The second array or range whose entries will be multiplied with corresponding entries in the first such array or range.\",\r\n \"example\": \"D2:F5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISFORMULA\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is a formula.\",\r\n \"a\": \"Whether a value is a formula.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"cell\",\r\n \"detail\": \"The cell to be verified as containing a formula.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"CELL\",\r\n \"t\": 15,\r\n \"d\": \"Returns the requested information about the specified cell.\",\r\n \"a\": \"Gets information about a cell.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"info_type\",\r\n \"detail\": \"The type of information requested (see article for available types)\",\r\n \"example\": \"\\\"type\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"reference\",\r\n \"detail\": \"The reference to the cell.\",\r\n \"example\": \"C2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"NA\",\r\n \"t\": 15,\r\n \"d\": \"Returns the \\\"value not available\\\" error, `#N/A`.\",\r\n \"a\": \"The `#N/A` error.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"ERROR_TYPE\",\r\n \"t\": 15,\r\n \"d\": \"Returns a number corresponding to the error value in a different cell.\",\r\n \"a\": \"Error value of cell (as number).\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"reference\",\r\n \"detail\": \"The cell to find the error number for although you can also provide the error value directly.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISBLANK\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether the referenced cell is empty.\",\r\n \"a\": \"Whether the referenced cell is empty.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Reference to the cell that will be checked for emptiness.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"ISERR\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is an error other than `#N/A`.\",\r\n \"a\": \"Whether a value is an error other than `#n/a`.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as an error type other than `#N/A`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISERROR\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is an error.\",\r\n \"a\": \"Whether a value is an error.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as an error type.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISLOGICAL\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is `TRUE` or `FALSE`.\",\r\n \"a\": \"Whether a value is `true` or `false`.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as a logical `TRUE` or `FALSE`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISNA\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is the error `#N/A`.\",\r\n \"a\": \"Whether a value is the error `#n/a`.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be compared with the error value `#N/A`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISNONTEXT\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is non-textual.\",\r\n \"a\": \"Whether a value is non-textual.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be checked.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISNUMBER\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is a number.\",\r\n \"a\": \"Whether a value is a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as a number.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISREF\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is a valid cell reference.\",\r\n \"a\": \"Whether a value is a valid cell reference.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as a cell reference.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"ISTEXT\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is text.\",\r\n \"a\": \"Whether a value is text.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as text.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TYPE\",\r\n \"t\": 15,\r\n \"d\": \"Returns a number associated with the type of data passed into the function.\",\r\n \"a\": \"Get the type of a value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose type is to be determined.\",\r\n \"example\": \"C4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"N\",\r\n \"t\": 15,\r\n \"d\": \"Returns the argument provided as a number. Text is converted to 0 and errors are returned as-is.\",\r\n \"a\": \"Argument provided as a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument to be converted to a number.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TO_DATE\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided number to a date.\",\r\n \"a\": \"Converts a provided number to a date.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a date.\",\r\n \"example\": \"25405\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TO_PURE_NUMBER\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided date/time, percentage, currency or other formatted numeric value to a pure number without formatting.\",\r\n \"a\": \"Converts any numeric value to a pure number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a pure number.\",\r\n \"example\": \"50%\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TO_TEXT\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided numeric value to a text value.\",\r\n \"a\": \"Converts a provided numeric value to a text value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to text.\",\r\n \"example\": \"24\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TO_DOLLARS\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided number to a dollar value.\",\r\n \"a\": \"Converts a provided number to a dollar value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a dollar value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TO_PERCENT\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided number to a percentage.\",\r\n \"a\": \"Converts a provided number to a percentage.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a percentage.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DGET\",\r\n \"t\": 17,\r\n \"d\": \"Returns a single value from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Single value from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DMAX\",\r\n \"t\": 17,\r\n \"d\": \"Returns the maximum value selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Maximum of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DMIN\",\r\n \"t\": 17,\r\n \"d\": \"Returns the minimum value selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Minimum of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DAVERAGE\",\r\n \"t\": 17,\r\n \"d\": \"Returns the average of a set of values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Average of a set of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DCOUNT\",\r\n \"t\": 17,\r\n \"d\": \"Counts numeric values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Counts values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DCOUNTA\",\r\n \"t\": 17,\r\n \"d\": \"Counts values, including text, selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Counts values and text from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DPRODUCT\",\r\n \"t\": 17,\r\n \"d\": \"Returns the product of values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Product of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DSTDEV\",\r\n \"t\": 17,\r\n \"d\": \"Returns the standard deviation of a population sample selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Standard deviation of population sample from table.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DSTDEVP\",\r\n \"t\": 17,\r\n \"d\": \"Returns the standard deviation of an entire population selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Standard deviation of entire population from table.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DSUM\",\r\n \"t\": 17,\r\n \"d\": \"Returns the sum of values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Sum of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DVAR\",\r\n \"t\": 17,\r\n \"d\": \"Returns the variance of a population sample selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Variance of population sample from table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DVARP\",\r\n \"t\": 17,\r\n \"d\": \"Returns the variance of an entire population selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Variance of a population from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"AGE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the age based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get age based on ID number.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"A1\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Deadline\",\r\n \"example\": \"\\\"2017-10-01\\\"\",\r\n \"detail\": \"The deadline or range of age calculation. The default is the current day.\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedatetime\"\r\n }]\r\n }, {\r\n \"n\": \"SEX_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate gender based on Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get gender based on ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BIRTHDAY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the birthday based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the birthday based on the ID number.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Birthday format\",\r\n \"example\": \"0\",\r\n \"detail\": \"Date type, default:0:[1900/01/01], 1:[1900-01-01], 2:[1900年1月1日]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PROVINCE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the province of birthplace based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the province of birthplace based on the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CITY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the city of birthplace based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the city of birthplace based on the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"STAR_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the constellation based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the constellation based on the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ANIMAL_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the zodiac (rat, ox, tiger, rabbit...) based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the zodiac according to the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISIDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Verify that the format of the ID card is correct. Support 15 or 18\",\r\n \"a\": \"Verify the correctness of the ID card format.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DM_TEXT_CUTWORD\",\r\n \"t\": \"4\",\r\n \"d\": \"Text segmentation. Split a series of words into a series of individual words\",\r\n \"a\": \"Chinese text segmentation.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"Text\",\r\n \"example\": \"\\\"I came to Beijing Tsinghua University\\\"\",\r\n \"detail\": \"Any text that needs word segmentation.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Word segmentation mode\",\r\n \"example\": \"0\",\r\n \"detail\": \"The default is 0[precision mode], 1[full mode], 2[search engine mode].\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DM_TEXT_TFIDF\",\r\n \"t\": \"4\",\r\n \"d\": \"Use tf-idf algorithm for keyword extraction. Identify keywords from a series of text\",\r\n \"a\": \"tf-idf keyword recognition.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Text\",\r\n \"example\": \"\\\"I came to Beijing Tsinghua University\\\"\",\r\n \"detail\": \"Any text that needs word segmentation.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Number of keywords\",\r\n \"example\": \"20\",\r\n \"detail\": \"The number of keywords returned by the algorithm, the default is 20\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"Corpus\",\r\n \"example\": \"1\",\r\n \"detail\": \"Select a corpus in a specific field, the default is 0[General], 1[Finance], 2[Medical]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DM_TEXT_TEXTRANK\",\r\n \"t\": \"4\",\r\n \"d\": \"Use TextRank algorithm to extract keywords. Identify keywords from a series of text\",\r\n \"a\": \"TextRank keyword recognition.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Text\",\r\n \"example\": \"\\\"I came to Beijing Tsinghua University\\\"\",\r\n \"detail\": \"Any text that needs word segmentation.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Number of keywords\",\r\n \"example\": \"20\",\r\n \"detail\": \"The number of keywords returned by the algorithm, the default is 20\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"Corpus\",\r\n \"example\": \"1\",\r\n \"detail\": \"Select a corpus in a specific field, the default is 0[General], 1[Finance], 2[Medical]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_CLOSE\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the corresponding stock closing price of A shares.\",\r\n \"a\": \"Returns the closing price of stock.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_OPEN\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the opening price of stock.\",\r\n \"a\": \"Return the opening price of a shares.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_MAX\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the highest price of stock.\",\r\n \"a\": \"Return the highest price of stock.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_MIN\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the lowest price of stock.\",\r\n \"a\": \"Returns the lowest price of stock.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_VOLUMN\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the corresponding stock trading volume of A shares.\",\r\n \"a\": \"Returns the corresponding stock trading volume of A shares.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_AMOUNT\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the corresponding stock turnover of A shares.\",\r\n \"a\": \"Returns the corresponding stock turnover of A shares.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISDATE\",\r\n \"t\": \"6\",\r\n \"d\": \"Returns whether a value is a date.\",\r\n \"a\": \"Whether a value is a date.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"example\": \"\\\"1990-01-01\\\"\",\r\n \"detail\": \"The value to be verified as a date.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LINESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell to describe the continuous trend of data\",\r\n \"a\": \"Generate sparklines line chart\",\r\n \"m\": [1, 8],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line color\",\r\n \"example\": \"#2ec7c9\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line thickness\",\r\n \"example\": \"1\",\r\n \"detail\": \"Line thickness of the line graph, the default is 1px\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line\",\r\n \"example\": \"avg\",\r\n \"detail\": \"A horizontal line, which can be min, max, avg, median, range or custom value, default 0 none\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line color\",\r\n \"example\": \"#000\",\r\n \"detail\": \"Color setting of auxiliary line, same as line color configuration, default #000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Maximum mark\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"Identifies the maximum value of the line graph, the same line color configuration, default 0 does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Minimum mark\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"Identify the minimum value of the line graph, the same line color configuration, default 0 does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Mark size\",\r\n \"example\": \"1.5\",\r\n \"detail\": \"The maximum and minimum mark size settings, the default is 1.5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AREASPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell area chart, generally used to describe the continuous cumulative value trend of the data\",\r\n \"a\": \"Generate sparklines area chart\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line color\",\r\n \"example\": \"#2ec7c9\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Fill color\",\r\n \"example\": \"#CCF3F4\",\r\n \"detail\": \"Form an area chart, the same line color configuration, default 0 does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line thickness\",\r\n \"example\": \"1\",\r\n \"detail\": \"Line thickness of the line graph, the default is 1px\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line\",\r\n \"example\": \"avg\",\r\n \"detail\": \"A horizontal line, which can be min, max, avg, median, range or custom value, default 0 none\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line color\",\r\n \"example\": \"#000\",\r\n \"detail\": \"Color setting of auxiliary line, same as line color configuration, default #000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the vertical histogram of cells, generally used to describe the size of discrete data\",\r\n \"a\": \"Generate sparklines vertical histogram\",\r\n \"m\": [1, 6],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Negative bar color\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"Negative bar color setting, representing the color of negative value, same as the bar color configuration, default #97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the bar chart, used to standardize the length of the bar chart, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can set the color of each bar individually, multiple settings can be set, and two formats are supported: 1 color such as #000, which means that the color of the first bar is black; 2 value range: color, such as -2:# 000 indicates that the bar with a value of -2 is black, 0:5:#000 indicates that the bar with a value of 0-5 is black, and the default is empty\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"STACKCOLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines, a cumulative vertical histogram embedded in a cell, generally used to describe the numerical size of multiple dimensions of discrete data\",\r\n \"a\": \"Generate sparklines cumulative vertical histogram\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Stack by column\",\r\n \"example\": \"1\",\r\n \"detail\": \"If you need to stack by row, set this item to false or 0, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the cumulative bar, used to regulate the length of the bar, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can individually set the bar color of each dimension, which can be set to the range of A1:A10, etc. The default is #2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell, generally used to describe the size of discrete data\",\r\n \"a\": \"Generate sparklines horizontal bar graph\",\r\n \"m\": [1, 6],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Negative bar color\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"Negative bar color setting, representing the color of negative value, same as the bar color configuration, default #97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the bar chart, used to standardize the length of the bar chart, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can set the color of each bar individually, multiple settings can be set, and two formats are supported: 1 color such as #000, which means that the color of the first bar is black; 2 value range: color, such as -2:# 000 indicates that the bar with a value of -2 is black, 0:5:#000 indicates that the bar with a value of 0-5 is black, and the default is empty\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"STACKBARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines, a cumulative horizontal bar graph embedded in a cell, which is generally used to describe the numerical size of multiple dimensions of discrete data\",\r\n \"a\": \"Generate sparklines cumulative horizontal bar graph\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Stack by column\",\r\n \"example\": \"1\",\r\n \"detail\": \"If you need to stack by row, set this item to false or 0, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the cumulative bar, used to regulate the length of the bar, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can individually set the bar color of each dimension, which can be set to the range of A1:A10, etc. The default is #2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DISCRETESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell, generally used to describe the trend of discrete data\",\r\n \"a\": \"Generate sparklines discrete graph\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Segmentation threshold\",\r\n \"example\": \"1\",\r\n \"detail\": \"Discrete graph column color distinction, for example: if the value is 0, blue is greater than 0, red is less than 0, and the default is 0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Above threshold color\",\r\n \"example\": \"#2ec7c9\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Below threshold color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The color setting of the bar below the threshold, the same as the color above the threshold, default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TRISTATESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines, a three-state graph embedded in the cell, which is generally used to describe the trend of three situations, such as winning, losing, or drawing.\",\r\n \"a\": \"Generate sparklines three-state graph\",\r\n \"m\": [1, 6],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Negative bar color\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"Negative bar color setting, representing the color of negative value, same as the bar color configuration, default #97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Zero value bar color\",\r\n \"example\": \"#999\",\r\n \"detail\": \"Zero value bar color setting, representing 0 value color, the same color configuration of the bar, default #999\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can set the color of each bar individually, multiple settings can be set, and two formats are supported: 1 color such as #000, which means that the color of the first bar is black; 2 value range: color, such as -2:# 000 indicates that the bar with a value of -2 is black, 0:5:#000 indicates that the bar with a value of 0-5 is black, and the default is empty\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PIESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines pie chart embedded in the cell, generally used to describe the proportion of data\",\r\n \"a\": \"Generate sparklines pie chart\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Rotation angle\",\r\n \"example\": \"0\",\r\n \"detail\": \"The rotation angle of the pie chart, the default is 0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"border\",\r\n \"example\": \"0\",\r\n \"detail\": \"Pie chart border size, default is none 0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Border color\",\r\n \"example\": \"#000\",\r\n \"detail\": \"The border color of the pie chart, the default is #000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color of the slice can be set in the palette, which can be set to the range of A1:A10, etc. The default is #2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BOXSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell box plot, generally used to describe the statistical distribution of the data set\",\r\n \"a\": \"Generate sparklines box plot\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Outlier ratio\",\r\n \"example\": \"1.5\",\r\n \"detail\": \"The threshold range of outliers, if it is 0 or false, it will not be displayed, the default is 1.5 times\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Target value\",\r\n \"example\": \"10\",\r\n \"detail\": \"The target value setting on the box plot, the default is false and does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Point size\",\r\n \"example\": \"1.5\",\r\n \"detail\": \"The radius of the target point and outlier is set, the default is 1.5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BULLETSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell, generally used to describe the task achievement rate\",\r\n \"a\": \"Generating sparklines bullets\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"Target\",\r\n \"example\": \"10\",\r\n \"detail\": \"The numerical value can be calculated effectively for the achieved target value, such as A1, 100, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"achieved\",\r\n \"example\": \"8\",\r\n \"detail\": \"Only when the value is completed can the value be calculated effectively, such as A1, 100, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Contrast\",\r\n \"example\": \"12\",\r\n \"detail\": \"Comparative values, such as excess, minimum, and bottom line for awards, can be effectively calculated, such as A1, 100, etc. You can set up to 9 comparison values\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COMPOSESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Support multiple types of pictures in the same cell, each parameter represents a sparklines diagram\",\r\n \"a\": \"Combine sparklines graphs into one cell\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"config\",\r\n \"example\": \"PIESPLINES(A1:A20)\",\r\n \"detail\": \"Sparklines chart settings, such as A1:A20, a completed pie chart, line chart settings, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SORT\",\r\n \"t\": \"14\",\r\n \"d\": \"Sorts the rows of a given array or range by the values in one or more columns.\",\r\n \"a\": \"Sorts rows of range by specified column.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The data to be sorted.\",\r\n \"example\": \"A2:A17\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"sort_column\",\r\n \"detail\": \"The index of the column in `range` or a range outside of `range` containing the values by which to sort.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"is_ascending\",\r\n \"detail\": \"`TRUE` or `FALSE` indicating whether to sort `sort_column` in ascending order. `FALSE` sorts in descending order.\",\r\n \"example\": \"-1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"sort_column2\",\r\n \"detail\": \"Additional columns.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FILTER\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns a filtered version of the source range, returning only rows or columns which meet the specified conditions.\",\r\n \"a\": \"Filters a range based off provided conditions.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The data to be filtered.\",\r\n \"example\": \"A5:D20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"condition1\",\r\n \"detail\": \"A column or row containing true or false values corresponding to the first column or row of `range`, or an array formula evaluating to true or false.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"condition2\",\r\n \"detail\": \"Additional rows or columns containing boolean values `TRUE` or `FALSE` indicating whether the corresponding row or column in `range` should pass through `FILTER`. Can also contain array formula expressions which evaluate to such rows or columns. All conditions must be of the same type (row or column). Mixing row conditions and column conditions is not permitted.\",\r\n \"example\": \"\\\"\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"UNIQUE\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns unique rows in the provided source range, discarding duplicates. Rows are returned in the order in which they first appear in the source range.\",\r\n \"a\": \"Unique rows in the provided source range.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The data to filter by unique entries.\",\r\n \"example\": \"A2:B26\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"by_col\",\r\n \"detail\": \"[Option] - Logical value, indicating how to compare; by row = FALSE() or omitted; by column = TRUE().\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"occurs_once\",\r\n \"detail\": \"[Option] - Logical value, only one occurrence in the unique value is returned = TRUE(); including all unique values = FALSE() or omitted.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANDARRAY\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns a grid of random numbers between 0 inclusive and 1 exclusive. The grid size will match the provided rows and columns arguments. If neither rows nor columns are provided, then the grid will be size 1 x 1.\",\r\n \"a\": \"Returns a grid of random numbers.\",\r\n \"m\": [0, 2],\r\n \"p\": [{\r\n \"name\": \"rows\",\r\n \"detail\": \"The number of rows to populate with a random number.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"columns\",\r\n \"detail\": \"The number of columns to populate with a random number.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SEQUENCE\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns a grid of sequential numbers starting at a specified start value and increasing by a specified step size. By default, the sequence starts at and increases by 1.\",\r\n \"a\": \"Returns a grid of sequential numbers.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"rows\",\r\n \"detail\": \"The number of rows in the function's resulting grid.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"columns\",\r\n \"detail\": \"The number of columns in the function's resulting grid. If omitted, the result grid will have 1 column.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"start\",\r\n \"detail\": \"The number, at which to start the sequence. If omitted, the sequence will start at 1.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"step\",\r\n \"detail\": \"The amount each value in the sequence will differ by. If omitted, each value will differ by 1.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n {\r\n \"n\": \"EVALUATE\",\r\n \"t\": \"3\",\r\n \"d\": \"Evaluate a formula or expression expressed in words and return the result\",\r\n \"a\": \"Evaluate according to literal formula or expression.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"expression\",\r\n \"example\": '\"A1+5*2^2\"',\r\n \"detail\": \"Formula or expression\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n ],\r\n toolbar: {\r\n undo: 'Undo',\r\n redo: 'Redo',\r\n paintFormat: 'Paint format',\r\n currencyFormat: 'Format as currency',\r\n percentageFormat: 'Format as percent',\r\n numberDecrease: 'Decrease decimal places',\r\n numberIncrease: 'Increase decimal places',\r\n moreFormats:'More formats',\r\n font: 'Font',\r\n fontSize: 'Font size',\r\n bold: 'Bold (Ctrl+B)',\r\n italic : 'Italic (Ctrl+I)',\r\n strikethrough: 'Strikethrough (Alt+Shift+5)',\r\n underline: 'Underline',\r\n textColor: 'Text color',\r\n chooseColor: 'choose color',\r\n resetColor: 'Reset',\r\n customColor: 'CUSTOM',\r\n alternatingColors: 'Alternating colors',\r\n confirmColor: 'OK',\r\n cancelColor: 'Cancel',\r\n collapse: 'Collapse',\r\n fillColor: 'Fill color',\r\n border: 'Border',\r\n borderStyle: 'Border style',\r\n mergeCell: 'Merge cells',\r\n chooseMergeType: 'Choose merge type',\r\n horizontalAlign: 'Horizontal align',\r\n verticalAlign: 'Vertical align',\r\n alignment: 'Alignment',\r\n textWrap: 'Text wrap',\r\n textWrapMode: 'Text wrap mode',\r\n textRotate: 'Text rotate',\r\n textRotateMode: 'Text rotate mode',\r\n freezeTopRow: 'Freeze top row',\r\n sortAndFilter: 'Sort and filter',\r\n findAndReplace: 'Find and replace',\r\n sum: 'SUM',\r\n autoSum: 'Auto SUM',\r\n moreFunction: 'More functions',\r\n conditionalFormat: 'Conditional format',\r\n postil: 'Comment',\r\n pivotTable: 'Pivot Table',\r\n chart: 'Chart',\r\n screenshot: 'Screenshot',\r\n splitColumn: 'Split text',\r\n insertImage: 'Insert image',\r\n insertLink: 'Insert link',\r\n dataVerification: 'Data verification',\r\n protection:\"Protect the sheet\",\r\n\r\n clearText:\"Clear color\",\r\n noColorSelectedText:\"No color is selected\",\r\n\r\n toolMore:\"More\",\r\n toolLess:\"Less\",\r\n toolClose:\"Close\",\r\n toolMoreTip:\"More features\",\r\n moreOptions:\"More options\",\r\n\r\n cellFormat:\"Cell format config\",\r\n print:\"Print\",\r\n },\r\n alternatingColors:{\r\n applyRange: 'Apply to range',\r\n selectRange: 'Select a data range',\r\n header: 'Header',\r\n footer: 'Footer',\r\n\r\n errorInfo:\"Cannot perform this operation on multiple selection areas, please select a single area and try again\",\r\n textTitle:\"Format style\",\r\n custom:\"CUSTOM\",\r\n close:\"close\",\r\n selectionTextColor:\"Click to select text color\",\r\n selectionCellColor:\"Click to select cell color\",\r\n removeColor:\"Remove alternating colors\",\r\n colorShow:\"color\",\r\n currentColor:\"Current\",\r\n\r\n tipSelectRange:\"Please select the range of alternating colors\",\r\n errorNoRange:\"No range is selected\",\r\n errorExistColors:\"Alternating colors already exist and cannot be edited\",\r\n },\r\n button: {\r\n confirm: 'OK',\r\n cancel: 'Cancel',\r\n close:\"Close\",\r\n update:\"Update\",\r\n delete:\"Delete\",\r\n insert:\"Insert\",\r\n },\r\n paint:{\r\n start: 'Paint format start',\r\n end: 'ESC',\r\n\r\n tipSelectRange:\"Please select the range to be copied\",\r\n tipNotMulti:\"Cannot perform this operation on multiple selection ranges\",\r\n },\r\n format:{\r\n moreCurrency: 'More currency formats',\r\n moreDateTime: 'More date and time formats',\r\n moreNumber: 'More number formats',\r\n\r\n titleCurrency: 'Currency formats',\r\n decimalPlaces: 'Decimal places',\r\n titleDateTime: 'Date and time formats',\r\n titleNumber: 'Number formats'\r\n },\r\n info:{\r\n detailUpdate: 'New opened',\r\n detailSave: 'Local cache restored',\r\n row: '',\r\n column: '',\r\n loading:\"Loading\",\r\n\r\n copy:\"Copy\",\r\n return:\"Exit\",\r\n rename:\"Rename\",\r\n tips:\"WorkBook rename\",\r\n noName:\"Untitled spreadsheet\",\r\n wait:\"waiting for update\",\r\n\r\n add:\"Add\",\r\n addLast:\"more rows at bottom\",\r\n backTop:\"Back to the top\",\r\n pageInfo:'Total ${total},${totalPage} page,current ${currentPage}',\r\n nextPage:\"Next\",\r\n\r\n tipInputNumber:\"Please enter the number\",\r\n tipInputNumberLimit:\"The increase range is limited to 1-100\",\r\n\r\n tipRowHeightLimit:\"Row height must be between 0 ~ 545\",\r\n tipColumnWidthLimit:\"The column width must be between 0 ~ 2038\",\r\n pageInfoFull:'Total ${total},${totalPage} page,All data displayed',\r\n },\r\n currencyDetail:{\r\n RMB:'RMB',\r\n USdollar:'US dollar',\r\n EUR:'EUR',\r\n GBP:'GBP',\r\n HK:'HK',\r\n JPY:'JPY',\r\n AlbanianLek:'Albanian Lek',\r\n AlgerianDinar:'Algerian Dinar',\r\n Afghani:'Afghani',\r\n ArgentinePeso:'Argentine Peso',\r\n UnitedArabEmiratesDirham:'United Arab Emirates Dirham',\r\n ArubanFlorin:'Aruban Florin',\r\n OmaniRial:'Omani Rial',\r\n Azerbaijanimanat:'Azerbaijani manat',\r\n EgyptianPound:'Egyptian Pound',\r\n EthiopianBirr:'Ethiopian Birr',\r\n AngolaKwanza:'Angola Kwanza',\r\n AustralianDollar:'Australian Dollar',\r\n Patacas:'Patacas',\r\n BarbadosDollar:'Barbados Dollar',\r\n PapuaNewGuineaKina:'Papua New Guinea Kina',\r\n BahamianDollar:'Bahamian Dollar',\r\n PakistanRupee:'Pakistan Rupee',\r\n ParaguayanGuarani:'Paraguayan Guarani',\r\n BahrainiDinar:'Bahraini Dinar',\r\n PanamanianBalboa:'Panamanian Balboa',\r\n Brazilianreal:'Brazilian real',\r\n Belarusianruble:'Belarusian ruble',\r\n BermudianDollar:'Bermudian Dollar',\r\n BulgarianLev:'Bulgarian Lev',\r\n IcelandKrona:'Iceland Krona',\r\n BosniaHerzegovinaConvertibleMark:'Bosnia-Herzegovina Convertible Mark',\r\n PolishZloty:'Polish Zloty',\r\n Boliviano:'Boliviano',\r\n BelizeDollar:'Belize Dollar',\r\n BotswanaPula:'Botswana Pula',\r\n NotDannuzhamu:'Not Dannuzhamu',\r\n BurundiFranc:'Burundi Franc',\r\n NorthKoreanWon:'North Korean Won',\r\n DanishKrone:'Danish Krone',\r\n EastCaribbeanDollar:'East Caribbean Dollar',\r\n DominicaPeso:'Dominica Peso',\r\n RussianRuble:'Russian Ruble',\r\n EritreanNakfa:'Eritrean Nakfa',\r\n CFAfranc:'CFA franc',\r\n PhilippinePeso:'Philippine Peso',\r\n FijiDollar:'Fiji Dollar',\r\n CapeVerdeEscudo:'Cape Verde Escudo',\r\n FalklandIslandsPound:'Falkland Islands Pound',\r\n GambianDalasi:'Gambian Dalasi',\r\n Congolesefranc:'Congolese franc',\r\n ColombianPeso:'Colombian Peso',\r\n CostaRicanColon:'Costa Rican Colon',\r\n CubanPeso:'Cuban Peso',\r\n Cubanconvertiblepeso:'Cuban convertible peso',\r\n GuyanaDollar:'Guyana Dollar',\r\n KazakhstanTenge:'Kazakhstan Tenge',\r\n Haitiangourde:'Haitian gourde',\r\n won:'won',\r\n NetherlandsAntillesGuilder:'Netherlands Antilles Guilder',\r\n Honduraslempiras:'Honduras lempiras',\r\n DjiboutiFranc:'Djibouti Franc',\r\n KyrgyzstanSom:'Kyrgyzstan Som',\r\n GuineaFranc:'Guinea Franc',\r\n CanadianDollar:'Canadian Dollar',\r\n GhanaianCedi:'Ghanaian Cedi',\r\n Cambodianriel:'Cambodian riel',\r\n CzechKoruna:'Czech Koruna',\r\n ZimbabweDollar:'Zimbabwe Dollar',\r\n QatariRiyal:'Qatari Riyal',\r\n CaymanIslandsDollar:'Cayman Islands Dollar',\r\n Comorianfranc:'Comorian franc',\r\n KuwaitiDinar:'Kuwaiti Dinar',\r\n CroatianKuna:'Croatian Kuna',\r\n KenyanShilling:'Kenyan Shilling',\r\n LesothoLoti:'Lesotho Loti',\r\n LaoKip:'Lao Kip',\r\n LebanesePound:'Lebanese Pound',\r\n Lithuanianlitas:'Lithuanian litas',\r\n LibyanDinar:'Libyan Dinar',\r\n LiberianDollar:'Liberian Dollar',\r\n RwandaFranc:'Rwanda Franc',\r\n RomanianLeu:'Romanian Leu',\r\n MalagasyAriary:'Malagasy Ariary',\r\n MaldivianRufiyaa:'Maldivian Rufiyaa',\r\n MalawiKwacha:'Malawi Kwacha',\r\n MalaysianRinggit:'Malaysian Ringgit',\r\n MacedoniawearingDinar:'Macedonia wearing Dinar',\r\n MauritiusRupee:'Mauritius Rupee',\r\n MauritanianOuguiya:'Mauritanian Ouguiya',\r\n MongolianTugrik:'Mongolian Tugrik',\r\n BangladeshiTaka:'Bangladeshi Taka',\r\n PeruvianNuevoSol:'Peruvian Nuevo Sol',\r\n MyanmarKyat:'Myanmar Kyat',\r\n MoldovanLeu:'Moldovan Leu',\r\n MoroccanDirham:'Moroccan Dirham',\r\n MozambiqueMetical:'Mozambique Metical',\r\n MexicanPeso:'Mexican Peso',\r\n NamibianDollar:'Namibian Dollar',\r\n SouthAfricanRand:'South African Rand',\r\n SouthSudanesePound:'South Sudanese Pound',\r\n NicaraguaCordoba:'Nicaragua Cordoba',\r\n NepaleseRupee:'Nepalese Rupee',\r\n NigerianNaira:'Nigerian Naira',\r\n NorwegianKrone:'Norwegian Krone',\r\n GeorgianLari:'Georgian Lari',\r\n RMBOffshore:'RMB (Offshore)',\r\n SwedishKrona:'Swedish Krona',\r\n SwissFranc:'Swiss Franc',\r\n SerbianDinar:'Serbian Dinar',\r\n SierraLeone:'Sierra Leone',\r\n SeychellesRupee:'Seychelles Rupee',\r\n SaudiRiyal:'Saudi Riyal',\r\n SaoTomeDobra:'Sao Tome Dobra',\r\n SaintHelenapound:'Saint Helena pound',\r\n SriLankaRupee:'Sri Lanka Rupee',\r\n SwazilandLilangeni:'Swaziland Lilangeni',\r\n SudanesePound:'Sudanese Pound',\r\n Surinamesedollar:'Surinamese dollar',\r\n SolomonIslandsDollar:'Solomon Islands Dollar',\r\n SomaliShilling:'Somali Shilling',\r\n TajikistanSomoni:'Tajikistan Somoni',\r\n PacificFranc:'Pacific Franc',\r\n ThaiBaht:'Thai Baht',\r\n TanzanianShilling:'Tanzanian Shilling',\r\n TonganPaanga:\"Tongan Pa'anga\",\r\n TrinidadandTobagoDollar:'Trinidad and Tobago Dollar',\r\n TunisianDinar:'Tunisian Dinar',\r\n TurkishLira:'Turkish Lira',\r\n VanuatuVatu:'Vanuatu Vatu',\r\n GuatemalanQuetzal:'Guatemalan Quetzal',\r\n CommissionBolivar:'Commission Bolivar',\r\n BruneiDollar:'Brunei Dollar',\r\n UgandanShilling:'Ugandan Shilling',\r\n UkrainianHryvnia:'Ukrainian Hryvnia',\r\n UruguayanPeso:'Uruguayan Peso',\r\n Uzbekistansom:'Uzbekistan som',\r\n WesternSamoaTala:'Western Samoa Tala',\r\n SingaporeDollar:'Singapore Dollar',\r\n NT:'NT',\r\n NewZealandDollar:'New Zealand Dollar',\r\n HungarianForint:'Hungarian Forint',\r\n SyrianPound:'Syrian Pound',\r\n JamaicanDollar:'Jamaican Dollar',\r\n ArmenianDram:'Armenian Dram',\r\n YemeniRial:'Yemeni Rial',\r\n IraqiDinar:'Iraqi Dinar',\r\n IranianRial:'Iranian Rial',\r\n NewIsraeliShekel:'New Israeli Shekel',\r\n IndianRupee:'Indian Rupee',\r\n IndonesianRupiah:'Indonesian Rupiah',\r\n JordanianDinar:'Jordanian Dinar',\r\n VND:'VND',\r\n ZambianKwacha:'Zambian Kwacha',\r\n GibraltarPound:'Gibraltar Pound',\r\n ChileanPeso:'Chilean Peso',\r\n CFAFrancBEAC:'CFA Franc BEAC'\r\n },\r\n defaultFmt:[\r\n { \"text\": 'Automatic', \"value\": \"General\", \"example\": \"\" },\r\n { \"text\": 'Plain text', \"value\": \"@\", \"example\": \"\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": 'Number', \"value\": \"##0.00\", \"example\": \"1000.12\" },\r\n { \"text\": 'Percent', \"value\": \"#0.00%\", \"example\": \"12.21%\" },\r\n { \"text\": 'Scientific', \"value\": \"0.00E+00\", \"example\": \"1.01E+5\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": 'Accounting', \"value\": \"¥(0.00)\", \"example\": \"¥(1200.09)\" },\r\n\r\n\r\n { \"text\": 'Currency', \"value\": \"¥0.00\", \"example\": \"¥1200.09\" },\r\n\r\n\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": 'Date', \"value\": \"yyyy-MM-dd\", \"example\": \"2017-11-29\" },\r\n { \"text\": 'Time', \"value\": \"hh:mm AM/PM\", \"example\": \"3:00 PM\" },\r\n { \"text\": 'Time 24H', \"value\": \"hh:mm\", \"example\": \"15:00\" },\r\n { \"text\": 'Date time', \"value\": \"yyyy-MM-dd hh:mm AM/PM\", \"example\": \"2017-11-29 3:00 PM\" },\r\n { \"text\": 'Date time 24 H', \"value\": \"yyyy-MM-dd hh:mm\", \"example\": \"2017-11-29 15:00\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": 'Custom formats', \"value\": \"fmtOtherSelf\", \"example\": \"more\" }\r\n ],\r\n dateFmtList:[\r\n {\r\n \"name\": \"1930-08-05\",\r\n \"value\": \"yyyy-MM-dd\"\r\n },\r\n {\r\n \"name\": \"1930/8/5\",\r\n \"value\": \"yyyy/MM/dd\"\r\n },\r\n {\r\n \"name\": \"08-05\",\r\n \"value\": \"MM-dd\"\r\n },\r\n {\r\n \"name\": \"8-5\",\r\n \"value\": \"M-d\"\r\n },\r\n {\r\n \"name\": \"13:30:30\",\r\n \"value\": \"h:mm:ss\"\r\n },\r\n {\r\n \"name\": \"13:30\",\r\n \"value\": \"h:mm\"\r\n },\r\n {\r\n \"name\": \"PM 01:30\",\r\n \"value\": 'AM/PM hh:mm'\r\n },\r\n {\r\n \"name\": \"PM 1:30\",\r\n \"value\": 'AM/PM h:mm'\r\n },\r\n {\r\n \"name\": \"PM 1:30:30\",\r\n \"value\": 'AM/PM h:mm:ss'\r\n },\r\n {\r\n \"name\": \"08-05 PM 01:30\",\r\n \"value\": \"MM-dd AM/PM hh:mm\"\r\n }\r\n ],\r\n fontFamily:{\r\n MicrosoftYaHei:\"YaHei\",\r\n },\r\n fontarray: [\"Times New Roman\",\"Arial\",\"Tahoma\",\"Verdana\"],\r\n fontjson: {\"times new roman\":0,\"arial\":1,\"tahoma\":2,\"verdana\":3},\r\n border:{\r\n borderTop:'borderTop',\r\n borderBottom:'borderBottom',\r\n borderLeft:'borderLeft',\r\n borderRight:'borderRight',\r\n borderNone:'borderNone',\r\n borderAll:'borderAll',\r\n borderOutside:'borderOutside',\r\n borderInside:'borderInside',\r\n borderHorizontal:'borderHorizontal',\r\n borderVertical:'borderVertical',\r\n borderColor:'borderColor',\r\n borderSize:'borderSize',\r\n },\r\n merge:{\r\n mergeAll:\"Merge all\",\r\n mergeV:\"Vertically\",\r\n mergeH:\"Horizontally\",\r\n mergeCancel:\"Unmerge\",\r\n overlappingError:\"Cannot merge overlapping areas\",\r\n partiallyError:\"Cannot perform this operation on partially merged cells\",\r\n },\r\n align:{\r\n left:\"left\",\r\n center:\"center\",\r\n right:\"right\",\r\n\r\n top:\"Top\",\r\n middle:\"Middle\",\r\n bottom:\"Bottom\",\r\n },\r\n textWrap:{\r\n \"overflow\":\"Overflow\",\r\n \"wrap\":\"Wrap\",\r\n \"clip\":\"Clip\",\r\n },\r\n rotation:{\r\n \"none\":\"None\",\r\n \"angleup\":\"Tilt Up\",\r\n \"angledown\":\"Tilt Down\",\r\n \"vertical\":\"Stack Vertically\",\r\n \"rotationUp\":\"Rotate Up\",\r\n \"rotationDown\":\"Rotate Down\"\r\n },\r\n freezen:{\r\n default:\"Freeze\",\r\n freezenRow:\"First Row\",\r\n freezenColumn:\"First Column\",\r\n freezenRC:\"Both\",\r\n freezenRowRange:\"Freezen row range\",\r\n freezenColumnRange:\"Freezen column range\",\r\n freezenRCRange:\"Freezen both range\",\r\n freezenCancel:\"Cancel\",\r\n\r\n noSeletionError:\"No Range to be selected\",\r\n },\r\n sort:{\r\n \"asc\":\"Ascending \",\r\n \"desc\":\"Descending \",\r\n \"custom\":\"Custom sort\",\r\n\r\n \"hasTitle\":\"Data has a header row\",\r\n \"sortBy\":\"Sort by\",\r\n \"addOthers\":\"Add another sort column\",\r\n \"close\":\"close\",\r\n \"confirm\":\"sort\",\r\n\r\n \"columnOperation\":\"Column\",\r\n \"secondaryTitle\":\"then by\",\r\n\r\n \"sortTitle\":\"Sort range\",\r\n\r\n \"sortRangeTitle\":\"Sort range from\",\r\n \"sortRangeTitleTo\":\"to\",\r\n\r\n\r\n \"noRangeError\":\"Cannot perform this operation on multiple selection areas, please select a single range and try again\",\r\n \"mergeError\":\"There are merged cells in the selection, this operation cannot be performed!\",\r\n\r\n },\r\n filter:{\r\n filter:\"create filter\",\r\n\r\n sortByAsc:\"Sort A-Z\",\r\n sortByDesc:\"Sort Z-A\",\r\n filterByColor:\"Filter by color\",\r\n filterByCondition:\"Filter by condition\",\r\n filterByValues:\"Filter by values\",\r\n\r\n filiterInputNone:\"None\",\r\n\r\n filiterInputTip:\"Enter filter value\",\r\n filiterRangeStartTip:\"Value for formula\",\r\n filiterRangeEndTip:\"Value for formula\",\r\n\r\n filterValueByAllBtn:\"Check all\",\r\n filterValueByClearBtn:\"Clear\",\r\n filterValueByInverseBtn:\"Inverse\",\r\n filterValueByTip:\"filter By Values\",\r\n filterConform:\"Confirm\",\r\n filterCancel:\"Cancel\",\r\n clearFilter:\"Clear filter\",\r\n\r\n conditionNone:\"None\",\r\n conditionCellIsNull:\"Is empty\",\r\n conditionCellNotNull:\"Is not empty\",\r\n conditionCellTextContain:\"Text contains\",\r\n conditionCellTextNotContain:\"Text does not contain\",\r\n conditionCellTextStart:\"Text starts with\",\r\n conditionCellTextEnd:\"Text ends with\",\r\n conditionCellTextEqual:\"Text is exactly\",\r\n conditionCellDateEqual:\"Date is\",\r\n conditionCellDateBefore:\"Date is before\",\r\n conditionCellDateAfter:\"Date is after\",\r\n conditionCellGreater:\"Greater than\",\r\n conditionCellGreaterEqual:\"Greater than or equal to\",\r\n conditionCellLess:\"Less than\",\r\n conditionCellLessEqual:\"Less than or equal to\",\r\n conditionCellEqual:\"Is equal to\",\r\n conditionCellNotEqual:\"Is not equal to\",\r\n conditionCellBetween:\"Is between\",\r\n conditionCellNotBetween:\"Is not between\",\r\n\r\n filiterMoreDataTip:\"Big amount of data! please wait\",\r\n filiterMonthText:\"Month\",\r\n filiterYearText:\"Year\",\r\n filiterByColorTip:\"Filter by cell color\",\r\n filiterByTextColorTip:\"Filter by font color\",\r\n filterContainerOneColorTip:\"This column contains only one color\",\r\n filterDateFormatTip:\"Date format\",\r\n\r\n valueBlank:\"(Null)\",\r\n mergeError:\"There are merged cells in the filter selection, this operation cannot be performed!\",\r\n },\r\n rightclick: {\r\n copy: 'Copy',\r\n copyAs: 'Copy as',\r\n paste: 'Paste',\r\n insert: 'Insert',\r\n delete: 'Delete',\r\n deleteCell: 'Delete cell',\r\n deleteSelected: 'Delete selected ',\r\n hide: 'Hide',\r\n hideSelected: 'Hide selected ',\r\n showHide: 'Show hidden ',\r\n to: 'Towards',\r\n left: 'Left',\r\n right: 'Right',\r\n top: 'Top',\r\n bottom: 'Bottom',\r\n moveLeft: 'Move left',\r\n moveUp: 'Move up',\r\n add: 'Add',\r\n row: 'Row',\r\n column: 'Column',\r\n width: 'Width',\r\n height: 'Height',\r\n number: 'Number',\r\n confirm: 'Confirm',\r\n orderAZ: 'A-Z order',\r\n orderZA: 'Z-A order',\r\n clearContent: 'Clear content',\r\n matrix: 'Matrix operation',\r\n sortSelection: 'Sort',\r\n filterSelection: 'Filter',\r\n chartGeneration: 'Create chart',\r\n firstLineTitle: 'first line title',\r\n untitled: 'untitled',\r\n array1: 'One-dimensional array',\r\n array2: 'Two-dimensional array',\r\n array3: 'Multidimensional Arrays',\r\n diagonal: 'Diagonal',\r\n antiDiagonal: 'Anti-diagonal',\r\n diagonalOffset: 'Diagonal offset',\r\n offset: 'Offset',\r\n boolean: 'Boolean',\r\n flip: 'Flip',\r\n upAndDown: 'Up and down',\r\n leftAndRight: 'Left and right',\r\n clockwise: 'Clockwise',\r\n counterclockwise: 'Counterclockwise',\r\n transpose: 'Transpose',\r\n matrixCalculation: 'Matrix calculation',\r\n plus: 'Plus',\r\n minus: 'Minus',\r\n multiply: 'Multiply',\r\n divided: 'Divided',\r\n power: 'Power',\r\n root: 'Root',\r\n log: 'Log',\r\n delete0: 'Delete 0 values at both ends',\r\n removeDuplicate: 'Remove duplicate values',\r\n byRow: 'By row',\r\n byCol: 'By column',\r\n generateNewMatrix: 'Generate new matrix',\r\n \r\n },\r\n comment:{\r\n \"insert\":\"Insert\",\r\n \"edit\":\"Edit\",\r\n \"delete\":\"Delete\",\r\n \"showOne\":\"Show/Hide\",\r\n \"showAll\":\"Show/Hide All\"\r\n },\r\n screenshot:{\r\n screenshotTipNoSelection:\"Please select the scope of the screenshot\",\r\n screenshotTipTitle:\"Warning!\",\r\n screenshotTipHasMerge:\"This operation cannot be performed on merged cells\",\r\n screenshotTipHasMulti:\"This operation cannot be performed on multiple selection regions\",\r\n screenshotTipSuccess:\"Successful\",\r\n screenshotImageName:\"Screenshot\",\r\n\r\n downLoadClose:\"Close\",\r\n downLoadCopy:\"Copy to clipboard\",\r\n downLoadBtn:\"Download\",\r\n browserNotTip:\"not supported by IE browser!\",\r\n rightclickTip:\"Please right-click \\\"copy\\\" on the picture\",\r\n successTip:\"Successfully (if pasting fails, please right-click on the image to \\\"copy image\\\")\",\r\n },\r\n splitText:{\r\n splitDelimiters:\"Delimiters\",\r\n splitOther:\"Other\",\r\n splitContinueSymbol:\"Consecutive separators are treated as a single\",\r\n splitDataPreview:\"Preview\",\r\n splitTextTitle:\"Split text\",\r\n splitConfirmToExe:\"There is already data here, do you want to replace it?\",\r\n\r\n tipNoMulti:\"Cannot perform this operation on multiple selection areas, please select a single area and try again\",\r\n tipNoMultiColumn:\"Only one column of data can be converted at a time. The selected area can have multiple rows but not multiple columns. Please try again after selecting a single column range\",\r\n },\r\n imageText:{\r\n imageSetting: 'Image setting',\r\n close: 'Close',\r\n conventional: 'Conventional',\r\n moveCell1: 'Move and resize cells',\r\n moveCell2: 'Move and do not resize the cell',\r\n moveCell3: 'Do not move and resize the cell',\r\n fixedPos: 'Fixed position',\r\n border: 'Border',\r\n width: 'Width',\r\n radius: 'Radius',\r\n style: 'Style',\r\n solid: 'Solid',\r\n dashed: 'Dashed',\r\n dotted: 'Dotted',\r\n double: 'Double',\r\n color: 'Color',\r\n },\r\n punctuation:{\r\n \"tab\":\"Tab\",\r\n \"semicolon\":\"semicolon\",\r\n \"comma\":\"comma\",\r\n \"space\":\"space\",\r\n \r\n },\r\n findAndReplace:{\r\n find:\"Find\",\r\n replace:\"Replace\",\r\n goto:\"Go to\",\r\n location:\"Location\",\r\n formula:\"Formula\",\r\n date:\"Date\",\r\n number:\"Number\",\r\n string:\"String\",\r\n error:\"Error\",\r\n condition:\"Condition\",\r\n rowSpan:\"Row span\",\r\n columnSpan:\"Column span\",\r\n locationExample:\"Location\",\r\n lessTwoRowTip:\"Please select at least two rows\",\r\n lessTwoColumnTip:\"Please select at least two columns\",\r\n\r\n findTextbox:\"Find Content\",\r\n replaceTextbox:\"Replace Content\",\r\n\r\n regexTextbox:\"Regular Expression\",\r\n wholeTextbox:\"Whole word\",\r\n distinguishTextbox:\"Case sensitive\",\r\n\r\n allReplaceBtn:\"Replace All\",\r\n replaceBtn:\"Replace\",\r\n allFindBtn:\"Find All\",\r\n findBtn:\"Find next\",\r\n\r\n noFindTip:\"The content was not found\",\r\n modeTip:\"This operation is not available in this mode\",\r\n\r\n searchTargetSheet:\"Sheet\",\r\n searchTargetCell:\"Cell\",\r\n searchTargetValue:\"Value\",\r\n\r\n searchInputTip:\"Please enter the search content\",\r\n\r\n noReplceTip:\"There is nothing to replace\",\r\n noMatchTip:\"No match found\",\r\n\r\n successTip:\"${xlength} items found\",\r\n\r\n locationConstant:\"Constant\",\r\n locationFormula:\"Formula\",\r\n locationDate:\"Date\",\r\n locationDigital:\"Number\",\r\n locationString:\"String\",\r\n locationBool:\"Logical\",\r\n locationError:\"Error\",\r\n locationNull:\"Null\",\r\n locationCondition:\"Conditional format\",\r\n locationRowSpan:\"Row span\",\r\n locationColumnSpan:\"Column span\",\r\n\r\n locationTiplessTwoRow:\"Please select at least two rows\",\r\n locationTiplessTwoColumn:\"Please select at least two columns\",\r\n locationTipNotFindCell:\"Cell not found\"\r\n \r\n },\r\n sheetconfig: {\r\n delete: 'Delete',\r\n copy: 'Copy',\r\n rename: 'Rename',\r\n changeColor: 'Change color',\r\n hide: 'Hide',\r\n unhide: 'Unhide',\r\n moveLeft: 'Move left',\r\n moveRight: 'Move right',\r\n resetColor: 'Reset color',\r\n cancelText: 'Cancel',\r\n chooseText: 'Confirm color',\r\n\r\n tipNameRepeat:\"The name of the tab page cannot be repeated! Please revise\",\r\n noMoreSheet:\"The workbook contains at least one visual worksheet. To delete the selected worksheet, please insert a new worksheet or show a hidden worksheet.\",\r\n confirmDelete:\"Are you sure to delete\",\r\n redoDelete:\"Can be undo by Ctrl+Z\",\r\n noHide:\"Can't hide, at least keep one sheet tag\",\r\n chartEditNoOpt:\"This operation is not allowed in chart editing mode!\",\r\n sheetNameSpecCharError:\"The name cannot contain:[ ] : \\ ? * / ' \\\"\",\r\n sheetNamecannotIsEmptyError:\"Sheet name cannot be empty\"\r\n },\r\n conditionformat: {\r\n conditionformat_greaterThan: 'Conditionformat-GreaterThan',\r\n conditionformat_greaterThan_title: 'Format cells greater than',\r\n conditionformat_lessThan: 'Conditionformat-LessThan',\r\n conditionformat_lessThan_title: 'Format cells smaller than',\r\n conditionformat_betweenness: 'Conditionformat-Betweenness',\r\n conditionformat_betweenness_title: 'Format cells with values between',\r\n conditionformat_equal: 'Conditionformat-Equal',\r\n conditionformat_equal_title: 'Format cells equal to',\r\n conditionformat_textContains: 'Conditionformat-TextContains',\r\n conditionformat_textContains_title: 'Format cells containing the following text',\r\n conditionformat_occurrenceDate: 'Conditionformat-OccurrenceDate',\r\n conditionformat_occurrenceDate_title: 'Format cells containing the following dates',\r\n conditionformat_duplicateValue: 'Conditionformat-DuplicateValue',\r\n conditionformat_duplicateValue_title: 'Format cells containing the following types of values',\r\n conditionformat_top10: 'Conditionformat-Top10',\r\n conditionformat_top10_percent: 'Conditionformat-Top10%',\r\n conditionformat_top10_title: 'Format the cells with the highest value',\r\n conditionformat_last10: 'Conditionformat-Last10',\r\n conditionformat_last10_percent: 'Conditionformat-Last10%',\r\n conditionformat_last10_title: 'Format the cells with the smallest value',\r\n conditionformat_AboveAverage: 'Conditionformat-AboveAverage',\r\n conditionformat_AboveAverage_title: 'Format cells above average',\r\n conditionformat_SubAverage: 'Conditionformat-SubAverage',\r\n conditionformat_SubAverage_title: 'Format cells below average',\r\n rule: 'Rule',\r\n newRule: 'New rule',\r\n editRule: 'Edit rule',\r\n deleteRule: 'Delete rule',\r\n deleteCellRule: 'Delete cell rule',\r\n deleteSheetRule: 'Delete sheet rule',\r\n manageRules: 'Management rules',\r\n showRules: 'Show its formatting rules',\r\n highlightCellRules: 'Highlight cell rules',\r\n itemSelectionRules: 'Item selection rules',\r\n conditionformatManageRules: 'Conditional Formatting Rule Manager',\r\n format: 'Format',\r\n setFormat: 'Set format',\r\n setAs: 'Set as',\r\n setAsByArea: 'For the selected area, set to',\r\n applyRange: 'Apply range',\r\n selectRange: 'Select application range',\r\n selectRange_percent: 'Percentage of selected range',\r\n selectRange_average: 'Average value of selected range',\r\n selectRange_value: 'Value in the selected range',\r\n pleaseSelectRange: 'Please select application range',\r\n selectDataRange: 'Select data range',\r\n selectCell: 'select cell',\r\n pleaseSelectCell: 'Please select cell',\r\n pleaseSelectADate: 'Please select a date',\r\n pleaseEnterInteger: 'Please enter an integer between 1 and 1000',\r\n onlySingleCell: 'Only a single cell can be referenced',\r\n conditionValueCanOnly: 'The condition value can only be a number or a single cell',\r\n ruleTypeItem1: 'Format all cells based on their respective values',\r\n ruleTypeItem2: 'Only format cells that contain',\r\n ruleTypeItem2_title: 'Only for cells that meet the following conditions',\r\n ruleTypeItem3: 'Format only the top or bottom numbers',\r\n ruleTypeItem3_title: 'Is the value in the following ranking',\r\n ruleTypeItem4: 'Format only values above or below the average',\r\n ruleTypeItem4_title: 'Is a value that satisfies the following conditions',\r\n ruleTypeItem5: 'Format only unique or repeated values',\r\n ruleTypeItem6: 'Use formulas to determine which cells to format',\r\n formula: 'Formula',\r\n textColor: 'Text color',\r\n cellColor: 'Cell color',\r\n confirm: 'Confirm',\r\n confirmColor: 'Confirm color',\r\n cancel: 'Cancel',\r\n close: 'Close',\r\n clearColorSelect: 'Clear color select',\r\n sheet: 'Sheet',\r\n currentSheet: 'Current Sheet',\r\n dataBar: 'data bar',\r\n dataBarColor: 'data bar color',\r\n gradientDataBar_1: 'Blue-white gradient data bar',\r\n gradientDataBar_2: 'Green-white gradient data bar',\r\n gradientDataBar_3: 'Red-white gradient data bar',\r\n gradientDataBar_4: 'Orange-white gradient stripes',\r\n gradientDataBar_5: 'Light blue-white gradient stripes',\r\n gradientDataBar_6: 'Purple-white gradient data bar',\r\n solidColorDataBar_1: 'Blue data bar',\r\n solidColorDataBar_2: 'Green data bar',\r\n solidColorDataBar_3: 'Red data bar',\r\n solidColorDataBar_4: 'Orange data bar',\r\n solidColorDataBar_5: 'Light blue data bar',\r\n solidColorDataBar_6: 'Purple data bar',\r\n colorGradation: 'color gradation',\r\n colorGradation_1: 'Green-yellow-red color gradation',\r\n colorGradation_2: 'Red-yellow-green color gradation',\r\n colorGradation_3: 'Green-white-red color gradation',\r\n colorGradation_4: 'Red-white-green color gradation',\r\n colorGradation_5: 'Blue-white-red color gradation',\r\n colorGradation_6: 'Red-white-blue color gradation',\r\n colorGradation_7: 'White-red color gradation',\r\n colorGradation_8: 'Red-white color gradation',\r\n colorGradation_9: 'Green-white color gradation',\r\n colorGradation_10: 'White-green color gradation',\r\n colorGradation_11: 'Green-yellow color gradation',\r\n colorGradation_12: 'Yellow-green color gradation',\r\n icons: 'icons',\r\n pleaseSelectIcon: 'Please click to select a group of icons:',\r\n cellValue: 'Cell value',\r\n specificText: 'Specific text',\r\n occurrence: 'Date',\r\n greaterThan: 'Greater than',\r\n lessThan: 'Less than',\r\n between: 'Between',\r\n equal: 'Equal',\r\n in: 'In',\r\n between2: '',\r\n contain: 'Contain',\r\n textContains: 'Text contains',\r\n duplicateValue: 'Duplicate value',\r\n uniqueValue: 'Unique value',\r\n top: 'Top',\r\n top10: 'Top 10',\r\n top10_percent: 'Top 10%',\r\n last: 'Last',\r\n last10: 'Last 10',\r\n last10_percent: 'Last 10%',\r\n oneself: '',\r\n above: 'Above',\r\n aboveAverage: 'Above average',\r\n below: 'Below',\r\n belowAverage: 'Below average',\r\n all: 'All',\r\n yesterday: 'YTD',\r\n today: 'Today',\r\n tomorrow: 'Tomorrow',\r\n lastWeek: 'Last week',\r\n thisWeek: 'This week',\r\n lastMonth: 'Last month',\r\n thisMonth: 'This month',\r\n lastYear: 'Last year',\r\n thisYear: 'This year',\r\n last7days: 'Last 7 days',\r\n last30days: 'Last 30 days',\r\n next7days: 'Next 7 days',\r\n next30days: 'Next 30 days',\r\n next60days: 'Next 60 days',\r\n chooseRuleType: 'Choose rule type',\r\n editRuleDescription: 'Edit rule description',\r\n newFormatRule: 'New format rule',\r\n editFormatRule: 'Edit format rule',\r\n formatStyle: 'Style',\r\n fillType: 'Fill',\r\n color: 'Color',\r\n twocolor: 'Two-color',\r\n tricolor: 'Tricolor',\r\n multicolor: 'Multi color',\r\n grayColor: 'Gray color',\r\n gradient: 'Gradient',\r\n solid: 'Solid',\r\n maxValue: 'Max value',\r\n medianValue: 'Median value',\r\n minValue: 'Min value',\r\n direction: 'Direction',\r\n threeWayArrow: 'Three-way arrow',\r\n fourWayArrow: 'Four-way arrow',\r\n fiveWayArrow: 'Five-way arrow',\r\n threeTriangles: 'Three triangles',\r\n shape: 'Shape',\r\n threeColorTrafficLight: 'Three-color traffic light',\r\n fourColorTrafficLight: 'Four-color traffic light',\r\n threeSigns: 'Three signs',\r\n greenRedBlackGradient: 'Green-red-black gradient',\r\n rimless: 'Rimless',\r\n bordered: 'Bordered',\r\n mark: 'Mark',\r\n threeSymbols: 'Three symbols',\r\n tricolorFlag: 'Tricolor flag',\r\n circled: 'Circled',\r\n noCircle: 'No circle',\r\n grade: 'Grade',\r\n grade4: '4 Grade',\r\n grade5: '5 Grade',\r\n threeStars: '3 Stars',\r\n fiveQuadrantDiagram: 'Five-quadrant diagram',\r\n fiveBoxes: '5 Boxes',\r\n },\r\n insertLink: {\r\n linkText: \"Text\",\r\n linkType: \"Link type\",\r\n external: \"External link\",\r\n internal: \"Internal link\",\r\n linkAddress: \"Link address\",\r\n linkSheet: \"Worksheet\",\r\n linkCell: \"Cell reference\",\r\n linkTooltip: \"Tooltip\",\r\n placeholder1: \"Please enter the web link address\",\r\n placeholder2: \"Please enter the cell to be quoted, example A1\",\r\n placeholder3: \"Please enter the prompt content\",\r\n tooltipInfo1: \"Please enter a valid link\",\r\n tooltipInfo2: \"Please enter the correct cell reference\",\r\n },\r\n dataVerification: {\r\n cellRange: 'Cell range',\r\n selectCellRange: 'Click to select a cell range',\r\n selectCellRange2: 'Please select a range of cells',\r\n verificationCondition: 'Verification condition',\r\n dropdown: 'drop-down list',\r\n checkbox: 'Checkbox',\r\n number: 'Number',\r\n number_integer: 'Number-integer',\r\n number_decimal: 'Number-decimal',\r\n text_content: 'Text-content',\r\n text_length: 'Text-length',\r\n date: 'Date',\r\n validity: 'Effectiveness',\r\n placeholder1: 'Please enter the options, separated by commas, such as 1,2,3,4,5',\r\n placeholder2: 'Please enter content',\r\n placeholder3: 'Numeric value, such as 10',\r\n placeholder4: 'Please enter the specified text',\r\n placeholder5: 'Please enter the prompt displayed when the cell is selected',\r\n selected: 'Selected',\r\n notSelected: 'Not selected',\r\n between: 'Between',\r\n notBetween: 'Not between',\r\n equal: 'Equal',\r\n notEqualTo: 'Not equal to',\r\n moreThanThe: 'More than the',\r\n lessThan: 'Less than',\r\n greaterOrEqualTo: 'Greater or equal to',\r\n lessThanOrEqualTo: 'Less than or equal to',\r\n include: 'Include',\r\n exclude: 'Exclude',\r\n earlierThan: 'Earlier than',\r\n noEarlierThan: 'No earlier than',\r\n laterThan: 'Later than',\r\n noLaterThan: 'No later than',\r\n identificationNumber: 'Identification number',\r\n phoneNumber: 'Phone number',\r\n remote: 'Automatic remote acquisition option',\r\n prohibitInput: 'Prohibit input when input data is invalid',\r\n hintShow: 'Show prompt when the cell is selected',\r\n deleteVerification: 'Delete verification',\r\n tooltipInfo1: 'The drop-down list option cannot be empty',\r\n tooltipInfo2: 'Checkbox content cannot be empty',\r\n tooltipInfo3: 'The value entered is not a numeric type',\r\n tooltipInfo4: 'The value 2 cannot be less than the value 1',\r\n tooltipInfo5: 'The text content cannot be empty',\r\n tooltipInfo6: 'The value entered is not a date type',\r\n tooltipInfo7: 'Date 2 cannot be less than date 1',\r\n },\r\n formula:{\r\n sum:\"Sum\",\r\n average:\"Average\",\r\n count:\"Count\",\r\n max:\"Max\",\r\n min:\"Min\",\r\n ifGenerate:\"If formula generator\",\r\n find:\"Learn more\",\r\n\r\n tipNotBelongToIf:\"This cell function does not belong to the if formula!\",\r\n tipSelectCell:\"Please select the cell to insert the function\",\r\n\r\n ifGenCompareValueTitle:\"Comparison value\",\r\n ifGenSelectCellTitle:\"Click to select cell\",\r\n ifGenRangeTitle:\"Range\",\r\n ifGenRangeTo:\"to\",\r\n ifGenRangeEvaluate:\"Range evaluate\",\r\n ifGenSelectRangeTitle:\"Click to select range\",\r\n ifGenCutWay:\"Partition way\",\r\n ifGenCutSame:\"Same Partition value\",\r\n ifGenCutNpiece:\"Partition by N\",\r\n ifGenCutCustom:\"Custom\",\r\n ifGenCutConfirm:\"Confirm\",\r\n\r\n ifGenTipSelectCell:\"Select cells\",\r\n ifGenTipSelectCellPlace:\"Please select cells\",\r\n\r\n ifGenTipSelectRange:\"Select range\",\r\n ifGenTipSelectRangePlace:\"Please select range\",\r\n\r\n ifGenTipNotNullValue:\"The comparison value cannot be empty!\",\r\n ifGenTipLableTitile:\"Label\",\r\n ifGenTipRangeNotforNull:\"The range cannot be empty!\",\r\n ifGenTipCutValueNotforNull:\"The partition value cannot be empty!\",\r\n ifGenTipNotGenCondition:\"No conditions are available for generation!\",\r\n },\r\n formulaMore:{\r\n valueTitle:\"Value\",\r\n tipSelectDataRange:\"Select data range\",\r\n tipDataRangeTile:\"Data range\",\r\n findFunctionTitle:\"Search function\",\r\n tipInputFunctionName:\"Function name or brief description of function\",\r\n\r\n \"Array\":\"Array\",\r\n \"Database\":\"Database\",\r\n \"Date\":\"Date\",\r\n \"Engineering\":\"Engineering\",\r\n \"Filter\":\"Filter\",\r\n \"Financial\":\"Financial\",\r\n \"luckysheet\":\"Luckysheet\",\r\n \"other\":\"Other\",\r\n \"Logical\":\"Logical\",\r\n \"Lookup\":\"Lookup\",\r\n \"Math\":\"Math\",\r\n \"Operator\":\"Operator\",\r\n \"Parser\":\"Parser\",\r\n \"Statistical\":\"Statistical\",\r\n \"Text\":\"Text\",\r\n \"dataMining\":\"Data Mining\",\r\n\r\n \"selectFunctionTitle\":\"Select a function\",\r\n \"calculationResult\":\"Result\",\r\n\r\n tipSuccessText:\"Success\",\r\n tipParamErrorText:\"Parameter type error\",\r\n\r\n \"helpClose\":\"Close\",\r\n \"helpCollapse\":\"Collapse\",\r\n \"helpExample\":\"Example\",\r\n \"helpAbstract\":\"Abstract\",\r\n\r\n \"execfunctionError\":'Error in the formula',\r\n \"execfunctionSelfError\":'The formula cannot refer to its own cell',\r\n \"execfunctionSelfErrorResult\":'The formula cannot refer to its own cell, which will lead to inaccurate calculation results',\r\n\r\n \"allowRepeatText\":\"Repeat\",\r\n \"allowOptionText\":\"Option\",\r\n\r\n \"selectCategory\":\"Or select a category\",\r\n },\r\n drag:{\r\n noMerge:\"Cannot perform this operation on merged cells\",\r\n affectPivot:\"This change cannot be made to the selected cell because it will affect the pivot table!\",\r\n noMulti:\"Cannot perform this operation on multiple selection areas, please select a single area\",\r\n noPaste:\"Unable to paste this content here, please select a cell in the paste area and try to paste again\",\r\n noPartMerge:\"Cannot perform this operation on partially merged cells\",\r\n\r\n inputCorrect:\"Please enter the correct value\",\r\n notLessOne:\"The number of rows and columns cannot be less than 1\",\r\n offsetColumnLessZero:\"The offset column cannot be negative!\",\r\n\r\n pasteMustKeybordAlert:\"在表格中进行复制粘贴: Ctrl + C 进行复制, Ctrl + V 进行粘贴, Ctrl + X 进行剪切\",\r\n pasteMustKeybordAlertHTMLTitle:\"在表格中进行复制粘贴\",\r\n pasteMustKeybordAlertHTML:\"Ctrl + C  进行复制
Ctrl + V  进行粘贴
Ctrl + X  进行剪切\",\r\n },\r\n pivotTable:{\r\n title:\"Pivot Table\",\r\n closePannel:\"Close\",\r\n editRange:\"Range\",\r\n tipPivotFieldSelected:\"Select the fields\",\r\n tipClearSelectedField:\"Clear all fields\",\r\n btnClearSelectedField:\"Clear\",\r\n btnFilter:\"Filter\",\r\n titleRow:\"Row\",\r\n titleColumn:\"Column\",\r\n titleValue:\"Value\",\r\n tipShowColumn:\"Statistics fields are displayed as columns\",\r\n tipShowRow:\"Statistics fields are displayed as rows\",\r\n\r\n titleSelectionDataRange:\"Select range\",\r\n titleDataRange:\"Data range\",\r\n\r\n valueSum:\"SUM\",\r\n\r\n valueStatisticsSUM:\"Sum\",\r\n valueStatisticsCOUNT:\"Count\",\r\n valueStatisticsCOUNTA:\"Count A\",\r\n valueStatisticsCOUNTUNIQUE:\"Count Unique\",\r\n valueStatisticsAVERAGE:\"Average\",\r\n valueStatisticsMAX:\"Max\",\r\n valueStatisticsMIN:\"Min\",\r\n valueStatisticsMEDIAN:\"Median\",\r\n valueStatisticsPRODUCT:\"Product\",\r\n valueStatisticsSTDEV:\"Stdev\",\r\n\r\n valueStatisticsSTDEVP:\"Stdevp\",\r\n valueStatisticslet:\"Var\",\r\n valueStatisticsVARP:\"VarP\",\r\n\r\n errorNotAllowEdit:\"This operation is prohibited in non-editing mode!\",\r\n errorNotAllowMulti:\"Cannot perform this operation on multiple selection areas, please select a single range and try again\",\r\n errorSelectRange:\"Please select the range of the new pivot table\",\r\n errorIsDamage:\"The source data of this pivot table is corrupted!\",\r\n errorNotAllowPivotData:\"Cannot select pivot table as source data!\",\r\n errorSelectionRange:\"Selection failed, wrong input range!\",\r\n errorIncreaseRange:\"Please expand the selected range!\",\r\n\r\n titleAddColumn:\"Add column to pivot table\",\r\n titleMoveColumn:\"Move the column to the white box below\",\r\n titleClearColumnFilter:\"Clear the filter for this column\",\r\n titleFilterColumn:\"Filter\",\r\n\r\n titleSort:\"Sort\",\r\n titleNoSort:\"No sort\",\r\n titleSortAsc:\"ASC\",\r\n titleSortDesc:\"DESC\",\r\n titleSortBy:\"Sort by\",\r\n titleShowSum:\"Show total\",\r\n titleStasticTrue:\"Yes\",\r\n titleStasticFalse:\"No\",\r\n },\r\n dropCell:{\r\n copyCell:\"Copy\",\r\n sequence:\"Sequence\",\r\n onlyFormat:\"Only format\",\r\n noFormat:\"Not format\",\r\n day:\"Day\",\r\n workDay:\"Work Day\",\r\n month:\"Month\",\r\n year:\"Year\",\r\n chineseNumber:\"Chinese numbers\",\r\n },\r\n imageCtrl:{\r\n borderTile:\"Image border color\",\r\n borderCur:\"Color\",\r\n },\r\n protection:{\r\n protectiontTitle:\"Protection\",\r\n enterPassword:\"Enter a password (optional)\",\r\n enterHintTitle:\"Prompt when editing is prohibited (optional)\",\r\n enterHint:\"The cell or chart you are trying to change is in a protected worksheet. If you want to change it, please unprotect the worksheet. You may need to enter a password\",\r\n swichProtectionTip:\"Protect the sheet and contents of locked cells\",\r\n authorityTitle:\"Allow users of this sheet to:\",\r\n selectLockedCells:\"Select locked cells\",\r\n selectunLockedCells:\"Select unlocked cells\",\r\n formatCells:\"Format cells\",\r\n formatColumns:\"Format columns\",\r\n formatRows:\"Format rows\",\r\n insertColumns:\"Insert columns\",\r\n insertRows:\"Insert rows\",\r\n insertHyperlinks:\"Insert hyperlinks\",\r\n deleteColumns:\"Delete columns\",\r\n deleteRows:\"Delete rows\",\r\n sort:\"Sort\",\r\n filter:\"Filter\",\r\n usePivotTablereports:\"Use Pivot Table reports\",\r\n editObjects:\"Edit objects\",\r\n editScenarios:\"Edit scenarios\",\r\n\r\n allowRangeTitle:\"Allow users of range to:\",\r\n allowRangeAdd:\"New...\",\r\n\r\n allowRangeAddTitle:\"Title\",\r\n allowRangeAddSqrf:\"Reference\",\r\n selectCellRange: 'Click to select a cell range',\r\n selectCellRangeHolder:\"Cell range\",\r\n allowRangeAddTitlePassword:\"Password\",\r\n allowRangeAddTitleHint:\"Prompt\",\r\n allowRangeAddTitleHintTitle:\"Prompt when a password is set (optional)\",\r\n allowRangeAddtitleDefault:\"Input range name\",\r\n\r\n rangeItemDblclick:\"Double click to edit\",\r\n rangeItemHasPassword:\"Has password\",\r\n\r\n rangeItemErrorTitleNull:\"Title is null\",\r\n rangeItemErrorRangeNull:\"Reference is null\",\r\n rangeItemErrorRange:\"Reference is error\",\r\n\r\n validationTitle:\"Password validation\",\r\n validationTips:\"Need to enter a password to unlock the protection of the worksheet\",\r\n validationInputHint:\"Enter a password\",\r\n\r\n checkPasswordNullalert:\"Password is required!\",\r\n checkPasswordWrongalert:\"Incorrect password, please try again!\",\r\n\r\n checkPasswordSucceedalert:\"Unlock Succeed!\",\r\n defaultRangeHintText:\"The cell is being password protected.\",\r\n defaultSheetHintText:\"The cell or chart is in a protected worksheet. To make changes, please unprotect the worksheet. You may need to enter a password\",\r\n },\r\n cellFormat:{\r\n cellFormatTitle:\"Format cells\",\r\n protection:\"Protection\",\r\n locked:\"Locked\",\r\n hidden:\"Hidden\",\r\n protectionTips:\"To lock cells or hide formulas, protect the worksheet. On the toolbar, Click Protect Sheet Button\",\r\n tipsPart:\"Partial checked\",\r\n tipsAll:\"All checked\",\r\n\r\n selectionIsNullAlert:\"Selection is required!\",\r\n sheetDataIsNullAlert:\"error, Data is none!\",\r\n\r\n },\r\n print:{\r\n normalBtn:\"Normal\",\r\n layoutBtn:\"Page Layout\",\r\n pageBtn:\"Page break preview\",\r\n\r\n menuItemPrint:\"Print (Ctrl+P)\",\r\n menuItemAreas:\"Print areas\",\r\n menuItemRows:\"Print title rows\",\r\n menuItemColumns:\"Print title columns\",\r\n },\r\n edit:{\r\n typing:\"typing\",\r\n },\r\n websocket:{\r\n success: 'WebSocket connection success',\r\n refresh: 'An error occurred in the WebSocket connection, please refresh the page!',\r\n wait: 'An error occurred in the WebSocket connection, please be patient!',\r\n close: 'WebSocket connection closed',\r\n contact: 'Server communication error occurred, please refresh the page and try again, if not, please contact the administrator!',\r\n support: 'The current browser does not support WebSocket',\r\n }\r\n };\r\n ","export default {\r\n functionlist:[{\r\n 'n': 'SUMIF',\r\n 't': 0,\r\n 'd': '对范围中符合指定条件的值求和。',\r\n 'a': '对范围中符合指定条件的值求和。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': '范围',\r\n 'detail': '要根据条件进行检测的范围。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': '条件',\r\n 'detail': '要应用于范围的模式或测试条件。\\n\\n如果范围包含的是要检测的文本,则条件必须为字符串。条件可以包含通配符,包括用于匹配单个字符的?或用于匹配零个或连续多个字符的*。要匹配问号星号本身,请在该字符前面加上波浪号(~)前缀(即~?和~*)。字符串条件必须用引号括起来。函数会检查范围中的每个单元格与条件是否相等或匹配(如果使用了通配符)。\\n\\n如果范围包含的是要检测的数字,则条件可以是字符串也可以是数字。如果给定的条件是一个数字,则检查范围中的每个单元格是否等于条件。另外,条件也可能是包含数字的字符串(也将对其进行相等检测),或者带有以下前缀的数字:=(检查是否相等)、>(检查范围单元格的值是否大于条件值)或<(检查范围单元格的值是否小于条件值)',\r\n 'example': '\">20\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '求和范围',\r\n 'detail': '要求和的范围(如果与范围不同)。',\r\n 'example': 'B1:B10',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'TAN',\r\n 't': 0,\r\n 'd': '返回已知角度的正切值。',\r\n 'a': '返回已知角度的正切值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '角度',\r\n 'detail': '要求其正切值的角度,以弧度表示。',\r\n 'example': '45*PI()/180',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TANH',\r\n 't': 0,\r\n 'd': '返回给定实数的双曲正切值。',\r\n 'a': '返回给定实数的双曲正切值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其双曲正切值的实数。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CEILING',\r\n 't': 0,\r\n 'd': '将数值向上取整为最接近的指定因数的倍数。',\r\n 'a': '将数值向上取整为最接近的指定因数的倍数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要向上舍入的数值。',\r\n 'example': '23.25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '因数',\r\n 'detail': '要将值舍入到此数的整数倍。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ATAN',\r\n 't': 0,\r\n 'd': '返回数值的反正切值,以弧度表示。',\r\n 'a': '返回数值的反正切值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其反正切值的数值。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ASINH',\r\n 't': 0,\r\n 'd': '返回数值的反双曲正弦值。',\r\n 'a': '返回数值的反双曲正弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其反双曲正弦值的数值。',\r\n 'example': '0.9',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ABS',\r\n 't': 0,\r\n 'd': '返回数值的绝对值。',\r\n 'a': '返回数值的绝对值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要返回其绝对值的数。',\r\n 'example': '-2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ACOS',\r\n 't': 0,\r\n 'd': '返回数值的反余弦值,以弧度表示。',\r\n 'a': '返回数值的反余弦值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其反余弦值的数值。必须介于-1和1之间,包括两端值。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ACOSH',\r\n 't': 0,\r\n 'd': '返回数值的反双曲余弦值。',\r\n 'a': '返回数值的反双曲余弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其反双曲余弦值的数值。必须大于等于1。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MULTINOMIAL',\r\n 't': 0,\r\n 'd': '返回参数和的阶乘除以各参数阶乘的乘积后得到的值。',\r\n 'a': '返回参数和的阶乘除以各参数阶乘的乘积后得到的值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '用于计算的第一项数值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '用于计算的其他数值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ATANH',\r\n 't': 0,\r\n 'd': '返回数值的反双曲正切值。',\r\n 'a': '返回数值的反双曲正切值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其反双曲正切值的数值。必须介于-1和1之间(不包括-1和1)。',\r\n 'example': '0.9',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ATAN2',\r\n 't': 0,\r\n 'd': '以弧度为单位返回 x 轴与从原点 (0,0) 到指定坐标点 (`x`,`y`) 之间连线的夹角。',\r\n 'a': '以弧度为单位返回 x 轴与从原点 (0,0) 到指定坐标点 (`x`,`y`) 之间连线的夹角。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '要计算其与x轴夹角大小的线段的终点x坐标。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'y',\r\n 'detail': '要计算其与x轴夹角大小的线段的终点y坐标。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUNTBLANK',\r\n 't': 1,\r\n 'd': '返回给定范围内的空单元格数。',\r\n 'a': '返回给定范围内的空单元格数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '范围',\r\n 'detail': '要统计空白单元格数量的范围。',\r\n 'example': 'A2:C100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'COSH',\r\n 't': 0,\r\n 'd': '返回给定实数的双曲余弦值。',\r\n 'a': '返回给定实数的双曲余弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其双曲余弦值的实数值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'INT',\r\n 't': 0,\r\n 'd': '将数值向下取整为小于或等于该数的最接近的整数。',\r\n 'a': '将数值向下取整为小于或等于该数的最接近的整数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要向下取整为最接近的整数的数值。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ISEVEN',\r\n 't': 0,\r\n 'd': '检查所提供的数值是否为偶数。',\r\n 'a': '检查所提供的数值是否为偶数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要验证其是否为偶数的数值。\\n\\n如果值为偶数或指向包含偶数的单元格的引用,ISEVEN将返回TRUE,否则返回FALSE。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ISODD',\r\n 't': 0,\r\n 'd': '检查所提供的数值是否为奇数。',\r\n 'a': '检查所提供的数值是否为奇数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要验证其是否为奇数的数值。\\n\\n如果值为奇数或指向包含奇数的单元格,ISODD将返回TRUE,否则返回FALSE。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LCM',\r\n 't': 0,\r\n 'd': '返回一个或多个整数的最小公倍数。',\r\n 'a': '返回一个或多个整数的最小公倍数。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '要在求最小公倍数数的计算中检查其因数的第一项数值或范围。',\r\n 'example': 'A2:A5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 在求最小公倍数时要考虑其因数的其他数值或范围。',\r\n 'example': '3',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LN',\r\n 't': 0,\r\n 'd': '返回数值以 e(欧拉数)为底的对数。',\r\n 'a': '返回数值以 e(欧拉数)为底的对数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要以 e 为底数计算其对数的值。\\n\\n值必须为正数。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOG',\r\n 't': 0,\r\n 'd': '根据指定底数返回数字的对数。',\r\n 'a': '根据指定底数返回数字的对数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '想要计算其对数的正实数。',\r\n 'example': '128',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '底数',\r\n 'detail': '[可选] - 对数的底数。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOG10',\r\n 't': 0,\r\n 'd': '返回数值以10为底的对数。',\r\n 'a': '返回数值以10为底的对数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其以10为底的对数的数值。\\n\\n值必须为正值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MOD',\r\n 't': 0,\r\n 'd': '返回两数相除的余数, 结果的符号与除数相同。',\r\n 'a': '返回两数相除的余数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '被除数',\r\n 'detail': '要将其相除以得到余数的数值。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '除数',\r\n 'detail': '用于除其他数的数值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MROUND',\r\n 't': 0,\r\n 'd': '将数值取整为另一整数最接近的整数倍。',\r\n 'a': '将数值取整为另一整数最接近的整数倍。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要取整为另一整数最接近的整数倍的数值。',\r\n 'example': '21',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '因数',\r\n 'detail': '值将取此因数的整数倍。',\r\n 'example': '14',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ODD',\r\n 't': 0,\r\n 'd': '将数值向上取整为最接近的奇整数。',\r\n 'a': '将数值向上取整为最接近的奇整数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要向上取整的数值,取整值为大于此值的最接近的奇数。\\n\\n如果值为负数,则将其取整为绝对值大于该值的相邻负奇数。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMSQ',\r\n 't': 0,\r\n 'd': '返回一组数值和/或单元格的平方总和。',\r\n 'a': '返回一组数值和/或单元格的平方总和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '要将其平方相加的第一个数值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 要将其平方与值1的平方相加的其他数值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COMBIN',\r\n 't': 0,\r\n 'd': '给定集合中的对象总数和要选择的对象数量,返回共有多少种不同选择方式。',\r\n 'a': '给定集合中的对象总数和要选择的对象数量',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'n',\r\n 'detail': '要从中进行选择的对象集合的大小。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'k',\r\n 'detail': '要选择的对象数量。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUM',\r\n 't': 0,\r\n 'd': '返回一组数值和/或单元格的总和。',\r\n 'a': '返回一组数值和/或单元格的总和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '要相加的第一个数值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 要相加的其他数值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'SUBTOTAL',\r\n 't': 0,\r\n 'd': '使用指定的汇总函数,返回一系列纵向单元格的分类汇总。',\r\n 'a': '使用指定的汇总函数',\r\n 'm': [2, 256],\r\n 'p': [{\r\n 'name': '函数代码',\r\n 'detail': '用于计算分类汇总的函数。\\n\\n1代表AVERAGE\\n\\n2代表COUNT\\n\\n3代表COUNTA\\n\\n4代表MAX\\n\\n5代表MIN\\n\\n6代表PRODUCT\\n\\n7代表STDEV\\n\\n8代表STDEVP\\n\\n9代表SUM\\n\\n10代表VAR\\n\\n11代表VARP\\n\\n通过在这些2位代码前附加10(对于1位代码)或1(对于2位代码),可以将隐藏值忽略。例如,102代表忽略隐藏单元格的COUNT,而110则代表忽略隐藏值的VAR。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '范围1',\r\n 'detail': '要计算分类汇总的第一个范围。',\r\n 'example': 'A2:A5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': '范围2',\r\n 'detail': '[可选] - 要计算分类汇总的其他范围。',\r\n 'example': 'B2:B8',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'ASIN',\r\n 't': 0,\r\n 'd': '返回数值的反正弦值,以弧度表示。',\r\n 'a': '返回数值的反正弦值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其反正弦值的数值。必须介于-1和1之间,包括两端值。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUNTIF',\r\n 't': 1,\r\n 'd': '返回范围内满足某个条件的单元格的数量。',\r\n 'a': '返回范围内满足某个条件的单元格的数量。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '范围',\r\n 'detail': '要根据条件进行检测的范围。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': '条件',\r\n 'detail': '要应用于范围的模式或测试条件。\\n\\n如果范围包含的是要检测的文本,则条件必须为字符串。条件可以包含通配符,包括用于匹配单个字符的?或用于匹配零个或连续多个字符的*。要匹配问号星号本身,请在该字符前面加上波浪号(~)前缀(即~?和~*)。字符串条件必须用引号括起来。函数会检查范围中的每个单元格与条件是否相等或匹配(如果使用了通配符)。\\n\\n如果范围包含的是要检测的数字,则条件可以是字符串也可以是数字。如果给定的条件是一个数字,则检查范围中的每个单元格是否等于条件。另外,条件也可能是包含数字的字符串(也将对其进行相等检测),或者带有以下前缀的数字:=、>、>=、<或<=,这些条件将分别用于检查范围中的单元格是否等于、大于、大于等于、小于、小于等于条件值。',\r\n 'example': '\">20\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RADIANS',\r\n 't': 0,\r\n 'd': '将以度表示的角度值转换为弧度。',\r\n 'a': '将以度表示的角度值转换为弧度。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '角度',\r\n 'detail': '要从度转换为弧度的角度。',\r\n 'example': '180',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RAND',\r\n 't': 0,\r\n 'd': '返回一个介于0和1之间(包括0但不包括1)的随机数。',\r\n 'a': '返回一个介于0和1之间(包括0但不包括1)的随机数。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'COUNTUNIQUE',\r\n 't': 0,\r\n 'd': '计算一列指定值和范围中不重复数值的个数。',\r\n 'a': '计算一列指定值和范围中不重复数值的个数。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '要检查其是否唯一的第一个值或范围。',\r\n 'example': 'A1:C100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 要检查是否唯一的其他值或范围。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DEGREES',\r\n 't': 0,\r\n 'd': '将以弧度表示的角度值转换为度。',\r\n 'a': '将以弧度表示的角度值转换为度。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '角度',\r\n 'detail': '要从弧度转换为度的角度。',\r\n 'example': 'PI()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ERFC',\r\n 't': 9,\r\n 'd': '返回数值的互补高斯误差函数。',\r\n 'a': '返回数值的互补高斯误差函数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'z',\r\n 'detail': '要为其计算互补高斯误差函数的数值。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EVEN',\r\n 't': 0,\r\n 'd': '将数值向上取整为最接近的偶整数。',\r\n 'a': '将数值向上取整为最接近的偶整数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要向上取整的数值,取整值为大于此值的最接近的偶数。\\n\\n如果值为负数,则将其取整为绝对值大于该值的相邻负偶数。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EXP',\r\n 't': 0,\r\n 'd': '返回欧拉数 e (~2.718) 的指定次幂。',\r\n 'a': '返回欧拉数 e (~2.718) 的指定次幂。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '指数',\r\n 'detail': '指定e的自乘幂次值。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FACT',\r\n 't': 0,\r\n 'd': '返回数值的阶乘。',\r\n 'a': '返回数值的阶乘。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算并返回其阶乘的数字或对数字(所在单元格)的引用。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FACTDOUBLE',\r\n 't': 0,\r\n 'd': '返回数值的“双阶乘”。',\r\n 'a': '返回数值的“双阶乘”。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算并返回其双阶乘的数字或对数字(所在单元格)的引用。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PI',\r\n 't': 0,\r\n 'd': '返回带有14位小数的 PI 值。',\r\n 'a': '返回带有14位小数的 PI 值。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'FLOOR',\r\n 't': 0,\r\n 'd': '将数值向下取整为指定因数的最接近的整数倍。',\r\n 'a': '将数值向下取整为指定因数的最接近的整数倍。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要向下舍入为因数的最接近整数倍的数值。',\r\n 'example': '23.25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '因数',\r\n 'detail': '要将值舍入到此数的整数倍。\\n\\n因数不得为0。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GCD',\r\n 't': 0,\r\n 'd': '返回一个或多个整数的最大公约数。',\r\n 'a': '返回一个或多个整数的最大公约数。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '要在查找最大公约数的计算中检查其因数的第一项数值或范围。',\r\n 'example': 'A2:A5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 在求最大公约数时要考虑其因数的其他数值或范围。',\r\n 'example': '96',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANDBETWEEN',\r\n 't': 0,\r\n 'd': '返回介于两个整数之间(包括这两个整数)的随机数。',\r\n 'a': '返回介于两个整数之间(包括这两个整数)的随机数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '下界',\r\n 'detail': '随机值范围的下界。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '上界',\r\n 'detail': '随机值范围的上界。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ROUND',\r\n 't': 0,\r\n 'd': '将数字四舍五入到指定的位数。',\r\n 'a': '将数字四舍五入到指定的位数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要四舍五入的数字。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '位数',\r\n 'detail': '要进行四舍五入运算的位数。\\n\\n位数可以取负值,在这种情况下会将值的小数点左侧部分舍入到指定的位数。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ROUNDDOWN',\r\n 't': 0,\r\n 'd': '朝着零的方向将数字进行向下舍入。',\r\n 'a': '朝着零的方向将数字进行向下舍入。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '需要向下舍入的任意实数。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '位数',\r\n 'detail': '要通过舍入达到的小数位数。\\n\\n位数可以取负值,在这种情况下会将值的小数点左侧部分舍入到指定的位数。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ROUNDUP',\r\n 't': 0,\r\n 'd': '朝着远离 0(零)的方向将数字进行向上舍入。',\r\n 'a': '朝着远离 0(零)的方向将数字进行向上舍入。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要将其舍入为位数位数字的值,始终向上舍入。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '位数',\r\n 'detail': '要通过舍入达到的小数位数。\\n\\n位数可以取负值,在这种情况下会将值的小数点左侧部分舍入到指定的位数。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SERIESSUM',\r\n 't': 0,\r\n 'd': '给定参数 x、n、m 和 a,返回幂级数的和 a1xn + a2x(n+m) + ... + aix(n+(i-1)m),其中 i 为范围 a 中的项数。',\r\n 'a': '给定参数 x、n、m 和 a',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '幂级数的输入值。随相应的近似类型而变,有可能为角度、指数或其他一些值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'n',\r\n 'detail': '在幂级数中x的初始自乘幂次。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'm',\r\n 'detail': 'x的幂次中的附加增量。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'a',\r\n 'detail': '包含幂级数系数的数组或范围。',\r\n 'example': '{FACT(0)',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SIGN',\r\n 't': 0,\r\n 'd': '给定输入数值,如果为负返回-1;如果为正返回1;如果为零则返回0。',\r\n 'a': '给定输入数值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要返回其符号的数值。',\r\n 'example': '-42',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SIN',\r\n 't': 0,\r\n 'd': '给定角度(以弧度表示),返回其正弦值。',\r\n 'a': '给定角度(以弧度表示)',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '角度',\r\n 'detail': '要返回其正弦值的角度,以弧度表示。',\r\n 'example': 'PI()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SINH',\r\n 't': 0,\r\n 'd': '返回给定实数的双曲正弦值。',\r\n 'a': '返回给定实数的双曲正弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其双曲正弦值的实数值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SQRT',\r\n 't': 0,\r\n 'd': '返回一个正数的正平方根。',\r\n 'a': '返回一个正数的正平方根。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要计算其正平方根的数值。\\n\\n值必须为正数;如果为负,SQRT 将返回 #NUM! 错误。',\r\n 'example': '9',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SQRTPI',\r\n 't': 0,\r\n 'd': '返回 PI 与给定正数乘积的正平方根。',\r\n 'a': '返回 PI 与给定正数乘积的正平方根。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要将其与 PI 相乘并返回该乘积的平方根的数值\\n\\n值必须为正数;如果为负数,SQRTPI 将返回 #NUM! 错误。',\r\n 'example': '9',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GAMMALN',\r\n 't': 1,\r\n 'd': '返回指定伽玛函数的以 e(欧拉数)为底的对数。',\r\n 'a': '返回指定伽玛函数的以 e(欧拉数)为底的对数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '伽玛函数的输入值。返回的将是伽玛 (值) 的自然对数。\\n\\n值必须为正数。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COS',\r\n 't': 0,\r\n 'd': '返回给定角度的余弦值(角度以弧度表示)。',\r\n 'a': '返回给定角度的余弦值(角度以弧度表示)。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '角度',\r\n 'detail': '要取其余弦值的角度,以弧度表示。',\r\n 'example': 'PI()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TRUNC',\r\n 't': 0,\r\n 'd': '截除指定有效位之外的部分,取数据的指定有效位。',\r\n 'a': '截除指定有效位之外的部分',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': '值',\r\n 'detail': '要截取的数据。',\r\n 'example': '3.141592654',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '位数',\r\n 'detail': '[可选 - 默认值为0] - 小数点右侧要保留的有效位数。\\n\\n如果位数大于值中的有效位数,则将“值”原样返回。\\n\\n位数可以取负值,在这种情况下会将小数点左侧指定位数的值更改为零。小数点右侧的所有位数都会被舍弃。如果值的所有位都被更改为零,则TRUNC会返回0。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'QUOTIENT',\r\n 't': 0,\r\n 'd': '返回以一个数除以另一个数所得的结果,不包含余数。',\r\n 'a': '返回以一个数除以另一个数所得的结果',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '被除数',\r\n 'detail': '要被除的数值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '除数',\r\n 'detail': '用于除其他数的数值。\\n\\n除数不得为0。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'POWER',\r\n 't': 0,\r\n 'd': '返回数值的指定次幂。',\r\n 'a': '返回数值的指定次幂。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '底数',\r\n 'detail': '要计算其指数次幂的数值。\\n\\n如果底数为负,则指数必须为整数。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '指数',\r\n 'detail': '指定底数的自乘幂次值。',\r\n 'example': '0.5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMIFS',\r\n 't': 0,\r\n 'd': '根据多项条件返回范围之和。',\r\n 'a': '根据多项条件返回范围之和。',\r\n 'm': [3, 257],\r\n 'p': [{\r\n 'name': '求和范围',\r\n 'detail': '要对其求和的范围。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': '条件范围1',\r\n 'detail': '要在哪个范围内检查条件1。',\r\n 'example': ' B1:B10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': '条件1',\r\n 'detail': '要应用于条件范围1的模式或测试条件。',\r\n 'example': ' \">20\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '条件范围2, 条件2...',\r\n 'detail': '[ 可选 ] - 要检查的其他范围和条件。',\r\n 'example': ' C1:C10',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COUNTIFS',\r\n 't': 1,\r\n 'd': '根据多项条件返回范围中的单元格数量。',\r\n 'a': '根据多项条件返回范围中的单元格数量。',\r\n 'm': [2, 256],\r\n 'p': [{\r\n 'name': '条件范围1',\r\n 'detail': '要在哪个范围内检查条件1。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': '条件1',\r\n 'detail': '要应用于条件范围1的模式或测试条件。',\r\n 'example': ' \">20\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '条件范围2, 条件2...',\r\n 'detail': '[ 可选 ] - 要检查的其他范围和条件,可重复。',\r\n 'example': ' B1:B10',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PRODUCT',\r\n 't': 0,\r\n 'd': '返回将一组数相乘所得的结果。',\r\n 'a': '返回将一组数相乘所得的结果。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '乘数1',\r\n 'detail': '用于计算乘积的第一个数值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '乘数2 ... 乘数30',\r\n 'detail': '[可选] - 要相乘的其他数值。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HARMEAN',\r\n 't': 1,\r\n 'd': '计算数据集的调和平均值。',\r\n 'a': '计算数据集的调和平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 数据集中包含的其他数值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HYPGEOMDIST',\r\n 't': 1,\r\n 'd': '返回超几何分布。 如果已知样本量、总体成功次数和总体大小,则 HYPGEOM.DIST 返回样本取得已知成功次数的概率。',\r\n 'a': '返回超几何分布。',\r\n 'm': [5, 5],\r\n 'p': [{\r\n 'name': 'Sample_s',\r\n 'detail': '样本中成功的次数。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'Number_sample',\r\n 'detail': '样本量。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'Population_s',\r\n 'detail': '总体中成功的次数。',\r\n 'example': '20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'Number_pop',\r\n 'detail': '总体大小。',\r\n 'example': '40',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '决定函数形式的逻辑值。\\n\\n如果 cumulative 为 TRUE(),则 HYPGEOM.DIST 返回累积分布函数;\\n\\n如果为 FALSE(),则返回概率密度函数。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'INTERCEPT',\r\n 't': 1,\r\n 'd': '计算数据集的线性回归方程直线与 Y 轴的相交点 (x=0) 的 y 值。',\r\n 'a': '计算数据集的线性回归方程直线与 Y 轴的相交点 (x=0) 的 y 值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'KURT',\r\n 't': 1,\r\n 'd': '计算数据集的峭度,该指标指示数据集(分布)的形态,尤其是该形态的陡峭程度。',\r\n 'a': '计算数据集的峭度',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '数据集中的第一个值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 数据集中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LARGE',\r\n 't': 1,\r\n 'd': '返回数据集中第 n 个最大元素,n 由用户指定。',\r\n 'a': '返回数据集中第 n 个最大元素',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据',\r\n 'detail': '包含相关数据集的数组或范围。',\r\n 'example': 'A2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'n',\r\n 'detail': '要返回的元素的排行位置(从大到小顺序)。\\n\\n例如,将n设为4将使LARGE返回数据中排名第4的最大元素。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STDEVA',\r\n 't': 1,\r\n 'd': '基于样本计算标准偏差,将文本取值为0。',\r\n 'a': '基于样本计算标准偏差',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2,…',\r\n 'detail': '[可选] - 样本中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STDEVP',\r\n 't': 1,\r\n 'd': '基于样本总体计算标准偏差。',\r\n 'a': '基于样本总体计算标准偏差。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '数据集中的第一个值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 数据集中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GEOMEAN',\r\n 't': 1,\r\n 'd': '计算数据集的几何平均值。',\r\n 'a': '计算数据集的几何平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 数据集中包含的其他数值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANK_EQ',\r\n 't': 1,\r\n 'd': '返回指定值在数据集中的排名。如果相同的值在数据集中存在多项,则返回其中的最高排名。',\r\n 'a': '返回指定值在数据集中的排名。如果相同的值在数据集中存在多项,则返回其中的最高排名。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要确定其排名的值。',\r\n 'example': 'A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'ref',\r\n 'detail': '包含相关数据集的数组或范围。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'order',\r\n 'detail': '[可选 - 默认为按降序 (FALSE()) ] - 要按升序还是按降序考虑“data”中的值。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANK_AVG',\r\n 't': 1,\r\n 'd': '返回指定值在数据集中的排名。如果相同的值在数据集中存在多项,则返回这些项排名的平均值。',\r\n 'a': '返回指定值在数据集中的排名。如果相同的值在数据集中存在多项,则返回这些项排名的平均值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要确定其排名的值。',\r\n 'example': 'A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'ref',\r\n 'detail': '包含相关数据集的数组或范围。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'order',\r\n 'detail': '[可选 - 默认为按降序 (FALSE()) ] - 要按升序还是按降序考虑“data”中的值。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PERCENTRANK_EXC',\r\n 't': 1,\r\n 'd': '以百分数形式返回指定值在给定数据集中的百分比排名(介于0和1之间,不包括两端值)。',\r\n 'a': '以百分数形式返回指定值在给定数据集中的百分比排名(介于0和1之间,不包括两端值)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'data',\r\n 'detail': '包含相关数据集的数组或范围。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'x',\r\n 'detail': '要确定其百分比排位的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'significance',\r\n 'detail': '[可选 - 默认值为 3] - 要在计算中使用的有效位数。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PERCENTRANK_INC',\r\n 't': 1,\r\n 'd': '以百分比形式返回指定值在给定数据集中的百分比排名(介于0和1之间,包括两端值)。',\r\n 'a': '以百分比形式返回指定值在给定数据集中的百分比排名(介于0和1之间,包括两端值)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'data',\r\n 'detail': '包含相关数据集的数组或范围。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'x',\r\n 'detail': '要确定其百分比排位的值。',\r\n 'example': ' A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'significance',\r\n 'detail': '[可选 - 默认值为 3] - 要在计算中使用的有效位数。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FORECAST',\r\n 't': 1,\r\n 'd': '基于数据集的线性回归,计算指定 x 的预期 y 值。',\r\n 'a': '基于数据集的线性回归',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': 'x轴上用于预测的值。',\r\n 'example': 'A1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FISHERINV',\r\n 't': 1,\r\n 'd': '返回指定数值的 Fisher 逆变换。',\r\n 'a': '返回指定数值的 Fisher 逆变换。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'y',\r\n 'detail': '要计算其Fisher逆变换的数值。',\r\n 'example': '0.962',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FISHER',\r\n 't': 1,\r\n 'd': '返回指定数值的 Fisher 变换。',\r\n 'a': '返回指定数值的 Fisher 变换。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '要计算其Fisher变换的数值。',\r\n 'example': '0.962',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MODE_SNGL',\r\n 't': 1,\r\n 'd': '返回数据集中出现次数最多的值。',\r\n 'a': '返回数据集中出现次数最多的值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算模式时要检查的第一个值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 在计算模式时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'WEIBULL_DIST',\r\n 't': 1,\r\n 'd': '给定形状和尺度,返回韦伯分布函数(或韦伯累积分布函数)的值。',\r\n 'a': '给定形状和尺度',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': 'WEIBULL 分布函数的输入值。',\r\n 'example': '2.4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'alpha',\r\n 'detail': 'Weibull 分布函数的形状参数。\\n\\nalpha 值必须大于 0。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'beta',\r\n 'detail': 'Weibull 分布函数的尺度参数。\\n\\nbeta 值必须大于 0。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': 'TRUE() 表示使用累积分布函数,FALSE() 则表示使用概率密度函数。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COUNT',\r\n 't': 1,\r\n 'd': '返回数据集中数值的个数。',\r\n 'a': '返回数据集中数值的个数。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计数时要检查的第一个值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 在计数时要检查的其他值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COUNTA',\r\n 't': 1,\r\n 'd': '返回数据集中值的数量。',\r\n 'a': '返回数据集中值的数量。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计数时要检查的第一个值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 在计数时要检查的其他值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVEDEV',\r\n 't': 1,\r\n 'd': '计算数据与数据集均值之间的偏差大小的平均值。',\r\n 'a': '计算数据与数据集均值之间的偏差大小的平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 样本中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'AVERAGE',\r\n 't': 1,\r\n 'd': '返回数据集的算术平均值,对文本忽略不计。',\r\n 'a': '返回数据集的算术平均值',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算平均值时用到的第一个数值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 在计算平均值时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVERAGEA',\r\n 't': 1,\r\n 'd': '返回数据集的算术平均值。',\r\n 'a': '返回数据集的算术平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算平均值时用到的第一个数值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 在计算平均值时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'BINOM_DIST',\r\n 't': 1,\r\n 'd': '返回一元二项式分布的概率。',\r\n 'a': '返回一元二项式分布的概率。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'number_s',\r\n 'detail': '试验的成功次数。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'trials',\r\n 'detail': '独立检验的次数。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'probability_s',\r\n 'detail': '任一给定检验的成功概率。',\r\n 'example': '0.005',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '是否使用二项式累积分布。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'BINOM_INV',\r\n 't': 1,\r\n 'd': '计算累积二项式分布大于或等于指定条件的最小值。',\r\n 'a': '计算累积二项式分布大于或等于指定条件的最小值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'trials',\r\n 'detail': '贝努利试验次数。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'probability_s',\r\n 'detail': '任一次给定检验的成功概率。',\r\n 'example': '0.005',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'alpha',\r\n 'detail': '期望的临界概率。',\r\n 'example': '0.8',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CONFIDENCE_NORM',\r\n 't': 1,\r\n 'd': '计算正态分布的置信区间的一半宽度。',\r\n 'a': '计算正态分布的置信区间的一半宽度。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'alpha',\r\n 'detail': '用来计算置信水平的显著性水平。\\n\\n置信水平等于 100*(1 - alpha)%,亦即,如果 alpha 为 0.05,则置信水平为 95%。',\r\n 'example': '0.05',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'standard_dev',\r\n 'detail': '数据区域的总体标准偏差。',\r\n 'example': '1.6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'size',\r\n 'detail': '样本总量的大小。',\r\n 'example': '250',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CORREL',\r\n 't': 1,\r\n 'd': '计算给定数据集的皮尔逊积矩相关系数 r。',\r\n 'a': '计算给定数据集的皮尔逊积矩相关系数 r。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COVARIANCE_P',\r\n 't': 1,\r\n 'd': '计算数据集的总体协方差。',\r\n 'a': '计算数据集的总体协方差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COVARIANCE_S',\r\n 't': 1,\r\n 'd': '计算数据集的样本协方差。',\r\n 'a': '计算数据集的样本协方差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEVSQ',\r\n 't': 1,\r\n 'd': '基于样本计算其偏差的平方和。',\r\n 'a': '基于样本计算其偏差的平方和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 样本中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EXPON_DIST',\r\n 't': 1,\r\n 'd': '返回带有指定 Lambda 和指定值的指数分布函数的值。',\r\n 'a': '返回带有指定 Lambda 和指定值的指数分布函数的值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '指数分布函数的输入值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'lambda',\r\n 'detail': '用于指定指数分布函数的 lambda 值。',\r\n 'example': '0.5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '是否使用指数累积分布。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVERAGEIF',\r\n 't': 1,\r\n 'd': '根据条件返回范围的平均值。',\r\n 'a': '根据条件返回范围的平均值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'criteria_range',\r\n 'detail': '要对其检查 criterion 的范围。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criterion',\r\n 'detail': '要应用于 criteria_range 的模式或测试条件。\\n\\n等于:\"文本\" 或 1 或 \"=文本\" 或 \"=1\"\\n\\n大于:\">1\"\\n\\n大于等于:\">=1\"\\n\\n小于:\"<1\"\\n\\n小于等于:\"<=1\"\\n\\n不等于:\"<>1\"或\"<>文本\"',\r\n 'example': '\">20\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'average_range',\r\n 'detail': '[可选] - 要计算平均值的范围。如果未提供此参数,则改用 criteria_range 来计算平均值。',\r\n 'example': 'B1:B10',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVERAGEIFS',\r\n 't': 1,\r\n 'd': '根据多项条件返回范围的平均值。',\r\n 'a': '根据多项条件返回范围的平均值。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name': 'average_range',\r\n 'detail': '要计算平均值的范围。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria_range1',\r\n 'detail': '要对其检查 criterion1 的范围。',\r\n 'example': ' B1:B10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criterion1',\r\n 'detail': '要应用于 criteria_range1 的模式或测试条件。',\r\n 'example': ' \">20\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria_range2, criterion2, ...',\r\n 'detail': '[可选] - 要检查的其他范围和条件。',\r\n 'example': ' C1:C10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PERMUT',\r\n 't': 1,\r\n 'd': '返回可从数字对象中选择的给定数目对象的排列数。',\r\n 'a': '返回可从数字对象中选择的给定数目对象的排列数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '表示对象个数的整数。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'number_chosen',\r\n 'detail': '表示每个排列中对象个数的整数。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TRIMMEAN',\r\n 't': 1,\r\n 'd': '在排除数据集高低两端的部分数据之后计算所得的均值。',\r\n 'a': '在排除数据集高低两端的部分数据之后计算所得的均值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据',\r\n 'detail': '包含相关数据集的数组或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': '排除比例',\r\n 'detail': '要从数据集的极值部分排除的数据占数据集的比例。\\n\\n排除比例必须大于等于0且小于1。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PERCENTILE_EXC',\r\n 't': 1,\r\n 'd': '返回数组的 K 百分点值,K 介于 0 到 1 之间,不含 0 与 1。',\r\n 'a': '返回数组的 K 百分点值,K 介于 0 到 1 之间,不含 0 与 1。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '定义相对位置的数组或数据区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'k',\r\n 'detail': '0 到 1 之间的百分点值,不包含 0 和 1。',\r\n 'example': '0.25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PERCENTILE_INC',\r\n 't': 1,\r\n 'd': '返回数组的 K 百分点值,K 介于 0 到 1 之间,包含 0 与 1。',\r\n 'a': '返回数组的 K 百分点值,K 介于 0 到 1 之间,包含 0 与 1。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '定义相对位置的数组或数据区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'k',\r\n 'detail': '0 到 1 之间的百分点值,包含 0 和 1。',\r\n 'example': '0.25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PEARSON',\r\n 't': 1,\r\n 'd': '返回皮尔生(Pearson)乘积矩相关系数 r。',\r\n 'a': '返回皮尔生(Pearson)乘积矩相关系数 r。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NORM_S_INV',\r\n 't': 1,\r\n 'd': '返回标准正态累积分布函数的反函数值。 该分布的平均值为 0,标准偏差为 1。',\r\n 'a': '返回标准正态累积分布函数的反函数值。 该分布的平均值为 0,标准偏差为 1。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'probability',\r\n 'detail': '对应于正态分布的概率。',\r\n 'example': '0.75',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NORM_S_DIST',\r\n 't': 1,\r\n 'd': '返回标准正态分布函数(该分布的平均值为 0,标准偏差为 1)。',\r\n 'a': '返回标准正态分布函数(该分布的平均值为 0,标准偏差为 1)。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'z',\r\n 'detail': '需要计算其分布的数值。',\r\n 'example': '2.4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '决定函数形式的逻辑值。\\n\\n如果为 TRUE(),则返回累积分布函数;\\n\\n如果为 FALSE(),则返回概率密度函数。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NORM_INV',\r\n 't': 1,\r\n 'd': '返回指定平均值和标准偏差的正态累积分布函数的反函数值。',\r\n 'a': '返回指定平均值和标准偏差的正态累积分布函数的反函数值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'probability',\r\n 'detail': '对应于正态分布的概率。',\r\n 'example': '0.75',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'mean',\r\n 'detail': '分布的算术平均值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'standard_dev',\r\n 'detail': '分布的标准偏差。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NORM_DIST',\r\n 't': 1,\r\n 'd': '返回指定平均值和标准偏差的正态分布函数。',\r\n 'a': '返回指定平均值和标准偏差的正态分布函数。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '需要计算其分布的数值。',\r\n 'example': '2.4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'mean',\r\n 'detail': '分布的算术平均值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'standard_dev',\r\n 'detail': '分布的标准偏差。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '决定函数形式的逻辑值。\\n\\n如果为 TRUE(),则返回累积分布函数;\\n\\n如果为 FALSE(),则返回概率密度函数。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NEGBINOM_DIST',\r\n 't': 1,\r\n 'd': '返回负二项式分布。',\r\n 'a': '返回负二项式分布。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'number_f',\r\n 'detail': '要模拟的失败次数。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'number_s',\r\n 'detail': '要模拟的成功次数。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'probability_s',\r\n 'detail': '任一次给定检验的成功概率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '决定函数形式的逻辑值。\\n\\n如果为 TRUE(),则返回累积分布函数;\\n\\n如果为 FALSE(),则返回概率密度函数。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'MINA',\r\n 't': 1,\r\n 'd': '返回数据集中的最小数值。',\r\n 'a': '返回数据集中的最小数值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算最小值时所用的第一个值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 在计算最小值时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MIN',\r\n 't': 1,\r\n 'd': '返回数值数据集中的最小值。',\r\n 'a': '返回数值数据集中的最小值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算最小值时所用的第一个值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 在计算最小值时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MEDIAN',\r\n 't': 1,\r\n 'd': '返回数值数据集中的中值。',\r\n 'a': '返回数值数据集中的中值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算中值时所用的第一个数值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 在计算中值时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MAXA',\r\n 't': 1,\r\n 'd': '返回数据集中的最大数值。',\r\n 'a': '返回数据集中的最大数值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算最大值时所用的第一个值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 在计算最大值时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MAX',\r\n 't': 1,\r\n 'd': '返回数值数据集中的最大值。',\r\n 'a': '返回数值数据集中的最大值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '计算最大值时所用的第一个值或范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2',\r\n 'detail': '[可选] - 在计算最大值时要考虑的其他数值或范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOGNORM_INV',\r\n 't': 1,\r\n 'd': '返回 x 的对数累积分布函数的反函数值。',\r\n 'a': '返回 x 的对数累积分布函数的反函数值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'probability',\r\n 'detail': '与对数分布相关的概率,介于 0 与 1 之间(不含 0 与 1)。',\r\n 'example': '0.4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'mean',\r\n 'detail': 'ln(x) 的平均值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'standard_dev',\r\n 'detail': 'ln(x) 的标准偏差,正数。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOGNORM_DIST',\r\n 't': 1,\r\n 'd': '返回 x 的对数分布函数。',\r\n 'a': '返回 x 的对数分布函数。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '用来计算函数的值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'mean',\r\n 'detail': 'ln(x) 的平均值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'standard_dev',\r\n 'detail': 'ln(x) 的标准偏差,正数。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '决定函数形式的逻辑值。\\n\\n如果为 TRUE(),则返回累积分布函数;\\n\\n如果为 FALSE(),则返回概率密度函数。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'Z_TEST',\r\n 't': 1,\r\n 'd': '返回 z 检验的单尾 P 值。',\r\n 'a': '返回 z 检验的单尾 P 值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '用来检验 x 的数组或数据区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'x',\r\n 'detail': '要测试的值。',\r\n 'example': 'B2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'sigma',\r\n 'detail': '[可选] - 总体(已知)标准偏差。 如果省略,则使用样本标准偏差。',\r\n 'example': '3',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PROB',\r\n 't': 1,\r\n 'd': '返回区域中的数值落在指定区间内的概率。',\r\n 'a': '返回区域中的数值落在指定区间内的概率。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'x_range',\r\n 'detail': '具有各自相应概率值的 x 数值区域。',\r\n 'example': 'A3:A6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'prob_range',\r\n 'detail': '与 x_range 中的值相关联的一组概率值。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'lower_limit',\r\n 'detail': '要计算其概率的数值下界。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'upper_limit',\r\n 'detail': '[可选 - 默认值为下界] - 要计算其概率的可选数值上界。\\n\\n如果省略上界,PROB则计算随机选取相应值的次数恰好等于下界的概率。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'QUARTILE_EXC',\r\n 't': 1,\r\n 'd': '基于 0 到 1 之间(不包括 0 和 1)的百分点值返回数据集的四分位数。',\r\n 'a': '基于 0 到 1 之间(不包括 0 和 1)的百分点值返回数据集的四分位数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '要求得四分位数值的数组或数字型单元格区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'quart',\r\n 'detail': '要返回第几个四分位值。\\n\\n1返回数据中最靠近第一个四分位值的值(25%标记)。\\n\\n2返回数据中最接近中值的值(50%标记)。\\n\\n3返回数据中最接近第三个四分位值的值(75%标记)。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'QUARTILE_INC',\r\n 't': 1,\r\n 'd': '根据 0 到 1 之间的百分点值(包含 0 和 1)返回数据集的四分位数。',\r\n 'a': '根据 0 到 1 之间的百分点值(包含 0 和 1)返回数据集的四分位数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '要求得四分位数值的数组或数字型单元格区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'quart',\r\n 'detail': '要返回第几个四分位值。\\n\\n0返回数据中的最小值(0%标记)。\\n\\n1返回数据中最靠近第一个四分位值的值(25%标记)。\\n\\n2返回数据中最接近中值的值(50%标记)。\\n\\n3返回数据中最接近第三个四分位值的值(75%标记)。\\n\\n4返回数据中的最大值(100%标记)。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'POISSON_DIST',\r\n 't': 1,\r\n 'd': '返回泊松分布。',\r\n 'a': '返回泊松分布。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '事件数。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'mean',\r\n 'detail': '期望值。非负数',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '一逻辑值,确定所返回的概率分布的形式。\\n\\n如果为 TRUE(),则返回发生的随机事件数在零(含零)和 x(含 x)之间的累积泊松概率;\\n\\n如果为 FALSE(),则返回发生的事件数正好是 x 的泊松概率密度函数。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RSQ',\r\n 't': 1,\r\n 'd': '返回皮尔生(Pearson)乘积矩相关系数 r 的平方。',\r\n 'a': '返回皮尔生(Pearson)乘积矩相关系数 r 的平方。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_DIST',\r\n 't': 1,\r\n 'd': '返回学生的左尾 t 分布。',\r\n 'a': '返回学生的左尾 t 分布。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': 'T-分布函数的输入。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'degrees_freedom',\r\n 'detail': '自由度数值。',\r\n 'example': '30',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'tails',\r\n 'detail': '决定函数形式的逻辑值。\\n\\n如果 cumulative 为 TRUE(),则 HYPGEOM.DIST 返回累积分布函数;\\n\\n如果为 FALSE(),则返回概率密度函数。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'T_DIST_2T',\r\n 't': 1,\r\n 'd': '返回学生的双尾 t 分布。',\r\n 'a': '返回学生的双尾 t 分布。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': 'T-分布函数的输入。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'degrees_freedom',\r\n 'detail': '自由度数值。',\r\n 'example': '30',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_DIST_RT',\r\n 't': 1,\r\n 'd': '返回学生的右尾 t 分布。',\r\n 'a': '返回学生的右尾 t 分布。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': 'T-分布函数的输入。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'degrees_freedom',\r\n 'detail': '自由度数值。',\r\n 'example': '30',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_INV',\r\n 't': 1,\r\n 'd': '返回学生的 t 分布的左尾反函数。',\r\n 'a': '返回学生的 t 分布的左尾反函数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'probability',\r\n 'detail': '与学生的 t 分布相关的概率。\\n\\n必须大于 0 且小于 1。',\r\n 'example': '0.35',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'deg_freedom',\r\n 'detail': '自由度数值。\\n\\n如果所提供的参数不是整数,将截取其整数部分。\\n\\n必须大于等于 1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_INV_2T',\r\n 't': 1,\r\n 'd': '返回学生 t 分布的双尾反函数。',\r\n 'a': '返回学生 t 分布的双尾反函数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'probability',\r\n 'detail': '与学生的 t 分布相关的概率。\\n\\n必须大于 0 且小于1。',\r\n 'example': '0.35',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'deg_freedom',\r\n 'detail': '自由度数值。\\n\\n如果所提供的参数不是整数,将截取其整数部分。\\n\\n必须大于等于 1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_TEST',\r\n 't': 1,\r\n 'd': '返回与t-检验相关的概率。用于判断两个样本是否可能是出自平均值相同的两个样本总体。',\r\n 'a': '返回与t-检验相关的概率。用于判断两个样本是否可能是出自平均值相同的两个样本总体。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'array1',\r\n 'detail': '将用于 t 检验的第一个数据样本或第一组单元格。',\r\n 'example': 'A1:A4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'array2',\r\n 'detail': '将用于 t 检验的第二个数据样本或第二组单元格。',\r\n 'example': 'B1:B4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'tails',\r\n 'detail': '指定分布的尾数。\\n\\n如果为 1:使用单尾分布。\\n\\n如果为 2:使用双尾分布。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '指定 t 检验的类型。\\n\\n如果为 1:执行配对检验。\\n\\n如果为 2:执行双样本等方差(同方差)检验。\\n\\n如果为3:执行双样本不等方差(异方差)检验。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'F_DIST',\r\n 't': 1,\r\n 'd': '给定输入值 x,计算两个数据集的左尾 F 概率分布(差异程度)。此分布也称为 Fisher-Snedecor 分布或 Snedecor F 分布。',\r\n 'a': '给定输入值 x',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '用来计算函数的值。',\r\n 'example': '15.35',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'degrees_freedom1',\r\n 'detail': '分子自由度。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'degrees_freedom2',\r\n 'detail': '分母自由度。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cumulative',\r\n 'detail': '用于确定函数形式的逻辑值。默认值为 FALSE。\\n\\n如果为 TRUE():F.DIST 将返回累积分布函数值。\\n\\n如果为 FALSE():F.DIST 将返回概率密度函数值。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'F_DIST_RT',\r\n 't': 1,\r\n 'd': '给定输入x,计算两个数据集的右尾F概率分布(差异程度)。 此分布也称为Fisher-Snedecor分布或Snedecor F分布。',\r\n 'a': '给定输入x',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '用来计算函数的值。',\r\n 'example': '15.35',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'degrees_freedom1',\r\n 'detail': '分子自由度。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'degrees_freedom2',\r\n 'detail': '分母自由度。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VAR_P',\r\n 't': 1,\r\n 'd': '基于样本总体计算方差。',\r\n 'a': '基于样本总体计算方差。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '数据集中的第一个值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, …',\r\n 'detail': '[可选] - 数据集中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VAR_S',\r\n 't': 1,\r\n 'd': '基于样本计算方差。',\r\n 'a': '基于样本计算方差。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, …',\r\n 'detail': '[可选] - 样本中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VARA',\r\n 't': 1,\r\n 'd': '基于样本计算方差,将文本取值为0。',\r\n 'a': '基于样本计算方差',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'value2, ...',\r\n 'detail': '[可选] - 样本中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VARPA',\r\n 't': 1,\r\n 'd': '基于样本总体计算方差,将文本取值为0。',\r\n 'a': '基于样本总体计算方差',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '样本中的第一项值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 数据集中包含的其他数值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STEYX',\r\n 't': 1,\r\n 'd': '返回通过线性回归法预测每个 x 的 y 值时所产生的标准误差。',\r\n 'a': '返回通过线性回归法预测每个 x 的 y 值时所产生的标准误差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STANDARDIZE',\r\n 't': 1,\r\n 'd': '给定分布的均值和标准偏差,计算一个随机变量正态化的相应值。',\r\n 'a': '给定分布的均值和标准偏差,计算一个随机变量正态化的相应值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'x',\r\n 'detail': '要正态化的随机变量值。',\r\n 'example': '96',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'mean',\r\n 'detail': '分布的均值。',\r\n 'example': '80',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'standard_dev',\r\n 'detail': '分布的标准偏差。',\r\n 'example': '6.7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SMALL',\r\n 't': 1,\r\n 'd': '返回数据集中的第 k 个最小值。',\r\n 'a': '返回数据集中的第 k 个最小值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '需要找到第 k 个最小值的数组或数值数据区域。',\r\n 'example': 'A2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'k',\r\n 'detail': '要返回的数据在数组或数据区域里的位置(从小到大)。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SLOPE',\r\n 't': 1,\r\n 'd': '计算通过数据集的线性回归得到的直线的斜率。',\r\n 'a': '计算通过数据集的线性回归得到的直线的斜率。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': '数据_y',\r\n 'detail': '代表因变量数据数组或矩阵的范围。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '数据_x',\r\n 'detail': '代表自变量数据数组或矩阵的范围。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SKEW',\r\n 't': 1,\r\n 'd': '返回分布的偏斜度。 偏斜度表明分布相对于平均值的不对称程度。 正偏斜度表明分布的不对称尾部趋向于更多正值。 负偏斜度表明分布的不对称尾部趋向于更多负值。',\r\n 'a': '返回分布的偏斜度。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '数据集中的第一个值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 数据集中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'SKEW_P',\r\n 't': 1,\r\n 'd': '返回基于样本总体的分布不对称度:表明分布相对于平均值的不对称程度。',\r\n 'a': '返回基于样本总体的分布不对称度:表明分布相对于平均值的不对称程度。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': '值1',\r\n 'detail': '数据集中的第一个值或范围。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '值2, ...',\r\n 'detail': '[可选] - 数据集中包含的其他值或范围。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'VLOOKUP',\r\n 't': 2,\r\n 'd': '纵向查找。在范围的第一列中自上而下搜索某个键值,并返回所找到的行中指定单元格的值。',\r\n 'a': '纵向查找。在范围的第一列中自上而下搜索某个键值',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': '搜索键值',\r\n 'detail': '要搜索的值,如 42、\"Cats\" 或 I24。',\r\n 'example': '10003',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '范围',\r\n 'detail': '要进行搜索的范围。VLOOKUP 将在该范围的第一列中搜索搜索键值中指定的键值。',\r\n 'example': 'A2:B26',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '索引',\r\n 'detail': '要返回的值的列索引,范围中的第一列编号为 1。\\n\\n如果索引不是介于 1 和范围中的列数之间,将返回 #VALUE! 。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '已排序',\r\n 'detail': '[默认值为 TRUE() ] - 指示要搜索的列(指定范围的第一列)是否已排序。大多数情况下,建议设为 FALSE()。\\n\\n建议将已排序设为 FALSE。如果设为 FALSE,将返回完全匹配项。如果存在多个匹配值,将返回找到的第一个值对应的单元格的内容,如果找不到匹配值,则返回 #N/A。\\n\\n如果将已排序设为 TRUE 或省略,将返回(小于或等于搜索键值的)最接近的匹配项。如果搜索的列中所有的值均大于搜索键值,则返回 #N/A。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HLOOKUP',\r\n 't': 2,\r\n 'd': '横向查找。在范围的第一行中搜索某个键值,并返回所找到的列中指定单元格的值。',\r\n 'a': '横向查找。在范围的第一行中搜索某个键值',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': '搜索键值',\r\n 'detail': '要搜索的值。例如,42、\"Cats\"或I24。',\r\n 'example': '10003',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '范围',\r\n 'detail': '要进行搜索的范围。将在该范围的第一行中搜索在搜索键值中指定的键值。',\r\n 'example': 'A2:Z6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '索引',\r\n 'detail': '要返回的值的行索引,范围中的第一行编号为1。\\n\\n如果索引不是介于1和范围中的行数之间,将返回#VALUE!。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '已排序',\r\n 'detail': '[可选 - 默认值为TRUE()] - 指示要搜索的行(指定范围的第一行)是否已排序。\\n\\n如果将已排序设为TRUE或省略,将返回最接近的匹配值(小于或等于搜索键值)。如果在搜索的行中所有的值均大于搜索键值,则返回#N/A。\\n\\n如果将已排序设为TRUE或将其省略,而范围的首行并非处于已排序状态,则返回值可能会是错误的。\\n\\n如果将已排序设为FALSE,则仅返回完全匹配。如果存在多个匹配值,将返回与找到的第一个值对应的单元格的内容,如果找不到匹配值则返回#N/A。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LOOKUP',\r\n 't': 2,\r\n 'd': '在行或列中查找相应键,并将相应单元格的值返回到与搜索行或列所在位置相同的结果范围中。',\r\n 'a': '在行或列中查找相应键',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': '搜索键值',\r\n 'detail': '要在行或列中搜索的值。例如,42、\"Cats\" 或 I24。',\r\n 'example': '10003',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '搜索范围 | 搜索结果数组',\r\n 'detail': '使用 LOOKUP 的一种方法是给定单行或单列形式的搜索范围进行搜索查找,这种方式要用到另一个参数结果范围。另一种方式是将这两个参数合并为一个搜索结果数组,其中第一行或第一列用于搜索,并将返回值放在该数组的最后一行或最后一列中。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '结果范围',\r\n 'detail': '[ 可选 ] - 用于存放返回结果的范围。返回值对应于在搜索范围中找到搜索键值的位置。此范围必须仅为单行或单列,而如果您使用的是搜索结果数组方式,则不应提供此参数。',\r\n 'example': 'B1:B100',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ADDRESS',\r\n 't': 2,\r\n 'd': '返回字符串形式的单元格引用。',\r\n 'a': '返回字符串形式的单元格引用。',\r\n 'm': [2, 5],\r\n 'p': [{\r\n 'name': 'row_num',\r\n 'detail': '一个数值,指定要在单元格引用中使用的行号。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'column_num',\r\n 'detail': '一个数值,指定要在单元格引用中使用的列号(而非名称)。A列的编号为1。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'abs_num',\r\n 'detail': '[可选 - 默认值为1] - 一个数值,指定要返回的引用类型。\\n\\n1 表示行列均采用绝对值(例如$A$1);\\n\\n2 表示采用绝对行号,相对列标(例如A$1);\\n\\n3 表示采用相对行号,绝对列标(例如$A1);\\n\\n4 表示行列均采用相对值(例如A1)。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'A1',\r\n 'detail': '[可选 - 默认值为TRUE()] - 一个布尔值,指示采用A1标记形式(TRUE)还是R1C1标记形式(FALSE)。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'sheet_text',\r\n 'detail': '[可选 - 默认缺省] - 用于指定地址所指向的工作表名称。',\r\n 'example': '\"Sheet2\"',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'INDIRECT',\r\n 't': 2,\r\n 'd': '返回以字符串指定的单元格引用。',\r\n 'a': '返回以字符串指定的单元格引用。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'ref_text',\r\n 'detail': '以带引号的字符串形式提供的单元格引用。',\r\n 'example': '\"Sheet2!\"&B10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'A1',\r\n 'detail': '[可选 - 默认值为TRUE()] - 一个布尔值,指示采用A1标记形式(TRUE)还是R1C1标记形式(FALSE)。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ROW',\r\n 't': 2,\r\n 'd': '返回指定单元格的行号',\r\n 'a': '返回指定单元格的行号',\r\n 'm': [0, 1],\r\n 'p': [{\r\n 'name': 'reference',\r\n 'detail': '[可选 - 默认为此公式所在的单元格] - 要返回其行号的单元格。\\n\\n如果单元格引用指向的范围其宽度大于一个单元格,而此公式不是用作数组公式的,这时会仅返回单元格引用中首行的编号值。',\r\n 'example': 'A9',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ROWS',\r\n 't': 2,\r\n 'd': '返回指定数组或范围中的行数。',\r\n 'a': '返回指定数组或范围中的行数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '要返回其行数的范围。',\r\n 'example': 'A9:A62',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COLUMN',\r\n 't': 2,\r\n 'd': '按照 `A=1` 的规则返回指定单元格的列号。',\r\n 'a': '按照 `A=1` 的规则返回指定单元格的列号。',\r\n 'm': [0, 1],\r\n 'p': [{\r\n 'name': 'reference',\r\n 'detail': '[可选 - 默认为包含此公式的单元格] - 要返回其列号的单元格。A列对应的编号为1。\\n\\n如果单元格引用是宽度超过一个单元格的范围,而此公式不是作为数组公式来使用的,因此将返回单元格引用中的第一列的位置。',\r\n 'example': 'A9',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COLUMNS',\r\n 't': 2,\r\n 'd': '返回指定数组或范围中的列数。',\r\n 'a': '返回指定数组或范围中的列数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '要返回其列数的范围。',\r\n 'example': 'A9:W62',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'OFFSET',\r\n 't': 2,\r\n 'd': '给定某范围的起始单元格引用以及该范围涵盖的行列数量,返回该范围的引用。',\r\n 'a': '给定某范围的起始单元格引用以及该范围涵盖的行列数量,返回该范围的引用。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name': 'reference',\r\n 'detail': '用于计算行列偏移量的起点。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'rows',\r\n 'detail': '要偏移的行数。\\n\\n行偏移量必须是整数,但也可以是负数。如果提供的参数带有小数,小数部分将被截去。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cols',\r\n 'detail': '要偏移的列数。\\n\\n列偏移量必须是整数,但也可以是负数。如果提供的参数带有小数,小数部分将被截去。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'height',\r\n 'detail': '[可选] - 要从偏移目标开始返回的范围的高度。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'width',\r\n 'detail': '[可选] - 要从偏移目标开始返回的范围的宽度。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MATCH',\r\n 't': 2,\r\n 'd': '在单元格中搜索指定项,然后返回该项在单元格区域中的相对位置。',\r\n 'a': '在单元格中搜索指定项,然后返回该项在单元格区域中的相对位置。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'lookup_value',\r\n 'detail': '要在 lookup_array 中匹配的值。',\r\n 'example': '\"Sunday\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'lookup_array',\r\n 'detail': '要搜索的单元格区域。\\n\\n如果所用的范围的高度和宽度均大于1,MATCH将返回#N/A!。',\r\n 'example': 'A2:A9',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'match_type',\r\n 'detail': '[可选 - 默认值为1] - 要采用的搜索方式。\\n\\n1为默认类型,此时MATCH会假设范围已按升序排序,并返回小于等于搜索键值的最大值。\\n\\n0表示完全匹配,在范围未排序的情况下需要使用此方式。\\n\\n-1让MATCH假设范围是按降序排序的,并返回大于等于搜索键值的最小值。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'INDEX',\r\n 't': 2,\r\n 'd': '返回表格或中的元素值,此元素由行号和列号的索引值给定。',\r\n 'a': '返回表格或中的元素值,此元素由行号和列号的索引值给定。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '单元格区域或数组常量。',\r\n 'example': 'A1:C20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'row_num',\r\n 'detail': '选择数组中的某行,函数从该行返回数值。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'column_num',\r\n 'detail': '选择数组中的某列,函数从该列返回数值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GETPIVOTDATA',\r\n 't': 2,\r\n 'd': '从与指定行和列标题对应的数据透视表中提取汇总值。',\r\n 'a': '从与指定行和列标题对应的数据透视表中提取汇总值。',\r\n 'm': [2, 254],\r\n 'p': [{\r\n 'name': 'data_field',\r\n 'detail': '您想从数据透视表中获取其数据的值名称。\\n值名称必须括在引号中或是指向包含相关文本的任何单元格的引用。\\n如果有多个值字段,则必须使用数据透视表中显示的确切名称(如“销售总额”)。',\r\n 'example': '\"SUM of number of units\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'pivot_table',\r\n 'detail': '目标数据透视表中的任何单元格的引用(推荐位于顶角的单元格)。',\r\n 'example': \"'Pivot table'!A1\",\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'field1',\r\n 'detail': '[可选] - 源数据集(不是数据透视表)中列的名称。',\r\n 'example': '\"division\"',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'item1',\r\n 'detail': '[可选] - 数据透视表中显示的与您要检索的字段名称 1 相对应的行或列的名称。',\r\n 'example': '\"east\"',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CHOOSE',\r\n 't': 2,\r\n 'd': '基于索引返回选项列表中的元素。',\r\n 'a': '基于索引返回选项列表中的元素。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name': 'index_num',\r\n 'detail': '指定要返回哪一项。\\n\\n如果索引为零、负值或大于提供的选择数量,将返回#VALUE!错误。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'value1',\r\n 'detail': '一项可能的返回值。必须提供。可以是单元格引用或单独的值。',\r\n 'example': '\"A\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '[可选] - 其他可以选择的值。选择',\r\n 'example': '\"B\"',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HYPERLINK',\r\n 't': 2,\r\n 'd': '在单元格内创建一个超链接。',\r\n 'a': '在单元格内创建一个超链接。',\r\n 'p': [{\r\n 'name': '网址',\r\n 'detail': '以引号括住的链接位置的完整网址,或对包含这种网址的单元格的引用。\\n\\n仅允许某些链接类型。其中包括:http://、https://、mailto:、aim:、ftp://、gopher://、telnet://和news://,明确禁用使用其他协议。如果指定的是其他协议,将会在单元格中显示链接标签,但该标签不会以链接形式呈现。\\n\\n如果未指定协议,则假设使用http://,并将其作为网址的前缀。',\r\n 'example': '\"http://www.google.com/\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '链接标签',\r\n 'detail': '[可选 - 默认为网址] - 要在单元格中作为链接显示的文本(用引号括起来的),或者指向包含这种标签的单元格的引用。\\n\\n如果链接标签是指向某个空单元格的引用,如果网址有效,就将其作为链接显示,否则作为纯文本显示。\\n\\n如果链接标签为空字符串常量(\"\"),所在单元格显示的内容将为空白,但通过点击该单元格或转入该单元格仍然可以访问链接。',\r\n 'example': '\"Google\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TIME',\r\n 't': 6,\r\n 'd': '将给定的小时、分钟和秒转换为时间。',\r\n 'a': '将给定的小时、分钟和秒转换为时间。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': '小时',\r\n 'detail': '0(零)到 32767 之间的数字,代表小时。\\n\\n任何大于 23 的值都会除以 24,余数将作为小时值。',\r\n 'example': '11',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '分钟',\r\n 'detail': '0(零)到 32767 之间的数字,代表分钟。\\n\\n任何大于 59 的值将转换为小时和分钟。',\r\n 'example': '40',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': '秒',\r\n 'detail': '0(零)到 32767 之间的数字,代表秒。\\n\\n任何大于 59 的值将转换为小时、分钟和秒。',\r\n 'example': '59',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TIMEVALUE',\r\n 't': 6,\r\n 'd': '按一天24小时返回该时间的分数表示。',\r\n 'a': '按一天24小时返回该时间的分数表示。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'time_text',\r\n 'detail': '用于表示时间的字符串。',\r\n 'example': '\"2:15 PM\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EOMONTH',\r\n 't': 6,\r\n 'd': '返回某个月份最后一天的序列号,该月份在另一个日期之前或之后的数个月(月数由参数指定)。',\r\n 'a': '返回某个月份最后一天的序列号',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '用于计算结果的参照日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'months',\r\n 'detail': '用于计算的起始日期之前(负)或之后(正)的月数。返回的是计算所得月份的最后那天。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EDATE',\r\n 't': 6,\r\n 'd': '返回表示某个日期的序列号,该日期在另一个日期的数月之前/之后。',\r\n 'a': '返回表示某个日期的序列号',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '用于计算结果的参照日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'months',\r\n 'detail': '用于计算的起始日期之前(负)或之后(正)的月数。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SECOND',\r\n 't': 6,\r\n 'd': '返回时间值的秒数。 秒数是 0(零)到 59 范围内的整数。',\r\n 'a': '返回时间值的秒数。 秒数是 0(零)到 59 范围内的整数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '时间',\r\n 'detail': '用于计算秒钟部分的时间。必须为以下值之一:指向包含日期/时间值的单元格的引用、返回日期/时间的函数或者数字。',\r\n 'example': 'TIME(11',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'MINUTE',\r\n 't': 6,\r\n 'd': '以数字格式返回特定时间的分钟部分。',\r\n 'a': '以数字格式返回特定时间的分钟部分。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '时间',\r\n 'detail': '用于计算分钟部分的时间。必须为以下值之一:指向包含日期/时间值的单元格的引用、返回日期/时间的函数或者数字。',\r\n 'example': 'TIME(11',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HOUR',\r\n 't': 6,\r\n 'd': '以数字格式返回特定时间的小时部分。',\r\n 'a': '以数字格式返回特定时间的小时部分。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': '时间',\r\n 'detail': '用于计算小时部分的时间。必须为以下值之一:指向包含日期/时间值的单元格的引用、返回日期/时间的函数或者数字。',\r\n 'example': 'TIME(11',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NOW',\r\n 't': 6,\r\n 'd': '以日期值格式返回当前日期和时间。',\r\n 'a': '以日期值格式返回当前日期和时间。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'NETWORKDAYS',\r\n 't': 6,\r\n 'd': '返回所提供的两个日期之间的净工作日天数。',\r\n 'a': '返回所提供的两个日期之间的净工作日天数。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '用于计算净工作日天数的时间段开始日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'end_date',\r\n 'detail': '用于计算净工作日天数的时间段结束日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'holidays',\r\n 'detail': '[可选] - 一个范围或数组常量,其中包含作为节假日的日期序号。\\n\\n在节假日数组中提供的值必须是日期序号值(例如由N所返回的值)或日期值(例如由DATE、DATEVALUE或TO_DATE返回的值)。由范围指定的值应该是标准的日期值或日期序数值。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NETWORKDAYS_INTL',\r\n 't': 6,\r\n 'd': '返回给定的两个日期之间的净工作日天数(排除指定的周末和节假日)。',\r\n 'a': '返回给定的两个日期之间的净工作日天数(排除指定的周末和节假日)。',\r\n 'm': [2, 4],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '用于计算净工作日天数的时间段开始日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'end_date',\r\n 'detail': '用于计算净工作日天数的时间段结束日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'weekend',\r\n 'detail': '[可选 - 默认值为1] - 用于表示哪些天为周末的数字或字符串。\\n字符串方式:可以使用由0和1组成的字符串来指定周末,串中的第一个数字字符代表周一,最后一个则代表周日。零表示这一天是工作日,1表示这一天为周末。例如,“0000011”表示将周六和周日作为周末。\\n数字方式:这种方式不使用上述字符串形式,而是使用一个数字。1 =周六/周日为周末,2 =周日/周一为周末,依此类推则7 =周五/周六。11 =周日为唯一周末,12 =周一为唯一周末,依此类推则17 =周六为唯一周末。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'holidays',\r\n 'detail': '[ 可选 ] - 这是一个范围或数组常量,其中包含作为节假日的日期。\\n在节假日数组内提供的值必须为日期序数值(例如N的返回值)或日期值(例如DATE、DATEVALUE或TO_DATE的返回值)。由范围指定的值应该是标准的日期值或日期序数值。',\r\n 'example': 'DATE(1969',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISOWEEKNUM',\r\n 't': 6,\r\n 'd': '返回给定日期在全年中的 ISO 周数。',\r\n 'a': '返回给定日期在全年中的 ISO 周数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'date',\r\n 'detail': '用于日期和时间计算的日期-时间代码。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'WEEKNUM',\r\n 't': 6,\r\n 'd': '返回特定日期的周数。',\r\n 'a': '返回特定日期的周数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'serial_number',\r\n 'detail': '要确定其位于第几周的日期,必须是对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'return_type',\r\n 'detail': '[可选 - 默认值为 1 ] - 代表一周起始日的数字,系统也使用该数字来确定一年的第一周(1=周日,2=周一)。',\r\n 'example': '7',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'WEEKDAY',\r\n 't': 6,\r\n 'd': '返回一个数字,对应于给定日期所在的星期几。',\r\n 'a': '返回一个数字,对应于给定日期所在的星期几。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'serial_number',\r\n 'detail': '要为其确定星期几的日期。必须是对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'return_type',\r\n 'detail': '[可选 - 默认值为 1] - 以数字指示使用哪种编号顺序来表示星期几。默认情况下,按星期日 (= 1) 开始计算。\\n\\n如果类型为 1,则星期值将从星期日开始算起,并且星期日的值为 1,因此星期六的值就是 7。\\n\\n如果类型为 2,则星期值将从星期一开始算起,并且星期一的值为 1,因此星期日的值就是 7。\\n\\n如果类型为 3,则星期值将从星期一算起,并且星期一的值为 0,因此星期日的值就是 6。',\r\n 'example': '7',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DAY',\r\n 't': 6,\r\n 'd': '以数字格式返回特定日期所在的当月几号。',\r\n 'a': '以数字格式返回特定日期所在的当月几号。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'serial_number',\r\n 'detail': '要从中提取具体几号的日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DAYS',\r\n 't': 6,\r\n 'd': '返回两个日期之间的天数。',\r\n 'a': '返回两个日期之间的天数。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'end_date',\r\n 'detail': '计算中要使用的结束日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': '2011-3-15',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'start_date',\r\n 'detail': '计算中要使用的开始日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': '2011-2-1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DAYS360',\r\n 't': 6,\r\n 'd': '按照每年360天,返回两个日期之间的差(用于计算利息)。',\r\n 'a': '按照每年360天,返回两个日期之间的差(用于计算利息)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '计算中要使用的开始日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'end_date',\r\n 'detail': '计算中要使用的结束日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'method',\r\n 'detail': '[可选 - 默认为FALSE()] - 指示要使用哪种天数计算方法。\\n\\nFALSE - 采用美国 (NASD) 方法时,如果起始日期为某月的最后一天,为便于计算,会将起始日期的当月几号更改为30。此外,如果结束日期是所在月份的最后一天,而且起始日期在其所在月的30号之前,则将结束日期更改为结束日期之后那个月的第一天,否则将结束日期更改为该月的30号。\\n\\nTRUE - 采用欧洲方法时,会将所有日期在31号的起始日期或结束日期更改为当月的30号。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DATE',\r\n 't': 6,\r\n 'd': '将提供的年、月、日转换为日期。',\r\n 'a': '将提供的年、月、日转换为日期。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'year',\r\n 'detail': '日期的年份部分,包含一到四位数字。\\n\\n介于 0(零)到 1899 之间,会将该值与 1900 相加来计算年份;\\n\\n介于 1900 到 9999 之间,将使用该数值作为年份;\\n\\n小于 0 或大于等于 10000,返回 错误值 #NUM!。',\r\n 'example': '1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'month',\r\n 'detail': '日期的月份部分,一个正整数或负整数。\\n\\n如果 month 大于 12,则 month 会将该月份数与指定年中的第一个月相加。\\n\\n如果 month 小于 1,month 则从指定年份的一月份开始递减该月份数,然后再加上 1 个月。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'day',\r\n 'detail': '日期的日部分,一个正整数或负整数。\\n\\n如果 day 大于月中指定的天数,则 day 会将天数与该月中的第一天相加。\\n\\n如果 day 小于 1,则 day 从指定月份的第一天开始递减该天数,然后再加上 1 天。',\r\n 'example': '20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DATEVALUE',\r\n 't': 6,\r\n 'd': '将提供的日期字符串转换为日期的序列号。',\r\n 'a': '将提供的日期字符串转换为日期的序列号。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'date_text',\r\n 'detail': '表示日期的字符串。',\r\n 'example': '\"1969-7-20\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DATEDIF',\r\n 't': 6,\r\n 'd': '计算两个日期之间的天数、月数或年数。',\r\n 'a': '计算两个日期之间的天数、月数或年数。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': '起始日期',\r\n 'detail': '计算中要使用的开始日期。必须是对包含DATE值的单元格的引用、返回DATE类型的函数或数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '结束日期',\r\n 'detail': '计算中要使用的结束日期。必须是对包含DATE值的单元格的引用、返回DATE类型的函数或数字。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '单位',\r\n 'detail': '时间单位的缩写文字。例如 \"M\" 代表月。有效值包括:\"Y\"、\"M\"、\"D\"、\"MD\"、\"YM\" 和 \"YD\"。\\n\\n\"Y\":返回起始日期和结束日期之间的整年数。\\n\\n\"M\":返回起始日期和结束日期之间的整月数。\\n\\n\"D\":返回起始日期和结束日期之间的天数。\\n\\n\"MD\":返回起始日期和结束日期之间的天数(不计整月数)。\\n\\n\"YM\":返回起始日期和结束日期之间的整月数(不计整年数)。\\n\\n\"YD\":返回起始日期和结束日期之间的天数(假设起始日期和结束日期的间隔不超过一年)。',\r\n 'example': '16)',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'WORKDAY',\r\n 't': 6,\r\n 'd': '指定工作日天数,计算结束日期。',\r\n 'a': '指定工作日天数,计算结束日期。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '计算的开始日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'days',\r\n 'detail': 'start_date 之前或之后不含周末及节假日的天数。\\n\\n为正值将生成未来日期;\\n\\n为负值生成过去日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'holidays',\r\n 'detail': '[可选] - 一个范围或数组常量,其中包含作为节假日的日期序号。\\n\\n在节假日数组中提供的值必须是日期序号值(例如由N所返回的值)或日期值(例如由DATE、DATEVALUE或TO_DATE返回的值)。由范围指定的值应该是标准的日期值或日期序数值。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'WORKDAY_INTL',\r\n 't': 6,\r\n 'd': '返回指定的若干个工作日之前或之后的日期的序列号(使用自定义周末参数)。 ',\r\n 'a': '返回指定的若干个工作日之前或之后的日期的序列号(使用自定义周末参数)。 ',\r\n 'm': [2, 4],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '开始日期(将被截尾取整)。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'days',\r\n 'detail': 'start_date 之前或之后的工作日的天数。\\n\\n正值表示未来日期;\\n\\n负值表示过去日期;\\n\\n零值表示开始日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'weekend',\r\n 'detail': '[可选 - 默认值为1] - 用于表示哪些天为周末的数字或字符串。\\n字符串方式:可以使用由0和1组成的字符串来指定周末,串中的第一个数字字符代表周一,最后一个则代表周日。零表示这一天是工作日,1表示这一天为周末。例如,“0000011”表示将周六和周日作为周末。\\n数字方式:这种方式不使用上述字符串形式,而是使用一个数字。1 =周六/周日为周末,2 =周日/周一为周末,依此类推则7 =周五/周六。11 =周日为唯一周末,12 =周一为唯一周末,依此类推则17 =周六为唯一周末。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'holidays',\r\n 'detail': '[ 可选 ] - 这是一个范围或数组常量,其中包含作为节假日的日期。\\n在节假日数组内提供的值必须为日期序数值(例如N的返回值)或日期值(例如DATE、DATEVALUE或TO_DATE的返回值)。由范围指定的值应该是标准的日期值或日期序数值。',\r\n 'example': 'DATE(1969',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'YEAR',\r\n 't': 6,\r\n 'd': '返回对应于某个日期的年份。 Year 作为 1900 - 9999 之间的整数返回。',\r\n 'a': '返回对应于某个日期的年份。 Year 作为 1900 - 9999 之间的整数返回。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'serial_number',\r\n 'detail': '用于计算年份的日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'YEARFRAC',\r\n 't': 6,\r\n 'd': '返回 start_date 和 end_date 之间的天数占全年天数的百分比。',\r\n 'a': '返回 start_date 和 end_date 之间的天数占全年天数的百分比。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'start_date',\r\n 'detail': '计算中要使用的开始日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'end_date',\r\n 'detail': '计算中要使用的结束日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 要使用的日计数基准类型。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TODAY',\r\n 't': 6,\r\n 'd': '以日期值格式返回当前日期。',\r\n 'a': '以日期值格式返回当前日期。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'MONTH',\r\n 't': 6,\r\n 'd': '返回日期(以序列数表示)中的月份。 月份是介于 1(一月)到 12(十二月)之间的整数。',\r\n 'a': '返回日期(以序列数表示)中的月份。 月份是介于 1(一月)到 12(十二月)之间的整数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'serial_number',\r\n 'detail': '要从中提取月份的日期。必须是以下一种:对包含日期的单元格的引用、返回日期类型的函数或者数字。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EFFECT',\r\n 't': 8,\r\n 'd': '根据名义利率及每年的复利计息期数来计算实际年利率。',\r\n 'a': '根据名义利率及每年的复利计息期数来计算实际年利率。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'nominal_rate',\r\n 'detail': '每年的名义利率。',\r\n 'example': '0.99',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'npery',\r\n 'detail': '每年的复利计算期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DOLLAR',\r\n 't': 12,\r\n 'd': '将数字格式设置为与语言区域相对应的货币格式。',\r\n 'a': '将数字格式设置为与语言区域相对应的货币格式。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要设置格式的值。',\r\n 'example': '1.2351',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'decimals',\r\n 'detail': '[可选 - 默认值为 2] - 要显示的小数位数。\\n\\n如果这是负数,则将数字四舍五入到小数点左侧。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DOLLARDE',\r\n 't': 8,\r\n 'd': '将以整数部分和分数部分转换为以小数部分表示的金额数字',\r\n 'a': '将以整数部分和分数部分转换为以小数部分表示的金额数字',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'fractional_dollar',\r\n 'detail': '以整数部份和分数部分表示的数字,用小数点隔开。',\r\n 'example': '100.10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fraction',\r\n 'detail': '用作分数中的分母的整数。',\r\n 'example': '32',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DOLLARFR',\r\n 't': 8,\r\n 'd': '将小数转换为分数表示的金额数字。',\r\n 'a': '将小数转换为分数表示的金额数字。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'decimal_dollar',\r\n 'detail': '小数。',\r\n 'example': '100.125',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fraction',\r\n 'detail': '用作分数中的分母的整数。',\r\n 'example': '32',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DB',\r\n 't': 8,\r\n 'd': '使用固定余额递减法,返回指定期间内某项固定资产的折旧值。',\r\n 'a': '使用固定余额递减法,返回指定期间内某项固定资产的折旧值。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'cost',\r\n 'detail': '资产原值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'salvage',\r\n 'detail': '折旧末尾时的值(有时也称为资产残值)。',\r\n 'example': '50',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'life',\r\n 'detail': '资产的折旧期数(有时也称作资产的使用寿命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'period',\r\n 'detail': '在使用期限内要计算折旧的折旧期。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'month',\r\n 'detail': '[可选 - 默认值为12] - 折旧第一年中的月数。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DDB',\r\n 't': 8,\r\n 'd': '用双倍余额递减法,返回指定期间内某项固定资产的折旧值。',\r\n 'a': '用双倍余额递减法,返回指定期间内某项固定资产的折旧值。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'cost',\r\n 'detail': '资产原值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'salvage',\r\n 'detail': '折旧末尾时的值(有时也称为资产残值)。',\r\n 'example': '50',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'life',\r\n 'detail': '资产的折旧期数(有时也称作资产的使用寿命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'period',\r\n 'detail': '在使用期限内要计算折旧的折旧期。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'factor',\r\n 'detail': '[可选 - 默认值为2] - 折旧的递减系数。',\r\n 'example': '2.25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RATE',\r\n 't': 8,\r\n 'd': '返回年金每期的利率。',\r\n 'a': '返回年金每期的利率。',\r\n 'm': [3, 6],\r\n 'p': [{\r\n 'name': 'nper',\r\n 'detail': '年金的付款总期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pmt',\r\n 'detail': '每期的付款金额,在年金周期内不能更改。',\r\n 'example': '-100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '现值即一系列未来付款当前值的总和。',\r\n 'example': '400',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fv',\r\n 'detail': '[可选 - 默认值为0] - 未来值,或在最后一次付款后希望得到的现金余额。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '[可选 - 默认值为0] - 指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'guess',\r\n 'detail': '[可选 - 默认值为0.1] - 预期利率。',\r\n 'example': '0.1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CUMPRINC',\r\n 't': 8,\r\n 'd': '基于等额分期付款和固定利率,计算投资在多个付款期内的累计本金偿还额。',\r\n 'a': '基于等额分期付款和固定利率,计算投资在多个付款期内的累计本金偿还额。',\r\n 'm': [6, 6],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '利率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'nper',\r\n 'detail': '总付款期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '年金的现值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'start_period',\r\n 'detail': '开始累计计算的付款期序号。\\n\\n首期必须大于等于1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'end_period',\r\n 'detail': '结束累计计算的付款期序号。\\n\\n末期必须大于首期。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPNUM',\r\n 't': 8,\r\n 'd': '返回在结算日和到期日之间的付息次数,向上舍入到最近的整数。',\r\n 'a': '返回在结算日和到期日之间的付息次数,向上舍入到最近的整数。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。到期日是有价证券有效期截止时的日期。',\r\n 'example': '02',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SYD',\r\n 't': 8,\r\n 'd': '返回在指定期间内资产按年限总和折旧法计算的折旧。',\r\n 'a': '返回在指定期间内资产按年限总和折旧法计算的折旧。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'cost',\r\n 'detail': '资产原值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'salvage',\r\n 'detail': '折旧末尾时的值(有时也称为资产残值)。',\r\n 'example': '50',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'life',\r\n 'detail': '资产的折旧期数(有时也称作资产的使用寿命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'period',\r\n 'detail': '在使用期限内要计算折旧的折旧期。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TBILLEQ',\r\n 't': 8,\r\n 'd': '基于贴现率计算美国政府短期债券的等效年化收益率。',\r\n 'a': '基于贴现率计算美国政府短期债券的等效年化收益率。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '债券的结算日期,此日期为债券发行后交付给买家的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '债券的到期或结束日期,届时可将其以面值或票面价值赎回。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'discount',\r\n 'detail': '债券购买时的贴现率。',\r\n 'example': '2)',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TBILLYIELD',\r\n 't': 8,\r\n 'd': '基于价格计算美国政府短期债券的收益率。',\r\n 'a': '基于价格计算美国政府短期债券的收益率。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '债券的结算日期,此日期为债券发行后交付给买家的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '债券的到期或结束日期,届时可将其以面值或票面价值赎回。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'pr',\r\n 'detail': '债券的购买价格。',\r\n 'example': '95',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TBILLPRICE',\r\n 't': 8,\r\n 'd': '基于贴现率计算美国政府短期债券的价格。',\r\n 'a': '基于贴现率计算美国政府短期债券的价格。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '债券的结算日期,此日期为债券发行后交付给买家的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '债券的到期或结束日期,届时可将其以面值或票面价值赎回。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'discount',\r\n 'detail': '债券购买时的贴现率。',\r\n 'example': '0.09',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PV',\r\n 't': 8,\r\n 'd': '基于等额分期付款和固定利率,计算年金投资的现值。',\r\n 'a': '基于等额分期付款和固定利率,计算年金投资的现值。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '各期利率。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'nper',\r\n 'detail': '年金的付款总期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pmt',\r\n 'detail': '每期的付款金额,在年金周期内不能更改。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fv',\r\n 'detail': '[可选] - 未来值,或在最后一次付款后希望得到的现金余额。',\r\n 'example': 'D2',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '[可选 - 默认值为0] - 指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ACCRINT',\r\n 't': 8,\r\n 'd': '返回定期付息证券的应计利息。',\r\n 'a': '返回定期付息证券的应计利息。',\r\n 'm': [6, 8],\r\n 'p': [{\r\n 'name': 'issue',\r\n 'detail': '有价证券的发行日。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'first_interest',\r\n 'detail': '有价证券的首次计息日。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'rate',\r\n 'detail': '有价证券的年息票利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'par',\r\n 'detail': '证券的票面值。',\r\n 'example': '10000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示““欧洲30/360”方法” - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'calc_method',\r\n 'detail': '[可选 - 默认为TRUE()] - 一个逻辑值,指定当结算日期晚于首次计息日期时用于计算总应计利息的方法。\\n\\n如果值为 TRUE,则返回从发行日到结算日的总应计利息。\\n\\n如果值为 FALSE,则返回从首次计息日到结算日的应计利息。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ACCRINTM',\r\n 't': 8,\r\n 'd': '返回在到期日支付利息的有价证券的应计利息。',\r\n 'a': '返回在到期日支付利息的有价证券的应计利息。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'issue',\r\n 'detail': '有价证券的发行日。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'settlement',\r\n 'detail': '有价证券的到期日。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'rate',\r\n 'detail': '有价证券的年息票利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'par',\r\n 'detail': '证券的票面值。',\r\n 'example': '1000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPDAYBS',\r\n 't': 8,\r\n 'd': '返回从付息期开始到结算日的天数。',\r\n 'a': '返回从付息期开始到结算日的天数。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPDAYS',\r\n 't': 8,\r\n 'd': '返回结算日所在的付息期的天数。',\r\n 'a': '返回结算日所在的付息期的天数。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPDAYSNC',\r\n 't': 8,\r\n 'd': '返回从结算日到下一票息支付日之间的天数。',\r\n 'a': '返回从结算日到下一票息支付日之间的天数。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPNCD',\r\n 't': 8,\r\n 'd': '计算结算日之后的下一票息或利息派发日期。',\r\n 'a': '计算结算日之后的下一票息或利息派发日期。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '01)',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': 'DATE(2019',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPPCD',\r\n 't': 8,\r\n 'd': '计算结算日之前的最后一个票息或利息支付日。',\r\n 'a': '计算结算日之前的最后一个票息或利息支付日。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '01)',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': 'DATE(2019',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FV',\r\n 't': 8,\r\n 'd': '基于等额分期付款和固定利率,计算年金投资的未来价值。',\r\n 'a': '基于等额分期付款和固定利率,计算年金投资的未来价值。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '各期利率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'nper',\r\n 'detail': '年金的付款总期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pmt',\r\n 'detail': '各期所应支付的金额,在整个年金期间保持不变。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '[可选 - 默认值为 0 ] - 现值,或一系列未来付款的当前值的累积和。',\r\n 'example': '400',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '[可选 - 默认值为 0 ] - 指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FVSCHEDULE',\r\n 't': 8,\r\n 'd': '返回应用一系列复利率计算的初始本金的未来值。',\r\n 'a': '返回应用一系列复利率计算的初始本金的未来值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'principal',\r\n 'detail': '现值。',\r\n 'example': '10000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'schedule',\r\n 'detail': '用于计算本金复利的一组利率。\\n\\n利率表必须是范围或数组,其中包含要用于计算复利的一组利率。这些利率值应该以十进制小数形式表示,或者使用UNARY_PERCENT以百分比形式表示,即表示为0.09或UNARY_PERCENT(9),而不要表示为9。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'YIELD',\r\n 't': 8,\r\n 'd': '返回定期支付利息的债券的收益率。',\r\n 'a': '返回定期支付利息的债券的收益率。',\r\n 'm': [6, 7],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'rate',\r\n 'detail': '有价证券的年息票利率。',\r\n 'example': '0.057',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pr',\r\n 'detail': '有价证券的价格。',\r\n 'example': '95',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'redemption',\r\n 'detail': '有价证券的清偿价值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'YIELDDISC',\r\n 't': 8,\r\n 'd': '基于价格计算折价发行的(不带息)债券的年收益率。',\r\n 'a': '基于价格计算折价发行的(不带息)债券的年收益率。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'pr',\r\n 'detail': '有价证券的价格。',\r\n 'example': '95',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'redemption',\r\n 'detail': '有价证券的清偿价值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NOMINAL',\r\n 't': 8,\r\n 'd': '基于给定的实际利率和年复利期数,返回名义年利率。',\r\n 'a': '基于给定的实际利率和年复利期数,返回名义年利率。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'effect_rate',\r\n 'detail': '每年的实际利率。',\r\n 'example': '0.85',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'npery',\r\n 'detail': '每年的复利期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'XIRR',\r\n 't': 8,\r\n 'd': '返回一组不一定定期发生的现金流的内部收益率。',\r\n 'a': '返回一组不一定定期发生的现金流的内部收益率。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'values',\r\n 'detail': '其中含有投资相关收益或支出的数组或范围。\\n\\n现金流数额中必须至少包含一项负的和一项正的现金流金额才能计算回报率。',\r\n 'example': 'B2:B25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'dates',\r\n 'detail': '与现金流数额参数中的现金流对应的日期数组或范围。',\r\n 'example': 'C2:C25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'guess',\r\n 'detail': '[可选 - 默认值为0.1] - 对内部回报率的估算值。',\r\n 'example': '250',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MIRR',\r\n 't': 8,\r\n 'd': '返回一系列定期现金流的修改后内部收益率。',\r\n 'a': '返回一系列定期现金流的修改后内部收益率。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'values',\r\n 'detail': '其中含有投资相关收益或支出的数组或范围。\\n\\n现金流数额中必须至少包含一项负的和一项正的现金流金额才能计算回报率。',\r\n 'example': 'A2:A25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'finance_rate',\r\n 'detail': '现金流中使用的资金支付的利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'reinvest_rate',\r\n 'detail': '将现金流再投资的收益率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'IRR',\r\n 't': 8,\r\n 'd': '返回由值中的数字表示的一系列现金流的内部收益率。 ',\r\n 'a': '返回由值中的数字表示的一系列现金流的内部收益率。 ',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'values',\r\n 'detail': '其中含有投资相关收益或支出的数组或范围。\\n\\n现金流数额中必须至少包含一项负的和一项正的现金流金额才能计算回报率。',\r\n 'example': 'A2:A25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'guess',\r\n 'detail': '[可选 - 默认为 0.1] - 内部收益率的估值。',\r\n 'example': '200',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NPV',\r\n 't': 8,\r\n 'd': '使用贴现率和一系列未来支出(负值)和收益(正值)来计算一项投资的净现值。',\r\n 'a': '使用贴现率和一系列未来支出(负值)和收益(正值)来计算一项投资的净现值。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '某一期间的贴现率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'value1',\r\n 'detail': '第一笔支出(负值)和收益(正值)。',\r\n 'example': '200',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2, ...',\r\n 'detail': '[可选] - 其他支出(负值)和收益(正值)。',\r\n 'example': '250',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'XNPV',\r\n 't': 8,\r\n 'd': '返回一组现金流的净现值,这些现金流不一定定期发生。',\r\n 'a': '返回一组现金流的净现值,这些现金流不一定定期发生。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '应用于现金流的贴现率。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'values',\r\n 'detail': '与 dates 中的支付时间相对应的一系列现金流。',\r\n 'example': 'B2:B25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'dates',\r\n 'detail': '与现金流支付相对应的支付日期表。',\r\n 'example': 'C2:C25',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'CUMIPMT',\r\n 't': 8,\r\n 'd': '基于等额分期付款和固定利率,计算投资在一系列付款期内的累计利息。',\r\n 'a': '基于等额分期付款和固定利率,计算投资在一系列付款期内的累计利息。',\r\n 'm': [6, 6],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '利息率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'nper',\r\n 'detail': '总付款期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '现值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'start_period',\r\n 'detail': '开始累计计算的付款期序号。\\n\\n首期必须大于等于1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'end_period',\r\n 'detail': '结束累计计算的付款期序号。\\n\\n末期必须大于首期。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PMT',\r\n 't': 8,\r\n 'd': '用于根据固定付款额和固定利率计算贷款的付款额。',\r\n 'a': '用于根据固定付款额和固定利率计算贷款的付款额。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '贷款利率。',\r\n 'example': '0.08',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'nper',\r\n 'detail': '该项贷款的付款总数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '现值,或一系列未来付款额现在所值的总额,也叫本金。',\r\n 'example': ' 100000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fv',\r\n 'detail': '[可选 - 默认值为 0] - 未来值,或在最后一次付款后希望得到的现金余额。',\r\n 'example': 'D2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '[可选 - 默认值为 0] - 指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'IPMT',\r\n 't': 8,\r\n 'd': '基于固定利率及等额分期付款方式,返回给定期数内对投资的利息偿还额。',\r\n 'a': '基于固定利率及等额分期付款方式,返回给定期数内对投资的利息偿还额。',\r\n 'm': [4, 6],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '各期利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'per',\r\n 'detail': '用于计算其利息数额的期数,必须在 1 到 nper 之间。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'nper',\r\n 'detail': '年金的付款总期数。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '现值,或一系列未来付款的当前值的累积和。',\r\n 'example': '80000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fv',\r\n 'detail': '[可选 - 默认值为 0] - 未来值,或在最后一次付款后希望得到的现金余额。',\r\n 'example': 'E2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '[可选 - 默认值为 0] - 指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PPMT',\r\n 't': 8,\r\n 'd': '返回根据定期固定付款和固定利率而定的投资在已知期间内的本金偿付额。',\r\n 'a': '返回根据定期固定付款和固定利率而定的投资在已知期间内的本金偿付额。',\r\n 'm': [4, 6],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '各期利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'per',\r\n 'detail': '指定期数,该值必须在 1 到 nper 范围内。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'nper',\r\n 'detail': '年金的付款总期数。',\r\n 'example': '3*12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '现值即一系列未来付款当前值的总和。',\r\n 'example': '100000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fv',\r\n 'detail': '[可选 - 默认值为 0] - 未来值,或在最后一次付款后希望得到的现金余额。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '[可选 - 默认值为 0] - 指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'INTRATE',\r\n 't': 8,\r\n 'd': '返回完全投资型证券的利率。',\r\n 'a': '返回完全投资型证券的利率。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'investment',\r\n 'detail': '有价证券的投资额。',\r\n 'example': '100000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'redemption',\r\n 'detail': '有价证券到期时的兑换值。',\r\n 'example': '101200',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PRICE',\r\n 't': 8,\r\n 'd': '返回定期付息的面值 ¥100 的有价证券的价格。',\r\n 'a': '返回定期付息的面值 ¥100 的有价证券的价格。',\r\n 'm': [6, 7],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'rate',\r\n 'detail': '有价证券的年息票利率。',\r\n 'example': '0.057',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'yld',\r\n 'detail': '有价证券的年收益率。',\r\n 'example': '0.065',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'redemption',\r\n 'detail': '面值 ¥100 的有价证券的清偿价值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PRICEDISC',\r\n 't': 8,\r\n 'd': '返回折价发行的面值 ¥100 的有价证券的价格。',\r\n 'a': '返回折价发行的面值 ¥100 的有价证券的价格。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'discount',\r\n 'detail': '有价证券的贴现率。',\r\n 'example': '0.0525',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'redemption',\r\n 'detail': '面值 ¥100 的有价证券的清偿价值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PRICEMAT',\r\n 't': 8,\r\n 'd': '返回到期付息的面值 ¥100 的有价证券的价格。',\r\n 'a': '返回到期付息的面值 ¥100 的有价证券的价格。',\r\n 'm': [5, 6],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'issue',\r\n 'detail': '有价证券的发行日。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'rate',\r\n 'detail': '有价证券在发行日的利率。',\r\n 'example': '0.061',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'yld',\r\n 'detail': '有价证券的年收益率。',\r\n 'example': '0.061',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RECEIVED',\r\n 't': 8,\r\n 'd': '返回一次性付息的有价证券到期收回的金额。',\r\n 'a': '返回一次性付息的有价证券到期收回的金额。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'investment',\r\n 'detail': '有价证券的投资额。',\r\n 'example': '10000000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'discount',\r\n 'detail': '有价证券的贴现率。',\r\n 'example': '0.0575',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '12',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DISC',\r\n 't': 8,\r\n 'd': '返回有价证券的贴现率。',\r\n 'a': '返回有价证券的贴现率。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'pr',\r\n 'detail': '有价证券的价格(按面值为 ¥100 计算)。',\r\n 'example': '97.975',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'redemption',\r\n 'detail': '面值 ¥100 的有价证券的清偿价值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '12',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NPER',\r\n 't': 8,\r\n 'd': '基于固定利率及等额分期付款方式,返回某项投资的总期数。',\r\n 'a': '基于固定利率及等额分期付款方式,返回某项投资的总期数。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name': 'rate',\r\n 'detail': '各期利率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pmt',\r\n 'detail': '各期所应支付的金额,在整个年金期间保持不变。',\r\n 'example': '500',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'pv',\r\n 'detail': '现值,或一系列未来付款的当前值的累积和。',\r\n 'example': '40000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'fv',\r\n 'detail': '[可选 - 默认值为0] - 未来值,或在最后一次付款后希望得到的现金余额。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'type',\r\n 'detail': '[可选 - 默认值为0] - 指定各期的付款时间是在期初还是期末。\\n\\n0 表示期末;\\n\\n1 表示期初。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SLN',\r\n 't': 8,\r\n 'd': '返回一个期间内的资产的直线折旧。',\r\n 'a': '返回一个期间内的资产的直线折旧。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'cost',\r\n 'detail': '资产原值。',\r\n 'example': '300000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'salvage',\r\n 'detail': '折旧末尾时的值(有时也称为资产残值)。',\r\n 'example': '75000',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'life',\r\n 'detail': '资产的折旧期数(有时也称作资产的使用寿命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DURATION',\r\n 't': 8,\r\n 'd': '返回假设面值 ¥100 的定期付息有价证券的修正期限。',\r\n 'a': '返回假设面值 ¥100 的定期付息有价证券的修正期限。',\r\n 'm': [5, 6],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'coupon',\r\n 'detail': '有价证券的年息票利率。',\r\n 'example': '0.08',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'yld',\r\n 'detail': '有价证券的年收益率。',\r\n 'example': '0.09',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MDURATION',\r\n 't': 8,\r\n 'd': '返回假设面值 ¥100 的有价证券的 Macauley 修正期限。',\r\n 'a': '返回假设面值 ¥100 的有价证券的 Macauley 修正期限。',\r\n 'm': [5, 6],\r\n 'p': [{\r\n 'name': 'settlement',\r\n 'detail': '有价证券的结算日。 有价证券结算日是在发行日之后,有价证券卖给购买者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'maturity',\r\n 'detail': '有价证券的到期日。 到期日是有价证券有效期截止时的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'coupon',\r\n 'detail': '有价证券的年息票利率。',\r\n 'example': '0.08',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'yld',\r\n 'detail': '有价证券的年收益率。',\r\n 'example': '0.09',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'frequency',\r\n 'detail': '年付息次数。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'basis',\r\n 'detail': '[可选 - 默认为0] - 指示要使用哪种天数计算方法。\\n\\n0表示“美国(NASD) 30/360”方法 - 此方法按照美国全国证券交易商协会标准,假设每月30天、每年360天,并对所输入的月末日期进行具体调整。\\n\\n1表示“实际/实际”方法 - 此方法计算基于指定日期之间的实际天数和所涉及的年份中的实际天数进行计算。此方法用于美国长期债券,也是在非财经用途方面使用最多的方法。\\n\\n2表示“实际/360”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为360天。\\n\\n3表示“实际/365”方法 - 此方法基于指定日期之间的实际天数进行计算,但假定每年为365天。\\n\\n4表示“欧洲30/360”方法 - 类似于0,此方法基于每月30天、每年360天进行计算,但按照欧洲金融惯例对月末日期进行调整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'BIN2DEC',\r\n 't': 9,\r\n 'd': '将二进制数转换为十进制数。',\r\n 'a': '将二进制数转换为十进制数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为十进制数的带符号的10位二进制数值(以字符串形式提供)。\\n\\n带符号的二进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n对于此函数,最大的正数输入值为0111111111,最小的负数输入值为1000000000。\\n\\n如果所提供的带符号的二进制数是有效的二进制数,会自动将其转换为相应的字符串输入。例如,BIN2DEC(100)和BIN2DEC(\"100\")得出的结果相同,均为4。',\r\n 'example': '101',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'BIN2HEX',\r\n 't': 9,\r\n 'd': '将二进制数转换为十六进制数。',\r\n 'a': '将二进制数转换为十六进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的十六进制数的带符号的10位二进制数值(以字符串形式提供)。\\n\\n带符号的二进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n对于此函数,最大的正数输入值为0111111111,最小的负数输入值为1000000000。\\n\\n如果所提供的带符号的二进制数是有效的二进制数,会自动将其转换为相应的字符串输入。例如,BIN2HEX(11111)和BIN2HEX(\"11111\")得出 的结果相同,均为1F。',\r\n 'example': '101',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。例如,BIN2HEX(\"11111\",8)所得的结果值为0000001F。\\n\\n如果带符号的二进制数的最高位为1,则忽略此值;即当提供的带符号的二进制数大于等于1000000000时忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'BIN2OCT',\r\n 't': 9,\r\n 'd': '将二进制数转换为八进制数。',\r\n 'a': '将二进制数转换为八进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的八进制数的带符号的10位二进制数值(以字符串形式提供)。\\n\\n带符号的二进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n对于此函数,最大的正数输入值为0111111111,最小的负数输入值为1000000000。\\n\\n如果所提供的带符号的二进制数是有效的二进制数,会自动将其转换为相应的字符串输入。例如,BIN2OCT(11111)和BIN2OCT(\"11111\")得出的结果相同,均为37。',\r\n 'example': '101',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。例如,BIN2OCT(\"11111\")得到的结果值为00000037。\\n\\n如果带符号的二进制数的最高位为1,则忽略此值;即当提供的带符号的二进制数大于等于1000000000时忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEC2BIN',\r\n 't': 9,\r\n 'd': '将十进制数转换为二进制数。',\r\n 'a': '将十进制数转换为二进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的二进制数的十进制数值(以字符串形式提供)。\\n\\n对于此函数,最大的正数输入值为511,最小的负数输入值为-512。\\n\\n如果所提供的十进制数是有效的十进制数,会自动将其转换为相应的字符串输入。例如,DEC2BIN(199)和DEC2BIN(\"199\")得出的结果相同,均为11000111。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。\\n\\n如果十进制数为负数,则忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEC2HEX',\r\n 't': 9,\r\n 'd': '将十进制数转换为十六进制数。',\r\n 'a': '将十进制数转换为十六进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的十六进制数的十进制数值(以字符串形式提供)。\\n\\n此函数可接受的最大正数值为549755813887,最小负数值为-549755814888。\\n\\n如果所提供的十进制数是有效的十进制数,会自动将其转换为相应的字符串输入。例如,DEC2HEX(100)和DEC2HEX(\"100\")得出的结果相同,均为64。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。\\n\\n如果十进制数为负数,则忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEC2OCT',\r\n 't': 9,\r\n 'd': '将十进制数转换为八进制数。',\r\n 'a': '将十进制数转换为八进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的八进制数的十进制数值(以字符串形式提供)。\\n\\n此函数可接受的最大正数值为536870911,最小负数值为-53687092。\\n\\n如果所提供的十进制数是有效的十进制数,会自动将其转换为相应的字符串输入。例如,DEC2OCT(199)和DEC2OCT(\"199\")得出的结果相同,均为307。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。\\n\\n如果十进制数为负数,则忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HEX2BIN',\r\n 't': 9,\r\n 'd': '将十六进制数转换为二进制数。',\r\n 'a': '将十六进制数转换为二进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的二进制数的带符号的40位十六进制数值(以字符串形式提供)。\\n\\n带符号的十六进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n此函数可接受的最大正数值为1FF,最小负数值为FFFFFFFE00。\\n\\n如果所提供的带符号的十六进制数是有效的十六进制数,函数会自动将其转换为相应的字符串输入。例如,HEX2BIN(199)和HEX2BIN(\"199\")得出的结果相同,均为110011001。',\r\n 'example': '\"f3\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。\\n\\n如果带符号的十六进制数的最高位为1,则忽略此值;即当提供的带符号的十六进制数大于等于8000000000时忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HEX2DEC',\r\n 't': 9,\r\n 'd': '将十六进制数转换为十进制数。',\r\n 'a': '将十六进制数转换为十进制数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为十进制数的带符号的40位十六进制数值(以字符串形式提供)。\\n\\n带符号的十六进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n此函数可接受的最大正数值为7fffffffff,最小负数值为8000000000。\\n\\n如果所提供的带符号的十六进制数是有效的十六进制数,函数会自动将其转换为相应的字符串输入。例如,HEX2DEC(199)和HEX2DEC(\"199\")得出的结果相同,均为409。',\r\n 'example': '\"f3\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HEX2OCT',\r\n 't': 9,\r\n 'd': '将十六进制数转换为八进制数。',\r\n 'a': '将十六进制数转换为八进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的八进制数的带符号的40位十六进制数值(以字符串形式提供)。\\n\\n带符号的十六进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n此函数可接受的最大正数值为1FFFFFFF,最小负数值为FFE0000000。\\n\\n如果所提供的带符号的十六进制数是有效的十六进制数,函数会自动将其转换为相应的字符串输入。例如,HEX2OCT(199)和HEX2OCT(\"199\")得出的结果相同,均为631。',\r\n 'example': '\"f3\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。\\n\\n如果带符号的十六进制数的最高位为1,则忽略此值;即当给定的带符号的十六进制数大于等于8000000000时忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'OCT2BIN',\r\n 't': 9,\r\n 'd': '将八进制数转换为二进制数。',\r\n 'a': '将八进制数转换为二进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的二进制数的带符号的30位八进制数值(以字符串形式提供)。\\n\\n带符号的八进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n此函数可接受的最大正数值为777,最小负数值为7777777000。\\n\\n如果所提供的带符号的八进制数是有效的八进制数,函数会自动将其转换为相应的字符串输入。例如,OCT2BIN(177)和OCT2BIN(\"177\")得出的结果相同,均为1111111。',\r\n 'example': '37',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。\\n\\n如果带符号的八进制数的最高位为1,则忽略此值;即当给定的带符号的八进制数大于等于4000000000时忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'OCT2DEC',\r\n 't': 9,\r\n 'd': '将八进制数转换为十进制数。',\r\n 'a': '将八进制数转换为十进制数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为十进制数的带符号的30位八进制数值(以字符串形式提供)。\\n\\n带符号的ba进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n此函数可接受的最大正数值为3777777777,最小负数值为4000000000。\\n\\n如果所提供的带符号的八进制数是有效的八进制数,函数会自动将其转换为相应的字符串输入。例如,OCT2DEC(177)和OCT2DEC(\"177\")得出的结果相同,均为127。',\r\n 'example': '37',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'OCT2HEX',\r\n 't': 9,\r\n 'd': '将八进制数转换为十六进制数。',\r\n 'a': '将八进制数转换为十六进制数。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要转换为带符号的十六进制数的带符号的30位八进制数值(以字符串形式提供)。\\n\\n带符号的ba进制数的最高位是符号位;也就是说,负数是以二的补码形式表示的。\\n\\n此函数可接受的最大正数值为3777777777,最小负数值为4000000000。\\n\\n如果所提供的带符号的八进制数是有效的八进制数,函数会自动将其转换为相应的字符串输入。例如,OCT2HEX(177)和OCT2HEX(\"177\")得出的结果相同,均为7F。',\r\n 'example': '37',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'places',\r\n 'detail': '[ 可选 ] - 结果中要确保的有效位数。\\n\\n如果设置的有效位数大于结果中的有效位数,则在结果的左侧填充0,使总有效位数达到有效位数。\\n\\n如果带符号的八进制数的最高位为1,则忽略此值;即当给定的带符号的八进制数大于等于4000000000时忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COMPLEX',\r\n 't': 9,\r\n 'd': '将实系数及虚系数转换为 x+yi 或 x+yj 形式的复数。',\r\n 'a': '将实系数及虚系数转换为 x+yi 或 x+yj 形式的复数。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'real_num',\r\n 'detail': '复数的实系数。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'i_num',\r\n 'detail': '复数的虚系数。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'suffix',\r\n 'detail': '[可选 - 默认为 \"i\"] - 复数中虚系数的后缀。',\r\n 'example': '\"j\"',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangestring'\r\n }]\r\n }, {\r\n 'n': 'IMREAL',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的复数的实系数。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的复数的实系数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'inumber',\r\n 'detail': '需要计算其实系数的复数。',\r\n 'example': '\"4+5i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMAGINARY',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的复数的虚系数。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的复数的虚系数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'inumber',\r\n 'detail': '需要计算其虚系数的复数。',\r\n 'example': '\"4+5i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMCONJUGATE',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的复数的共轭复数。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的复数的共轭复数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'inumber',\r\n 'detail': '需要计算其共轭数的复数。',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMABS',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的复数的绝对值(模)。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的复数的绝对值(模)。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'inumber',\r\n 'detail': '要计算其绝对值的复数。',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DELTA',\r\n 't': 9,\r\n 'd': '检验两个值是否相等。 如果 number1=number2,则返回 1;否则返回 0。',\r\n 'a': '检验两个值是否相等。 如果 number1=number2,则返回 1;否则返回 0。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'number1',\r\n 'detail': '第一个数字。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'number2',\r\n 'detail': '[可选 - 默认为 0] - 第二个数字。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'IMSUM',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 个复数的和。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 个复数的和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': 'inumber1',\r\n 'detail': '要相加的第一个复数',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'inumber2, …',\r\n 'detail': '[可选] - 要与值1 相加的其他复数',\r\n 'example': '\"5-3i\"',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMSUB',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的两个复数的差。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的两个复数的差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'inumber1',\r\n 'detail': '从(复)数中减去 inumber2。',\r\n 'example': '\"6+5i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'inumber2',\r\n 'detail': '从 inumber1 中减(复)数。',\r\n 'example': '\"2+3i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMPRODUCT',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 个复数的乘积。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 个复数的乘积。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': 'inumber1',\r\n 'detail': '用于计算乘积的第一个复数',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'inumber2, …',\r\n 'detail': '[可选] - 要相乘的其他复数。',\r\n 'example': '\"5-3i\"',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMDIV',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的两个复数的商。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的两个复数的商。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'inumber1',\r\n 'detail': '复数分子或被除数。',\r\n 'example': '\"11+16i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'inumber2',\r\n 'detail': '复数分母或除数。',\r\n 'example': '\"3+2i\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NOT',\r\n 't': 10,\r\n 'd': '返回某个逻辑值的相反值 - “NOT(TRUE())”将返回 FALSE;“NOT(FALSE())”将返回 TRUE。',\r\n 'a': '返回某个逻辑值的相反值 - “NOT(TRUE())”将返回 FALSE;“NOT(FALSE())”将返回 TRUE。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'logical',\r\n 'detail': '计算结果为 TRUE 或 FALSE 的任何值或表达式。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TRUE',\r\n 't': 10,\r\n 'd': '返回逻辑值 TRUE。',\r\n 'a': '返回逻辑值 TRUE。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'FALSE',\r\n 't': 10,\r\n 'd': '返回逻辑值 FALSE。',\r\n 'a': '返回逻辑值 FALSE。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'AND',\r\n 't': 10,\r\n 'd': '所有参数的计算结果为 TRUE 时,返回 TRUE;只要有一个参数的计算结果为 FALSE,即返回 FALSE。',\r\n 'a': '所有参数的计算结果为 TRUE 时,返回 TRUE;只要有一个参数的计算结果为 FALSE,即返回 FALSE。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': 'logical1',\r\n 'detail': '要测试的第一个条件,其计算结果可以为 TRUE 或 FALSE。',\r\n 'example': 'A2 = \"foo\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'logical2,...',\r\n 'detail': '[可选] - 要测试的其他条件,其计算结果可以为 TRUE 或 FALSE,最多可包含 255 个条件。',\r\n 'example': 'A3 = \"bar\"',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IFERROR',\r\n 't': 10,\r\n 'd': '如果第一个参数不是错误值,就返回第一个参数;否则,返回第二个参数。',\r\n 'a': '如果第一个参数不是错误值',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '检查是否存在错误的参数。',\r\n 'example': 'A1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value_if_error',\r\n 'detail': '公式的计算结果错误时返回的值。 计算以下错误类型:#N/A、#VALUE!、#REF!、#DIV/0!、#NUM!、#NAME? 或 #NULL!。',\r\n 'example': '\"Error in cell A1\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IF',\r\n 't': 10,\r\n 'd': '当逻辑表达式的值为 TRUE 时返回一个值,而当其为 FALSE 时返回另一个值。',\r\n 'a': '当逻辑表达式的值为 TRUE 时返回一个值,而当其为 FALSE 时返回另一个值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'logical_test',\r\n 'detail': '一个表达式或对包含表达式的单元格的引用,该表达式代表某种逻辑值(即TRUE或FALSE)。',\r\n 'example': 'A2 = \"foo\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value_if_true',\r\n 'detail': '当逻辑表达式为TRUE时的返回值。',\r\n 'example': '\"A2 is foo\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value_if_false',\r\n 'detail': '[可选 - 默认为空白] - 当逻辑表达式等于FALSE时的函数返回值。',\r\n 'example': '\"A2 was false\"',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'OR',\r\n 't': 10,\r\n 'd': '只要有一个参数的计算结果为 TRUE 时,返回 TRUE;所有参数的计算结果为 FALSE,即返回 FALSE。',\r\n 'a': '只要有一个参数的计算结果为 TRUE 时,返回 TRUE;所有参数的计算结果为 FALSE,即返回 FALSE。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': 'logical1',\r\n 'detail': '要测试的第一个条件,其计算结果可以为 TRUE 或 FALSE。',\r\n 'example': 'A2 = \"foo\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': '逻辑表达式2',\r\n 'detail': '[可选] - 其他表达式或对包含表达式的单元格的引用,这些表达式代表某种逻辑值(即TRUE或FALSE)或者可以强制转换为逻辑值。',\r\n 'example': ' A3 = \"bar\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NE',\r\n 't': 11,\r\n 'd': '如果指定的值不相等,则返回“TRUE”;否则返回“FALSE”。相当于“<>”运算符。',\r\n 'a': '如果指定的值不相等,则返回“TRUE”;否则返回“FALSE”。相当于“<>”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '第一个值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '要检查是否与 value1 不相等的值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EQ',\r\n 't': 11,\r\n 'd': '如果指定的值相等,则返回“TRUE”;否则返回“FALSE”。相当于“=”运算符。',\r\n 'a': '如果指定的值相等,则返回“TRUE”;否则返回“FALSE”。相当于“=”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '第一个值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '要检查是否与 value1 相等的值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'GT',\r\n 't': 11,\r\n 'd': '如果第一个参数严格大于第二个,则返回 TRUE;否则返回 FALSE。相当于“>”运算符。',\r\n 'a': '如果第一个参数严格大于第二个,则返回 TRUE;否则返回 FALSE。相当于“>”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '要测试其是否大于 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '第二个值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'GTE',\r\n 't': 11,\r\n 'd': '如果第一个参数大于或等于第二个,则返回 TRUE;否则返回 FALSE。相当于“>=”运算符。',\r\n 'a': '如果第一个参数大于或等于第二个,则返回 TRUE;否则返回 FALSE。相当于“>=”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '要测试其是否大于等于 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '第二个值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LT',\r\n 't': 11,\r\n 'd': '如果第一个参数严格小于第二个,则返回 TRUE;否则返回 FALSE。相当于“<”运算符。',\r\n 'a': '如果第一个参数严格小于第二个,则返回 TRUE;否则返回 FALSE。相当于“<”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '要测试其是否小于 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '第二个值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LTE',\r\n 't': 11,\r\n 'd': '如果第一个参数小于或等于第二个,则返回 TRUE;否则返回 FALSE。相当于“<=”运算符。',\r\n 'a': '如果第一个参数小于或等于第二个,则返回 TRUE;否则返回 FALSE。相当于“<=”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '要测试其是否小于等于 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '第二个值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ADD',\r\n 't': 11,\r\n 'd': '返回两个数值之和。相当于 `+` 运算符。',\r\n 'a': '返回两个数值之和。相当于 `+` 运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '第一个加数。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '第二个加数。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MINUS',\r\n 't': 11,\r\n 'd': '返回两个数值之差。相当于“-”运算符。',\r\n 'a': '返回两个数值之差。相当于“-”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '被减数,即要对其计减的数值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '减数,即要从 value1 中减除的数值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MULTIPLY',\r\n 't': 11,\r\n 'd': '返回两个数的乘积。相当于“*”运算符。',\r\n 'a': '返回两个数的乘积。相当于“*”运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '第一个乘数。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '第二个乘数。',\r\n 'example': 'B2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DIVIDE',\r\n 't': 11,\r\n 'd': '返回两个参数相除所得的结果。相当于 `/` 运算符。',\r\n 'a': '返回两个参数相除所得的结果。相当于 `/` 运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': '要被除的数值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '用于除其他数的数值。\\n\\n除数不得为0。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CONCAT',\r\n 't': 11,\r\n 'd': '返回两个值的串联。相当于 `&` 运算符。',\r\n 'a': '返回两个值的串联。相当于 `&` 运算符。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value1',\r\n 'detail': 'value2 将附于其后的值。',\r\n 'example': '\"de\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'value2',\r\n 'detail': '要附于 value1 之后的值。',\r\n 'example': '\"mystify\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'UNARY_PERCENT',\r\n 't': 11,\r\n 'd': '返回按百分比解释的数值。例如,“UNARY_PERCENT(100)”等于1。',\r\n 'a': '返回按百分比解释的数值。例如,“UNARY_PERCENT(100)”等于1。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要作为百分比解释的数值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CONCATENATE',\r\n 't': 12,\r\n 'd': '将两个或多个文本字符串联接为一个字符串。',\r\n 'a': '将两个或多个文本字符串联接为一个字符串。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': 'text1',\r\n 'detail': '初始字符串。',\r\n 'example': '\"Super\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'text2 ...',\r\n 'detail': '[可选] - 要按顺序连接在一起的其他字符串。',\r\n 'example': '\"calla\"',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CODE',\r\n 't': 12,\r\n 'd': '返回所提供的字符串中首字符的 Unicode 映射值。',\r\n 'a': '返回所提供的字符串中首字符的 Unicode 映射值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要返回其首字符的Unicode映射值的字符串。',\r\n 'example': '\"a\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CHAR',\r\n 't': 12,\r\n 'd': '按照当前 Unicode 编码表,将数字转换为对应的字符。',\r\n 'a': '按照当前 Unicode 编码表,将数字转换为对应的字符。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '介于 1 到 255 之间的数字。',\r\n 'example': '97',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ARABIC',\r\n 't': 12,\r\n 'd': '将罗马数字转换为阿拉伯数字。',\r\n 'a': '将罗马数字转换为阿拉伯数字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要转换格式的罗马数字',\r\n 'example': '\"XIV\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ROMAN',\r\n 't': 12,\r\n 'd': '将数字格式设置为罗马数字形式。',\r\n 'a': '将数字格式设置为罗马数字形式。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要设置格式的数字,介于1到3999之间(包括这两个数字)。',\r\n 'example': '499',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'REGEXEXTRACT',\r\n 't': 12,\r\n 'd': '按照正则表达式提取匹配的子串。',\r\n 'a': '按照正则表达式提取匹配的子串。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '输入文本。',\r\n 'example': '\"Needle in a haystack\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'regular_expression',\r\n 'detail': '此函数将返回文本中符合此表达式的第一个子串。',\r\n 'example': '\".e{2}dle\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REGEXMATCH',\r\n 't': 12,\r\n 'd': '判断一段文本是否与正则表达式相匹配。',\r\n 'a': '判断一段文本是否与正则表达式相匹配。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要用正则表达式测试的文本。',\r\n 'example': '\"Spreadsheets\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'regular_expression',\r\n 'detail': '用来测试文本的正则表达式。',\r\n 'example': '\"S.r\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REGEXREPLACE',\r\n 't': 12,\r\n 'd': '使用正则表达式将文本字符串中的一部分替换为其他文本字符串。',\r\n 'a': '使用正则表达式将文本字符串中的一部分替换为其他文本字符串。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要对其局部进行替换操作的文本。',\r\n 'example': '\"Spreadsheets\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'regular_expression',\r\n 'detail': '正则表达式。 text 中所有匹配的实例都将被替换。',\r\n 'example': '\"S.*d\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'replacement',\r\n 'detail': '要插入到原有文本中的文本。',\r\n 'example': '\"Bed\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'T',\r\n 't': 12,\r\n 'd': '返回文本格式的字符串参数。',\r\n 'a': '返回文本格式的字符串参数。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要转换为文本的参数。\\n\\n如果值为文本,T将返回值本身。\\n\\n如果值为指向包含文本的单元格的引用,T将返回值中的内容。\\n\\n如果值为错误值或包含错误值的单元格,T将返回该错误值。\\n\\n对于所有其他情况,T将返回空串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FIXED',\r\n 't': 12,\r\n 'd': '以固定的小数位数设置数字的格式。',\r\n 'a': '以固定的小数位数设置数字的格式。',\r\n 'm': [1, 3],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '要进行舍入并转换为文本的数字。',\r\n 'example': '3.141592653',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'decimals',\r\n 'detail': '[可选 - 默认值为2] - 结果中要显示的小数位数。\\n\\n如果数值的有效位数小于小数位数,将以零填充。如果数值的有效位数大于小数位数,则将其舍入到所需的小数位数而不是将其截断。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'no_commas',\r\n 'detail': '[可选 - 默认值为FALSE()] - 一个逻辑值,如果为 TRUE(),则会禁止 FIXED 在返回的文本中包含逗号。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FIND',\r\n 't': 12,\r\n 'd': '返回字符串在文本中首次出现的位置(区分大小写)。',\r\n 'a': '返回字符串在文本中首次出现的位置(区分大小写)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'find_text',\r\n 'detail': '要在要搜索的文本中查找的字符串。',\r\n 'example': '\"n\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'within_text',\r\n 'detail': '要在其中搜索搜索字符串的首次出现位置的文本。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'start_num',\r\n 'detail': '[可选 - 默认值为1] - 要在要搜索的文本中开始搜索的字符位置。',\r\n 'example': '14',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FINDB',\r\n 't': 12,\r\n 'd': '返回某个字符串在文本中首次出现的位置(每个双字节字符占两个位置)。',\r\n 'a': '返回某个字符串在文本中首次出现的位置(每个双字节字符占两个位置)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'find_text',\r\n 'detail': '要在要搜索的文本中查找的字符串。',\r\n 'example': '\"新\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'within_text',\r\n 'detail': '要在其中搜索搜索字符串的首次出现位置的文本。',\r\n 'example': '\"农历新年\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'start_num',\r\n 'detail': '[可选 - 默认值为 1] - 要在要搜索的文本中开始搜索的字符位置。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'JOIN',\r\n 't': 12,\r\n 'd': '将一个或多个使用指定定界符的一维数组的元素连接到一起。',\r\n 'a': '将一个或多个使用指定定界符的一维数组的元素连接到一起。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name': 'separator',\r\n 'detail': '置于相互连接的值之间的字符或字符串。\\n\\n定界符可以为空,例如JOIN(,{1,2,3})。',\r\n 'example': '\" and-a \"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'array1',\r\n 'detail': '要使用定界符连接的一个或多个值。',\r\n 'example': '{1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'array2, ...',\r\n 'detail': '[可选] - 要使用定界符连接的其他值或数组。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LEFT',\r\n 't': 12,\r\n 'd': '从文本字符串的第一个字符开始返回指定个数的字符。',\r\n 'a': '从文本字符串的第一个字符开始返回指定个数的字符。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '包含要提取的字符的文本字符串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'num_chars',\r\n 'detail': '[可选 - 默认值为1] - 指定要由 LEFT 提取的字符的数量。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RIGHT',\r\n 't': 12,\r\n 'd': '根据所指定的字符数返回文本字符串中最后一个或多个字符。',\r\n 'a': '根据所指定的字符数返回文本字符串中最后一个或多个字符。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '包含要提取的字符的文本字符串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'num_chars',\r\n 'detail': '[可选 - 默认值为1] - 指定要由 RIGHT 提取的字符的数量。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MID',\r\n 't': 12,\r\n 'd': '返回文本字符串中从指定位置开始的特定数目的字符。',\r\n 'a': '返回文本字符串中从指定位置开始的特定数目的字符。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '包含要提取的字符的文本字符串。',\r\n 'example': '\"get this\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'start_num',\r\n 'detail': '要从字符串中开始提取的位置。字符串中第一个字符的索引为1。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'num_chars',\r\n 'detail': '指定要由 MID 提取的字符的数量。\\n\\n如果提取的字符数尚不足提取长度个字符时就到达了字符串尾部,则MID返回从开始位置到字符串尾部的字符。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LEN',\r\n 't': 12,\r\n 'd': '返回给定字符串的长度。',\r\n 'a': '返回给定字符串的长度。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要返回其长度的字符串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LENB',\r\n 't': 12,\r\n 'd': '返回文本中所包含的字符数。与双字节字符集(DBCS)一起使用。',\r\n 'a': '返回文本中所包含的字符数。与双字节字符集(DBCS)一起使用。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要返回其字节数的字符串。(一个汉字为两个字节数)',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LOWER',\r\n 't': 12,\r\n 'd': '将指定字符串中的字母转换为小写。',\r\n 'a': '将指定字符串中的字母转换为小写。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要转换为小写的字符串。',\r\n 'example': '\"LOREM IPSUM\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'UPPER',\r\n 't': 12,\r\n 'd': '将指定字符串中的字母转换为大写。',\r\n 'a': '将指定字符串中的字母转换为大写。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要转换为大写的字符串。',\r\n 'example': '\"lorem ipsum\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EXACT',\r\n 't': 12,\r\n 'd': '比较两个字符串是否相同。',\r\n 'a': '比较两个字符串是否相同。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'text1',\r\n 'detail': '要比较的第一个字符串。',\r\n 'example': 'A1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'text2',\r\n 'detail': '要比较的第二个字符串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REPLACE',\r\n 't': 12,\r\n 'd': '将文本字符串的一部分替换为其他文本字符串。',\r\n 'a': '将文本字符串的一部分替换为其他文本字符串。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name': 'old_text',\r\n 'detail': '要对其局部进行替换操作的文本。',\r\n 'example': '\"Spreadsheets\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'start_num',\r\n 'detail': '开始进行替换操作的位置(文本开头位置为 1)。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'num_chars',\r\n 'detail': '要在文本中替换的字符个数。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'new_text',\r\n 'detail': '要插入到原有文本中的文本。',\r\n 'example': '\"Bed\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REPT',\r\n 't': 12,\r\n 'd': '返回指定文本的多次重复。',\r\n 'a': '返回指定文本的多次重复。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要重复的字符或字符串。',\r\n 'example': '\"ha\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'number_times',\r\n 'detail': '要重复的文本要在返回值中出现的次数。\\n\\n最大重复次数为100。即使重复次数大于100,REPT也仅将相应文本重复100次。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SEARCH',\r\n 't': 12,\r\n 'd': '返回字符串在文本中首次出现的位置(不区分大小写)。',\r\n 'a': '返回字符串在文本中首次出现的位置(不区分大小写)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'find_text',\r\n 'detail': '要在要搜索的文本中查找的字符串。',\r\n 'example': '\"n\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'within_text',\r\n 'detail': '要在其中搜索搜索字符串的首次出现位置的文本。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'start_num',\r\n 'detail': '[ 可选 - 默认值为1 ] - 要在要搜索的文本中开始搜索的字符位置。',\r\n 'example': '14',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUBSTITUTE',\r\n 't': 12,\r\n 'd': '在文本字符串中用 new_text 替换 old_text。',\r\n 'a': '在文本字符串中用 new_text 替换 old_text。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '需要替换其中字符的文本,或对含有文本(需要替换其中字符)的单元格的引用。',\r\n 'example': '\"search for it\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'old_text',\r\n 'detail': '需要替换的文本。',\r\n 'example': '\"search for\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'new_text',\r\n 'detail': '用于替换 old_text 的文本。',\r\n 'example': '\"Google\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'instance_num',\r\n 'detail': '[ 可选 ] - 指定要用 new_text 替换 old_text 的事件。 如果指定了 instance_num,则只有满足要求的 old_text 被替换。 否则,文本中出现的所有 old_text 都会更改为 new_text。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CLEAN',\r\n 't': 12,\r\n 'd': '移除文本中的不可打印 ASCII 字符后将其返回。',\r\n 'a': '移除文本中的不可打印 ASCII 字符后将其返回。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要移除其中不可打印字符的文本。',\r\n 'example': '\"AF\"&CHAR(31)',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TEXT',\r\n 't': 12,\r\n 'd': '按照指定格式将数字转换为文本。',\r\n 'a': '按照指定格式将数字转换为文本。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要设置格式的数字、日期或时间。',\r\n 'example': '1.23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'format_text',\r\n 'detail': '以括号括起来的模式串,将按该模式设置数字的格式。\\n\\n0表示在数值位数少于格式指定的位数时必定以零填充。例如,TEXT(12.3,\"000.00\")将返回012.30。当数值的小数位数超过模式指定的小数位数时,四舍五入为指定的小数位数。例如,TEXT(12.305,\"00.00\")将返回12.31。\\n\\n#类似于0,但并不是在小数点的两侧都以零填充。例如,TEXT(12.3,\"###.##\")将返回12.3。',\r\n 'example': '\"$0.00\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TRIM',\r\n 't': 12,\r\n 'd': '删除指定字符串前后的空格。',\r\n 'a': '删除指定字符串前后的空格。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要修剪的字符串或指向包含该字符串的单元格的引用。',\r\n 'example': '\" lorem ipsum\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'VALUE',\r\n 't': 12,\r\n 'd': '将可识别的任何日期、时间或数字格式的字符串转换为数字。',\r\n 'a': '将可识别的任何日期、时间或数字格式的字符串转换为数字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '包含要转换的值的字符串。',\r\n 'example': '\"123\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PROPER',\r\n 't': 12,\r\n 'd': '将指定字符串中每个单词的首字母转为大写。',\r\n 'a': '将指定字符串中每个单词的首字母转为大写。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'text',\r\n 'detail': '要转换的文本,其中每个单词的首字母都将转为大写,所有其他字母则转为小写。',\r\n 'example': '\"united states\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CONVERT',\r\n 't': 13,\r\n 'd': '将数字从一种度量系统转换为另一种度量系统。',\r\n 'a': '将数字从一种度量系统转换为另一种度量系统。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'number',\r\n 'detail': '是以 from_unit 为单位的需要进行转换的数值。',\r\n 'example': '5.1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'from_unit',\r\n 'detail': '是数值的单位。',\r\n 'example': '\"g\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'to_unit',\r\n 'detail': '是结果的单位。',\r\n 'example': '\"kg\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'SUMX2MY2',\r\n 't': 14,\r\n 'd': '返回两数组中对应数值的平方差之和。',\r\n 'a': '返回两数组中对应数值的平方差之和。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array_x',\r\n 'detail': '第一个数组或数值区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'array_y',\r\n 'detail': '第二个数组或数值区域。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMX2PY2',\r\n 't': 14,\r\n 'd': '返回两数组中对应数值的平方和之和。',\r\n 'a': '返回两数组中对应数值的平方和之和。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array_x',\r\n 'detail': '第一个数组或数值区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'array_y',\r\n 'detail': '第二个数组或数值区域。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMXMY2',\r\n 't': 14,\r\n 'd': '返回两数组中对应数值之差的平方和。',\r\n 'a': '返回两数组中对应数值之差的平方和。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array_x',\r\n 'detail': '第一个数组或数值区域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'array_y',\r\n 'detail': '第二个数组或数值区域。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TRANSPOSE',\r\n 't': 14,\r\n 'd': '将数组或单元格范围的行列转置。',\r\n 'a': '将数组或单元格范围的行列转置。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '要将其行列互换的数组或范围。',\r\n 'example': '{1,2}',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'TREND',\r\n 't': 14,\r\n 'd': '返回线性趋势值。',\r\n 'a': '返回线性趋势值。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name': 'known_y',\r\n 'detail': '关系表达式 y = mx + b 中已知的 y 值集合。\\n\\n如果 known_y 为二维数组或范围,则 known_x 的维数必须与之相同,或者省略此参数。\\n\\n如果 known_y 为一维数组或范围,known_x 则可代表二维数组或范围中的多个自变量。也就是说,如果 known_y 为单行,则将 known_x 中的每行解释为各自独立的值,类似情况也适用于 known_y 为单列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'known_x',\r\n 'detail': '[可选 - 默认该数组为{1,2,3,...},其大小与 known_y 相同] - 关系表达式 y = mx + b 中已知的可选 x 值集合。\\n\\n如果 known_y 为一维数组或范围,known_x 则可代表二维数组或范围中的多个自变量。也就是说,如果 known_y 为单行,则将 known_x 中的每行解释为各自独立的值,类似情况也适用于 known_y 为单列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'new_x',\r\n 'detail': '[可选 - 默认与 known_x 相同] - 需要函数 TREND 返回对应 y 值的新 x 值。',\r\n 'example': 'A11:A13',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'const',\r\n 'detail': '[可选 - 默认值为TRUE()] - 一个逻辑值,用于指定是否将常量 b 强制设为 0。\\n\\nTRUE() 表示 b 将按正常计算;\\n\\nFALSE() 表示 b 将被设为 0(零),m 将被调整以使 y = mx。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FREQUENCY',\r\n 't': 14,\r\n 'd': '计算数值在某个区域内的出现频率,然后返回一个垂直数组。',\r\n 'a': '计算数值在某个区域内的出现频率,然后返回一个垂直数组。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'data_array',\r\n 'detail': '要对其频率进行计数的一组数值或对这组数值的引用。',\r\n 'example': 'A2:A40',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'bins_array',\r\n 'detail': '要将 data_array 中的值插入到的间隔数组或对间隔的引用。\\n\\n为清晰起见,应将类别排序,但如果未排序,FREQUENCY会在内部对这些指定的值进行排序并返回正确结果。',\r\n 'example': 'B2:B5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GROWTH',\r\n 't': 14,\r\n 'd': '使用现有数据计算预测的指数等比。',\r\n 'a': '使用现有数据计算预测的指数等比。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name': 'known_y',\r\n 'detail': '关系表达式 y = b*m^x 中已知的 y 值集合。\\n\\n如果已知数据_y为二维数组或范围,则已知数据_x的维数必须与之相同,或者省略此参数。\\n\\n如果已知数据_y为一维数组或范围,已知数据_x则可代表二维数组或范围中的多个自变量。也就是说,如果已知数据_y为单行,则将已知数据_x中的每行解释为各自独立的值,类似情况也适用于已知数据_y为单列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'known_x',\r\n 'detail': '[可选 - 默认该数组为{1,2,3,...},其大小与 known_y 相同] - 关系表达式 y = b*m^x 中已知的可选 x 值集合。\\n\\n如果已知数据_y为一维数组或范围,已知数据_x则可代表二维数组或范围中的多个自变量。也就是说,如果已知数据_y为单行,则将已知数据_x中的每行解释为各自独立的值,类似情况也适用于已知数据_y为单列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'new_x',\r\n 'detail': '[可选 - 默认与 known_x 相同] - 需要函数 GROWTH 返回对应 y 值的新 x 值。',\r\n 'example': 'A11:A13',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'const',\r\n 'detail': '[可选 - 默认值为TRUE()] -一个逻辑值,用于指定是否将常量 b 强制设为 1。\\n\\nTRUE() 表示 b 将按正常计算;\\n\\nFALSE() 表示 b 将被设为 1,m 将被调整以使 y = m^x。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LINEST',\r\n 't': 14,\r\n 'd': '可通过使用最小二乘法计算与现有数据最佳拟合的直线,来计算某直线的统计值,然后返回描述此直线的数组。',\r\n 'a': '可通过使用最小二乘法计算与现有数据最佳拟合的直线,来计算某直线的统计值,然后返回描述此直线的数组。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name': 'known_y',\r\n 'detail': '关系表达式 y = mx + b 中已知的 y 值集合。\\n\\n如果 known_y 为二维数组或范围,则 known_x 的维数必须与之相同,或者省略此参数。\\n\\n如果 known_y 为一维数组或范围,known_x 则可代表二维数组或范围中的多个自变量。也就是说,如果 known_y 为单行,则将 known_x 中的每行解释为各自独立的值,类似情况也适用于 known_y 为单列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'known_x',\r\n 'detail': '[可选 - 默认该数组为{1,2,3,...},其大小与 known_y 相同] - 关系表达式 y = mx + b 中已知的可选 x 值集合。\\n\\n如果 known_y 为一维数组或范围,known_x 则可代表二维数组或范围中的多个自变量。也就是说,如果 known_y 为单行,则将 known_x 中的每行解释为各自独立的值,类似情况也适用于 known_y 为单列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'const',\r\n 'detail': '[可选 - 默认值为TRUE()] - 一个逻辑值,用于指定是否将常量 b 强制设为 0。\\n\\nTRUE() 表示 b 将按正常计算;\\n\\nFALSE() 表示 b 将被设为 0(零),m 将被调整以使 y = mx。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'stats',\r\n 'detail': '[可选 - 默认值为FALSE()] - 一个逻辑值,用于指定是否返回附加回归统计值。\\n\\n如果详细为TRUE,除了对应于每个自变量的一组线性系数和y截距之外,LINEST还返回以下信息:\\n\\n每项系数和截距的标准误差、\\n\\n限定系数(介于0和1之间,1表示完全相关)、\\n\\n因变量值的标准误差、\\n\\nF统计或F观测值,指示所观测到的因变量和自变量变量之间的关系是随机的还是线性的、\\n\\n自由度,用于在参照表中查找F统计值以估算可信度、\\n\\n回归平方和,以及\\n\\n残差平方和。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LOGEST',\r\n 't': 14,\r\n 'd': '在回归分析中,计算最符合数据的指数回归拟合曲线,并返回描述该曲线的数值数组。',\r\n 'a': '在回归分析中,计算最符合数据的指数回归拟合曲线,并返回描述该曲线的数值数组。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name': 'known_y',\r\n 'detail': '关系表达式 y = mx + b 中已知的 y 值集合。\\n\\n如果 known_y 为二维数组或范围,则 known_x 的维数必须与之相同,或者省略此参数。\\n\\n如果 known_y 为一维数组或范围,known_x 则可代表二维数组或范围中的多个自变量。也就是说,如果 known_y 为单行,则将 known_x 中的每行解释为各自独立的值,类似情况也适用于 known_y 为单列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'known_x',\r\n 'detail': '[可选 - 默认该数组为{1,2,3,...},其大小与 known_y 相同] - 关系表达式 y = mx + b 中已知的可选 x 值集合。\\n\\n如果 known_y 为一维数组或范围,known_x 则可代表二维数组或范围中的多个自变量。也就是说,如果 known_y 为单行,则将 known_x 中的每行解释为各自独立的值,类似情况也适用于 known_y 为单列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'const',\r\n 'detail': '[可选 - 默认值为TRUE()] - 一个逻辑值,用于指定是否将常量 b 强制设为 0。\\n\\nTRUE() 表示 b 将按正常计算;\\n\\nFALSE() 表示 b 将被设为 0(零),m 将被调整以使 y = mx。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'stats',\r\n 'detail': '[可选 - 默认值为FALSE()] - 一个逻辑值,用于指定是否返回附加回归统计值。\\n\\n如果详细为TRUE,则除了为每个自变量和系数 b 返回一组指数值之外,LOGEST 还将返回以下数据:\\n\\n每项指数和系数的标准误差、\\n\\n限定系数(介于 0 和 1 之间,1 表示完全相关)、\\n\\n因变量值的标准误差、\\n\\nF 统计或 F 观测值,指示所观测到的因变量和自变量之间的关系是随机的还是指数的、\\n\\n自由度 - 用于在参照表中查找 F 统计值以估算可信度、\\n\\n回归平方和,以及\\n\\n残差平方和。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'MDETERM',\r\n 't': 14,\r\n 'd': '返回一个数组的矩阵行列式的值。',\r\n 'a': '返回一个数组的矩阵行列式的值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '行数和列数相等的数值数组。',\r\n 'example': 'A1:D4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MINVERSE',\r\n 't': 14,\r\n 'd': '返回数组中存储的矩阵的逆矩阵。',\r\n 'a': '返回数组中存储的矩阵的逆矩阵。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '行数和列数相等的数值数组。',\r\n 'example': 'A1:D4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MMULT',\r\n 't': 14,\r\n 'd': '返回两个数组的矩阵乘积。结果矩阵的行数与 array1 的行数相同,矩阵的列数与 array2 的列数相同。',\r\n 'a': '返回两个数组的矩阵乘积。结果矩阵的行数与 array1 的行数相同,矩阵的列数与 array2 的列数相同。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'array1',\r\n 'detail': '要进行矩阵乘法运算的第一个矩阵数组。\\n\\narray1 列数必须与 array2 的行数相同',\r\n 'example': 'A1:B3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'array2',\r\n 'detail': '要进行矩阵乘法运算的第二个矩阵数组。\\n\\narray2 的行数必须与 array1 列数相同',\r\n 'example': 'C1:F2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMPRODUCT',\r\n 't': 14,\r\n 'd': '在给定的几组数组中,将数组间对应的元素相乘,并返回乘积之和。',\r\n 'a': '在给定的几组数组中,将数组间对应的元素相乘,并返回乘积之和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name': 'array1',\r\n 'detail': '其相应元素需要进行相乘并求和的第一个数组参数。',\r\n 'example': 'A2:C5',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'array2',\r\n 'detail': '[可选] - 其相应元素需要进行相乘并求和的其它数组参数。',\r\n 'example': 'D2:F5',\r\n 'require': 'o',\r\n 'repeat': 'y',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ISFORMULA',\r\n 't': 15,\r\n 'd': '检查公式是否位于引用的单元格中。',\r\n 'a': '检查公式是否位于引用的单元格中。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'cell',\r\n 'detail': '要检查是否存在公式的单元格。\\n\\n如果 cell 为包含公式的单元格,则 ISFORMULA 将返回 TRUE。如果 cell 为相应单元格范围,则当该范围内的首个单元格包含公式时,系统会返回 TRUE。如果是任何其他值,系统都将返回 FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'CELL',\r\n 't': 15,\r\n 'd': '返回有关单元格的格式、位置或内容的信息。',\r\n 'a': '返回有关单元格的格式、位置或内容的信息。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name': 'info_type',\r\n 'detail': '一个文本值,指定要返回的单元格信息的类型。',\r\n 'example': '\"type\"',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'reference',\r\n 'detail': '需要其相关信息的单元格。',\r\n 'example': 'C2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'NA',\r\n 't': 15,\r\n 'd': '返回错误值 #N/A。',\r\n 'a': '返回错误值 #N/A。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'ERROR_TYPE',\r\n 't': 15,\r\n 'd': '返回与其他单元格中的错误值相对应的数字。',\r\n 'a': '返回与其他单元格中的错误值相对应的数字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'error_val',\r\n 'detail': '用于查找错误号的单元格,虽然您也可以直接提供错误值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISBLANK',\r\n 't': 15,\r\n 'd': '检查所引用的单元格是否为空。',\r\n 'a': '检查所引用的单元格是否为空。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '对要检查其是否为空的单元格的引用。\\n\\n如果是空单元格,则 TRUE;否则返回 FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'ISERR',\r\n 't': 15,\r\n 'd': '检查某个值是否为 #N/A 以外的错误值。',\r\n 'a': '检查某个值是否为 #N/A 以外的错误值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要验证其是否为#N/A以外的错误类型的值。\\n\\n如果值是除#N/A之外的任何错误(包括#DIV/0!、#NAME?、#NULL!、#NUM!、#VALUE!和#REF!),ISERR将返回TRUE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISERROR',\r\n 't': 15,\r\n 'd': '检查某个值是否为错误值。',\r\n 'a': '检查某个值是否为错误值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要验证其是否为错误类型的值。\\n\\n只要值是某种错误值(包括#DIV/0!、#N/A、#NAME?、#NULL!、#NUM!、#VALUE!和#REF!),ISERROR就会返回TRUE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISLOGICAL',\r\n 't': 15,\r\n 'd': '检查某个值是 TRUE 还是 FALSE。',\r\n 'a': '检查某个值是 TRUE 还是 FALSE。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要验证其为逻辑TRUE还是逻辑FALSE的值。\\n\\n*如果值为TRUE或FALSE,或为指向值为TRUE或FALSE的单元格的引用,ISLOGICAL将返回TRUE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISNA',\r\n 't': 15,\r\n 'd': '检查某个值是否为错误值 #N/A。',\r\n 'a': '检查某个值是否为错误值 #N/A。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要与错误值#N/A进行比较的值。\\n\\n*如果值为#N/A或指向包含#N/A的单元格的引用,则ISNA将返回TRUE,否则返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISNONTEXT',\r\n 't': 15,\r\n 'd': '检查某个值是否为非文本。',\r\n 'a': '检查某个值是否为非文本。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要检查的文本。\\n\\n*如果参数为文本值或指向包含文本的单元格的引用,ISNONTEXT将返回FALSE,否则返回TRUE。\\n\\n当值为指向空单元格的引用时,ISNONTEXT会返回TRUE。\\n\\n当值为空字符串时,ISNONTEXT将返回FALSE,因为空串被视作文本。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISNUMBER',\r\n 't': 15,\r\n 'd': '检查某个值是否为数字。',\r\n 'a': '检查某个值是否为数字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要验证其是否为数字的值。\\n\\n*如果参数为数字或指向内容为数字值的单元格的引用,ISNUMBER将返回TRUE,否则返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISREF',\r\n 't': 15,\r\n 'd': '检查某个值是否为有效的单元格引用。',\r\n 'a': '检查某个值是否为有效的单元格引用。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要验证其是否为单元格引用的值。\\n\\n*如果参数是有效的单元格引用,ISREF将返回TRUE,否则返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'ISTEXT',\r\n 't': 15,\r\n 'd': '检查某个值是否为文本。',\r\n 'a': '检查某个值是否为文本。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要验证其是否为文本的值。\\n\\n如果参数为文本值或指向包含文本值的单元格的引用,ISTEXT将返回TRUE,否则返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TYPE',\r\n 't': 15,\r\n 'd': '返回数值的类型。',\r\n 'a': '返回数值的类型。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要确定其类型的数据。\\n\\n数字 返回 1;\\n\\n文本 返回 2;\\n\\n逻辑值 返回 4;\\n\\n错误值 返回 16;\\n\\n数组 返回 64;',\r\n 'example': 'C4',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'N',\r\n 't': 15,\r\n 'd': '返回转化为数值后的值。',\r\n 'a': '返回转化为数值后的值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要转换为数字的参数。\\n\\n如果值为数字,则返回该数字。\\n\\n如果值为日期,则返回该日期的序列号。\\n\\n如果值为TRUE,则返回1。\\n\\n如果值为FALSE,则返回0。\\n\\n如果值为错误值,则返回错误值。\\n\\n如果值为其他值,则返回0。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TO_DATE',\r\n 't': 16,\r\n 'd': '将指定的数字转换为日期。',\r\n 'a': '将指定的数字转换为日期。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要转换为日期的参数或其单元格引用。\\n\\n如果值为数字或指向内容为数值的单元格的引用,TO_DATE会将值转换为相应的日期并返回,值代表从十二月30日到对应的日期之间的天数,\\n\\n负值表示对应的日期在十二月30日之前,而小数值则代表一天中从午夜算起的时间。\\n如果值不是数字或指向内容为数值的单元格的引用,则TO_DATE将在不做任何修改的情况下返回值。',\r\n 'example': '25405',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TO_PURE_NUMBER',\r\n 't': 16,\r\n 'd': '将给定的日期/时间、百分比、货币金额或其他格式的数值转换为不带格式的纯数字。',\r\n 'a': '将给定的日期/时间、百分比、货币金额或其他格式的数值转换为不带格式的纯数字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要转换为纯数字的参数或其单元格引用。\\n\\n如果值为数字或指向包含数值的单元格的引用,TO_PURE_NUMBER将以不带任何格式与解释的形式返回值。\\n\\n如果值不是数字或指向内容为数值的单元格的引用,则TO_PERCENT将在不做任何修改的情况下返回值。',\r\n 'example': '50%',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TO_TEXT',\r\n 't': 16,\r\n 'd': '将给定的数字值转换为文本格式。',\r\n 'a': '将给定的数字值转换为文本格式。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要转换为文本的参数或其单元格引用。\\n\\n如果值为数字或指向包含数值的单元格的引用,TO_TEXT将返回字符串形式的值,并保持现有格式。即原为货币的仍为货币,原为十进制数的仍为十进制数,原为百分比的仍为百分比,原为日期的仍为日期。\\n\\n如果值不是数字或指向内容为数值的单元格的引用,则TO_TEXT将在不做任何修改的情况下返回值。',\r\n 'example': '24',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TO_DOLLARS',\r\n 't': 16,\r\n 'd': '将指定的数字转换为美元金额。',\r\n 'a': '将指定的数字转换为美元金额。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要转换为美元金额的参数或其单元格引用。\\n\\n如果值不是数字或指向内容为数值的单元格的引用,则 TO_DOLLARS 将在不做任何修改的情况下返回值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TO_PERCENT',\r\n 't': 16,\r\n 'd': '将指定的数字转换为百分比。',\r\n 'a': '将指定的数字转换为百分比。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name': 'value',\r\n 'detail': '要转换为百分比的参数或其单元格引用。\\n\\n如果值为数字或指向包含数值的单元格的引用,TO_PERCENT会以1 = 100%为标准,将值转换为百分比。\\n\\n如果值不是数字或指向内容为数值的单元格的引用,则TO_PERCENT将在不做任何修改的情况下返回值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DGET',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,从列表或数据库的列中提取符合指定条件的单个值。',\r\n 'a': '使用 SQL 式查询,从列表或数据库的列中提取符合指定条件的单个值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DMAX',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的最大数字。',\r\n 'a': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的最大数字。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DMIN',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的最小数字。',\r\n 'a': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的最小数字。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DAVERAGE',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,对列表或数据库中满足指定条件的记录字段(列)中的数值求平均值。',\r\n 'a': '使用 SQL 式查询,对列表或数据库中满足指定条件的记录字段(列)中的数值求平均值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DCOUNT',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中包含数字的单元格的个数。',\r\n 'a': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中包含数字的单元格的个数。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DCOUNTA',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的非空单元格的个数。',\r\n 'a': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的非空单元格的个数。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DPRODUCT',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的数值的乘积。',\r\n 'a': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的数值的乘积。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DSTDEV',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回利用列表或数据库中满足指定条件的记录字段(列)中的数字作为一个样本估算出的总体标准偏差。',\r\n 'a': '使用 SQL 式查询,返回利用列表或数据库中满足指定条件的记录字段(列)中的数字作为一个样本估算出的总体标准偏差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DSTDEVP',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回利用列表或数据库中满足指定条件的记录字段(列)中的数字作为样本总体计算出的总体标准偏差。',\r\n 'a': '使用 SQL 式查询,返回利用列表或数据库中满足指定条件的记录字段(列)中的数字作为样本总体计算出的总体标准偏差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DSUM',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的数字之和。',\r\n 'a': '使用 SQL 式查询,返回列表或数据库中满足指定条件的记录字段(列)中的数字之和。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DVAR',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,返回利用列表或数据库中满足指定条件的记录字段(列)中的数字作为一个样本估算出的总体方差。',\r\n 'a': '使用 SQL 式查询,返回利用列表或数据库中满足指定条件的记录字段(列)中的数字作为一个样本估算出的总体方差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n 'n': 'DVARP',\r\n 't': 17,\r\n 'd': '使用 SQL 式查询,通过使用列表或数据库中满足指定条件的记录字段(列)中的数字计算样本总体的样本总体方差。',\r\n 'a': '使用 SQL 式查询,通过使用列表或数据库中满足指定条件的记录字段(列)中的数字计算样本总体的样本总体方差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name': 'database',\r\n 'detail': '构成列表或数据库的单元格区域,列表的第一行包含每一列的标签。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'field',\r\n 'detail': '指定 database 中的哪一列包含要提取和用于计算的值。\\n\\nfield 可以是与 database 第一行中某个列标题对应的文本标签,也可以是指定相关列的数字索引,第一列的索引值为 1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'criteria',\r\n 'detail': '包含所指定条件的单元格区域。计算之前将使用这些条件来过滤 database 中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }]\r\n }, {\r\n \"n\": \"AGE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根据中国身份证号计算出年龄。支持15位或18位身份证\",\r\n \"a\": \"根据身份证号得到年龄。\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": \"A1\",\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"截止日期\",\r\n \"example\": '\"2017-10-01\"',\r\n \"detail\": \"年龄计算的截止日期或范围,默认为当日。\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedatetime\"\r\n }]\r\n },\r\n // SEX_BY_IDCARD\r\n {\r\n \"n\": \"SEX_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根据中国身份证号计算出性别。支持15位或18位身份证\",\r\n \"a\": \"根据身份证号得到性别。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n // BIRTHDAY_BY_IDCARD\r\n {\r\n \"n\": \"BIRTHDAY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根据中国身份证号计算出生日。支持15位或18位身份证\",\r\n \"a\": \"根据身份证号得到生日。\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"生日格式\",\r\n \"example\": '0',\r\n \"detail\": \"日期类型,默认0:[1900/01/01], 1:[1900-01-01], 2:[1900年1月1日]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n // PROVINCE_BY_IDCARD\r\n {\r\n \"n\": \"PROVINCE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根据中国身份证号计算出籍贯的省份。支持15位或18位身份证\",\r\n \"a\": \"根据身份证号得到籍贯的省份。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n // CITY_BY_IDCARD\r\n {\r\n \"n\": \"CITY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根据中国身份证号计算出籍贯的城市。支持15位或18位身份证\",\r\n \"a\": \"根据身份证号得到籍贯的城市。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n // STAR_BY_IDCARD\r\n {\r\n \"n\": \"STAR_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根据中国身份证号计算出星座。支持15位或18位身份证\",\r\n \"a\": \"根据身份证号得到星座。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n // ANIMAL_BY_IDCARD\r\n {\r\n \"n\": \"ANIMAL_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根据中国身份证号计算出生肖(鼠、牛、虎、兔...)。支持15位或18位身份证\",\r\n \"a\": \"根据身份证号得到生肖。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n // ISIDCARD\r\n {\r\n \"n\": \"ISIDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"验证身份证的格式是否正确。支持15位或18位身份证\",\r\n \"a\": \"验证身份证格式正确性。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"身份证号\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\": \"15位或者18位的身份证号或范围。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n // DM_TEXT_CUTWORD\r\n {\r\n \"n\": \"DM_TEXT_CUTWORD\",\r\n \"t\": \"4\",\r\n \"d\": \"文本分词。把一连串文字拆分为一系列单独词语\",\r\n \"a\": \"中文文本分词。\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"文本\",\r\n \"example\": '\"我来到北京清华大学\"',\r\n \"detail\": \"任意需要分词的文本。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"分词模式\",\r\n \"example\": '0',\r\n \"detail\": \"默认为0[精确模式], 1[全模式], 2[搜索引擎模式]。\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DM_TEXT_TFIDF\r\n {\r\n \"n\": \"DM_TEXT_TFIDF\",\r\n \"t\": \"4\",\r\n \"d\": \"采用tf-idf算法进行关键词提取。从一连串文字中识别关键词\",\r\n \"a\": \"tf-idf关键词识别。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"文本\",\r\n \"example\": '\"我来到北京清华大学\"',\r\n \"detail\": \"任意需要分词的文本。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"关键词个数\",\r\n \"example\": '20',\r\n \"detail\": \"算法返回的关键词个数,默认20\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"语料库\",\r\n \"example\": '1',\r\n \"detail\": \"选择特定领域的语料库,默认0[通用], 1[金融], 2[医疗]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DM_TEXT_TEXTRANK\r\n {\r\n \"n\": \"DM_TEXT_TEXTRANK\",\r\n \"t\": \"4\",\r\n \"d\": \"采用TextRank算法进行关键词提取。从一连串文字中识别关键词\",\r\n \"a\": \"TextRank关键词识别。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"文本\",\r\n \"example\": '\"我来到北京清华大学\"',\r\n \"detail\": \"任意需要分词的文本。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"关键词个数\",\r\n \"example\": '20',\r\n \"detail\": \"算法返回的关键词个数,默认20\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"语料库\",\r\n \"example\": '1',\r\n \"detail\": \"选择特定领域的语料库,默认0[通用], 1[金融], 2[医疗]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_CLOSE\r\n {\r\n \"n\": \"DATA_CN_STOCK_CLOSE\",\r\n \"t\": \"5\",\r\n \"d\": \"根据股票代码和日期,返回A股对应股票收盘价。\",\r\n \"a\": \"返回A股对应股票收盘价。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"股票代码\",\r\n \"example\": '\"000001\"',\r\n \"detail\": \"6位股票代码,必填项。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\": \"股票的交易日,默认为最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"复权除权\",\r\n \"example\": '0',\r\n \"detail\": \"选择股票的除权复权类型,默认0[前复权], 1[原始价格], 2[后复权]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_OPEN\r\n {\r\n \"n\": \"DATA_CN_STOCK_OPEN\",\r\n \"t\": \"5\",\r\n \"d\": \"根据股票代码和日期,返回A股对应股票开盘价。\",\r\n \"a\": \"返回A股对应股票开盘价。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"股票代码\",\r\n \"example\": '\"000001\"',\r\n \"detail\": \"6位股票代码,必填项。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\": \"股票的交易日,默认为最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"复权除权\",\r\n \"example\": '0',\r\n \"detail\": \"选择股票的除权复权类型,默认0[前复权], 1[原始价格], 2[后复权]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_MAX\r\n {\r\n \"n\": \"DATA_CN_STOCK_MAX\",\r\n \"t\": \"5\",\r\n \"d\": \"根据股票代码和日期,返回A股对应股票最高价。\",\r\n \"a\": \"返回A股对应股票最高价。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"股票代码\",\r\n \"example\": '\"000001\"',\r\n \"detail\": \"6位股票代码,必填项。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\": \"股票的交易日,默认为最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"复权除权\",\r\n \"example\": '0',\r\n \"detail\": \"选择股票的除权复权类型,默认0[前复权], 1[原始价格], 2[后复权]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_MIN\r\n {\r\n \"n\": \"DATA_CN_STOCK_MIN\",\r\n \"t\": \"5\",\r\n \"d\": \"根据股票代码和日期,返回A股对应股票最低价。\",\r\n \"a\": \"返回A股对应股票最低价。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"股票代码\",\r\n \"example\": '\"000001\"',\r\n \"detail\": \"6位股票代码,必填项。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\": \"股票的交易日,默认为最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"复权除权\",\r\n \"example\": '0',\r\n \"detail\": \"选择股票的除权复权类型,默认0[前复权], 1[原始价格], 2[后复权]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_VOLUMN\r\n {\r\n \"n\": \"DATA_CN_STOCK_VOLUMN\",\r\n \"t\": \"5\",\r\n \"d\": \"根据股票代码和日期,返回A股对应股票成交量。\",\r\n \"a\": \"返回A股对应股票成交量。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"股票代码\",\r\n \"example\": '\"000001\"',\r\n \"detail\": \"6位股票代码,必填项。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\": \"股票的交易日,默认为最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"复权除权\",\r\n \"example\": '0',\r\n \"detail\": \"选择股票的除权复权类型,默认0[前复权], 1[原始价格], 2[后复权]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_AMOUNT\r\n {\r\n \"n\": \"DATA_CN_STOCK_AMOUNT\",\r\n \"t\": \"5\",\r\n \"d\": \"根据股票代码和日期,返回A股对应股票成交额。\",\r\n \"a\": \"返回A股对应股票成交额。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"股票代码\",\r\n \"example\": '\"000001\"',\r\n \"detail\": \"6位股票代码,必填项。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\": \"股票的交易日,默认为最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"复权除权\",\r\n \"example\": '0',\r\n \"detail\": \"选择股票的除权复权类型,默认0[前复权], 1[原始价格], 2[后复权]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n // ISDATE\r\n {\r\n \"n\": \"ISDATE\",\r\n \"t\": \"6\",\r\n \"d\": \"验证日期的格式是否正确。支持多种日期格式\",\r\n \"a\": \"验证日期格式正确性。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"日期\",\r\n \"example\": '\"1990-01-01\"',\r\n \"detail\": \"日期值,例如1990/01/01, 1990年1月1日等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n //sparklines函数,线图\r\n {\r\n \"n\": \"LINESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的折线图sparklines,用于描述数据的连续走势\",\r\n \"a\": \"生成单元格折线图\",\r\n \"m\": [1, 8],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //lineColor\r\n {\r\n \"name\": \"线条颜色\",\r\n \"example\": '#2ec7c9',\r\n \"detail\": \"线图的线条颜色,可以是否个范围A1、色表索引数值或者具体颜色值,设置为0或false则不显示,支持regx、rgb、rgba等。默认#2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n // {\r\n // \"name\": \"填充颜色\",\r\n // \"example\": '#CCF3F4',\r\n // \"detail\": \"形成面积图,同线条颜色配置,默认0不显示\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // },\r\n //lineWidth\r\n {\r\n \"name\": \"线条粗细\",\r\n \"example\": '1',\r\n \"detail\": \"折线图线段粗细,默认为1px\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //normalRangeMin和normalRangeMax设为相同的值,min、max、avg、median需要计算\r\n {\r\n \"name\": \"辅助线\",\r\n \"example\": 'avg',\r\n \"detail\": \"一条横线,可以是min、max、avg、median、范围或自定义数值,默认0无\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //normalRangeColor\r\n {\r\n \"name\": \"辅助线颜色\",\r\n \"example\": '#000',\r\n \"detail\": \"辅助线的颜色设置,同线条颜色配置,默认#000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //maxSpotColor\r\n {\r\n \"name\": \"最大值标识\",\r\n \"example\": '#fc5c5c',\r\n \"detail\": \"标识线图最大值,同线条颜色配置,默认0不显示\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //minSpotColor\r\n {\r\n \"name\": \"最小值标识\",\r\n \"example\": '#fc5c5c',\r\n \"detail\": \"标识线图最小值,同线条颜色配置,默认0不显示\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //spotRadius\r\n {\r\n \"name\": \"标识大小\",\r\n \"example\": '1.5',\r\n \"detail\": \"最大值和最小值的标识大小设置,默认为1.5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines面积图\r\n {\r\n \"n\": \"AREASPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的面积图sparklines,一般用于描述数据的连续累积值走势\",\r\n \"a\": \"生成单元格面积图\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //lineColor\r\n {\r\n \"name\": \"线条颜色\",\r\n \"example\": '#2ec7c9',\r\n \"detail\": \"线图的线条颜色,可以是否个范围A1、色表索引数值或者具体颜色值,设置为0或false则不显示,支持regx、rgb、rgba等。默认#2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //fillColor\r\n {\r\n \"name\": \"填充颜色\",\r\n \"example\": '#CCF3F4',\r\n \"detail\": \"形成面积图,同线条颜色配置,默认0不显示\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //lineWidth\r\n {\r\n \"name\": \"线条粗细\",\r\n \"example\": '1',\r\n \"detail\": \"折线图线段粗细,默认为1px\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //normalRangeMin和normalRangeMax设为相同的值,min、max、avg、median需要计算\r\n {\r\n \"name\": \"辅助线\",\r\n \"example\": 'avg',\r\n \"detail\": \"一条横线,可以是min、max、avg、median、范围或自定义数值,默认0无\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //normalRangeColor\r\n {\r\n \"name\": \"辅助线颜色\",\r\n \"example\": '#000',\r\n \"detail\": \"辅助线的颜色设置,同线条颜色配置,默认#000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }\r\n // //maxSpotColor\r\n // {\r\n // \"name\": \"最大值标识\",\r\n // \"example\": '#fc5c5c',\r\n // \"detail\": \"标识线图最大值,同线条颜色配置,默认0不显示\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // },\r\n // //minSpotColor\r\n // {\r\n // \"name\": \"最小值标识\",\r\n // \"example\": '#fc5c5c',\r\n // \"detail\": \"标识线图最大值,同线条颜色配置,默认0不显示\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // },\r\n // //spotRadius\r\n // {\r\n // \"name\": \"标识大小\",\r\n // \"example\": '1.5',\r\n // \"detail\": \"最大值和最小值的标识大小设置,默认为1.5\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // }\r\n ]\r\n },\r\n //sparklines柱状图\r\n {\r\n \"n\": \"COLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的垂直柱状图sparklines,一般用于描述离散数据之间的大小情况\",\r\n \"a\": \"生成单元格垂直柱状图\",\r\n \"m\": [1, 6],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\": \"柱条间隔\",\r\n \"example\": '1',\r\n \"detail\": \"柱条之间的间隔距离,默认为1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //barColor\r\n {\r\n \"name\": \"柱条颜色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\": \"线图的线条颜色,可以是否个范围A1、色表索引数值或者具体颜色值,设置为0或false则不显示,支持regx、rgb、rgba等。默认#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //negBarColor\r\n {\r\n \"name\": \"负向柱条颜色\",\r\n \"example\": '#97b552',\r\n \"detail\": \"负向柱条颜色设置,代表负值的颜色,同柱条颜色配置,默认#97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\": \"最大值\",\r\n \"example\": '100',\r\n \"detail\": \"柱图最大值,用于规范柱图长度,默认为自动计算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //colorMap\r\n {\r\n \"name\": \"色板\",\r\n \"example\": '#97b552',\r\n \"detail\": \"调色板可以单独设置每个柱条的颜色,可设置多个,支持两种格式:1颜色例如#000,代表第一个柱的颜色是黑色;2数值范围:颜色,例如-2:#000表示数值为-2的柱为黑色,0:5:#000表示数值0-5的柱为黑色,默认为空\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines累积柱状图\r\n {\r\n \"n\": \"STACKCOLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的累积垂直柱状图sparklines,一般用于描述离散数据多个维度的数值大小\",\r\n \"a\": \"生成单元格累积垂直柱状图\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //stackconfig\r\n {\r\n \"name\": \"按列堆积\",\r\n \"example\": '1',\r\n \"detail\": \"如果需要按行堆积则本项设为false或0,默认为是1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\": \"柱条间隔\",\r\n \"example\": '1',\r\n \"detail\": \"柱条之间的间隔距离,默认为1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\": \"最大值\",\r\n \"example\": '100',\r\n \"detail\": \"累积柱图最大值,用于规范柱图长度,默认为自动计算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //stackedBarColor\r\n {\r\n \"name\": \"累积色板\",\r\n \"example\": '#97b552',\r\n \"detail\": \"调色板可以单独设置每个维度的柱条颜色,可设置为A1:A10等范围,默认为#2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines条形图\r\n {\r\n \"n\": \"BARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的横向条形图sparklines,一般用于描述离散数据之间的大小情况\",\r\n \"a\": \"生成单元格横向条形图\",\r\n \"m\": [1, 6],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\": \"柱条间隔\",\r\n \"example\": '1',\r\n \"detail\": \"柱条之间的间隔距离,默认为1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //barColor\r\n {\r\n \"name\": \"柱条颜色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\": \"线图的线条颜色,可以是否个范围A1、色表索引数值或者具体颜色值,设置为0或false则不显示,支持regx、rgb、rgba等。默认#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //negBarColor\r\n {\r\n \"name\": \"负向柱条颜色\",\r\n \"example\": '#97b552',\r\n \"detail\": \"负向柱条颜色设置,代表负值的颜色,同柱条颜色配置,默认#97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\": \"最大值\",\r\n \"example\": '100',\r\n \"detail\": \"柱图最大值,用于规范柱图长度,默认为自动计算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //colorMap\r\n {\r\n \"name\": \"色板\",\r\n \"example\": '#97b552',\r\n \"detail\": \"调色板可以单独设置每个柱条的颜色,可设置多个,支持两种格式:1颜色例如#000,代表第一个柱的颜色是黑色;2数值范围:颜色,例如-2:#000表示数值为-2的柱为黑色,0:5:#000表示数值0-5的柱为黑色,默认为空\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines累积条形图\r\n {\r\n \"n\": \"STACKBARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的累积横向条形图sparklines,一般用于描述离散数据多个维度的数值大小\",\r\n \"a\": \"生成单元格累积横向条形图\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //stackconfig\r\n {\r\n \"name\": \"按列堆积\",\r\n \"example\": '1',\r\n \"detail\": \"如果需要按行堆积则本项设为false或0,默认为是1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\": \"柱条间隔\",\r\n \"example\": '1',\r\n \"detail\": \"柱条之间的间隔距离,默认为1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\": \"最大值\",\r\n \"example\": '100',\r\n \"detail\": \"累积柱图最大值,用于规范柱图长度,默认为自动计算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //stackedBarColor\r\n {\r\n \"name\": \"累积色板\",\r\n \"example\": '#97b552',\r\n \"detail\": \"调色板可以单独设置每个维度的柱条颜色,可设置为A1:A10等范围,默认为#2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines离散图\r\n {\r\n \"n\": \"DISCRETESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的离散图sparklines,一般用于描述离散数据走势\",\r\n \"a\": \"生成单元格离散图\",\r\n \"m\": [1, 4],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //thresholdValue\r\n {\r\n \"name\": \"分割阈值\",\r\n \"example\": '1',\r\n \"detail\": \"离散图柱形颜色的区分,例如:该值为0,则大于0为蓝色,小于0为红色,默认为0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //lineColor\r\n {\r\n \"name\": \"阈值以上颜色\",\r\n \"example\": '#2ec7c9',\r\n \"detail\": \"线图的线条颜色,可以是否个范围A1、色表索引数值或者具体颜色值,设置为0或false则不显示,支持regx、rgb、rgba等。默认#2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //thresholdColor\r\n {\r\n \"name\": \"阈值以下颜色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\": \"阈值以下柱条颜色设置,同阈值以上颜色,默认#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines三态图\r\n {\r\n \"n\": \"TRISTATESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的三态图sparklines,一般用于描述三种态势的走势例如胜负平\",\r\n \"a\": \"生成单元格三态图\",\r\n \"m\": [1, 6],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\": \"柱条间隔\",\r\n \"example\": '1',\r\n \"detail\": \"柱条之间的间隔距离,默认为1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //posBarColor\r\n {\r\n \"name\": \"柱条颜色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\": \"线图的线条颜色,可以是否个范围A1、色表索引数值或者具体颜色值,设置为0或false则不显示,支持regx、rgb、rgba等。默认#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //negBarColor\r\n {\r\n \"name\": \"负向柱条颜色\",\r\n \"example\": '#97b552',\r\n \"detail\": \"负向柱条颜色设置,代表负值的颜色,同柱条颜色配置,默认#97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //zeroBarColor\r\n {\r\n \"name\": \"零值柱条颜色\",\r\n \"example\": '#999',\r\n \"detail\": \"零值柱条颜色设置,代表0值颜色,同柱条颜色配置,默认#999\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //colorMap\r\n {\r\n \"name\": \"色板\",\r\n \"example\": '#97b552',\r\n \"detail\": \"调色板可以单独设置每个柱条的颜色,可设置多个,支持两种格式:1颜色例如#000,代表第一个柱的颜色是黑色;2数值范围:颜色,例如-2:#000表示数值为-2的柱为黑色,0-5:#000表示数值0-5的柱为黑色,默认为空\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines饼图\r\n {\r\n \"n\": \"PIESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的饼图sparklines,一般用于描述数据占比\",\r\n \"a\": \"生成单元格饼图\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //offset\r\n {\r\n \"name\": \"旋转角度\",\r\n \"example\": '0',\r\n \"detail\": \"饼图的旋转角度,默认为0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //borderWidth\r\n {\r\n \"name\": \"饼图边框\",\r\n \"example\": '0',\r\n \"detail\": \"饼图边框大小,默认为无0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //borderColor\r\n {\r\n \"name\": \"边框颜色\",\r\n \"example\": '#000',\r\n \"detail\": \"饼图边框颜色,默认为#000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //sliceColors\r\n {\r\n \"name\": \"饼图色板\",\r\n \"example\": '#97b552',\r\n \"detail\": \"调色板可以设置切片的颜色,可设置为A1:A10等范围,默认为#2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines箱线图\r\n {\r\n \"n\": \"BOXSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的箱线图sparklines,一般用于描述数据集的统计分布\",\r\n \"a\": \"生成单元格箱线图\",\r\n \"m\": [1, 4],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"数据范围\",\r\n \"example\": 'A1:A20',\r\n \"detail\": \"数据范围,数值才能被有效计算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //outlierIQR,如果为0或false则showOutliers设为false,否则为true\r\n {\r\n \"name\": \"离群点比例\",\r\n \"example\": '1.5',\r\n \"detail\": \"离群点的阈值范围,如果为0或false则不显示,默认为1.5倍\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //target\r\n {\r\n \"name\": \"目标点值\",\r\n \"example\": '10',\r\n \"detail\": \"箱线图上的目标值设置,默认为false不显示\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //spotRadius\r\n {\r\n \"name\": \"数据点大小\",\r\n \"example\": '1.5',\r\n \"detail\": \"目标点和离群点的半径大小设置,默认为1.5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines子弹图\r\n {\r\n \"n\": \"BULLETSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在单元格内的子弹图sparklines,一般用于描述任务达成率\",\r\n \"a\": \"生成单元格子弹图\",\r\n \"m\": [2, 3],\r\n \"p\": [\r\n //目标data1\r\n {\r\n \"name\": \"目标\",\r\n \"example\": '10',\r\n \"detail\": \"达成的目标值,数值才能被有效计算,例如A1, 100等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //目前达成data2\r\n {\r\n \"name\": \"实际完成\",\r\n \"example\": '8',\r\n \"detail\": \"目前完成值,数值才能被有效计算,例如A1, 100等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n },\r\n //对比值datax\r\n {\r\n \"name\": \"对比值\",\r\n \"example\": '12',\r\n \"detail\": \"对比值,例如超额、最低、获奖底线等,数值才能被有效计算,例如A1, 100等。可以设置最多9个对比值\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines组合图,支持多个类型的图画在同一个单元格\r\n {\r\n \"n\": \"COMPOSESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"支持多个类型的图画在同一个单元格,每个参数代表一个sparklines图\",\r\n \"a\": \"组合sparklines图到一个单元格\",\r\n \"m\": [1, 1],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\": \"图设置\",\r\n \"example\": 'PIESPLINES(A1:A20)',\r\n \"detail\": \"sparklines图设置,例如A1:A20, 一个完成的饼图、线图设置等。\",\r\n \"require\": \"m\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }\r\n ]\r\n },\r\n //动态数组公式\r\n {\r\n 'n': 'SORT',\r\n 't': '14',\r\n 'd': '返回数组中元素的排序数组。返回的数组与提供的数组参数形状相同。',\r\n 'a': '返回数组中元素的排序数组。返回的数组与提供的数组参数形状相同。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '要排序的范围或数组。',\r\n 'example': 'A2:A17',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'sort_index',\r\n 'detail': '[可选] - 表示要排序的行或列的数字。(默认row1/col1)',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'sort_order',\r\n 'detail': '[可选] - 表示所需排序顺序的数字;1表示升序(默认),-1表示降序。',\r\n 'example': '-1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'by_col',\r\n 'detail': '[可选] - 表示所需排序方向的逻辑值;按行排序为FALSE()(默认),按列排序为TRUE()。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FILTER',\r\n 't': '14',\r\n 'd': '基于一个布尔(真/假)数组过滤一个数组。',\r\n 'a': '基于一个布尔(真/假)数组过滤一个数组。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '要筛选的数组或范围。',\r\n 'example': 'A5:D20',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'include',\r\n 'detail': '布尔数组,其高度或宽度与数组相同',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'range'\r\n }, {\r\n 'name': 'if_empty',\r\n 'detail': '[可选] - 如果包含数组中的所有值都为空(filter不返回任何值),则返回的值。',\r\n 'example': '\"\"',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'UNIQUE',\r\n 't': '14',\r\n 'd': '返回列表或区域中的唯一值的列表。',\r\n 'a': '返回列表或区域中的唯一值的列表。',\r\n 'm': [1, 3],\r\n 'p': [{\r\n 'name': 'array',\r\n 'detail': '从其返回唯一值的数组或区域。',\r\n 'example': 'A2:B26',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'by_col',\r\n 'detail': '[可选] - 逻辑值,指示如何比较;按行 = FALSE() 或省略;按列 = TRUE()。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }, {\r\n 'name': 'occurs_once',\r\n 'detail': '[可选] - 逻辑值,仅返回唯一值中出现一次 = TRUE();包括所有唯一值 = FALSE() 或省略。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANDARRAY',\r\n 't': '14',\r\n 'd': '返回 0 到 1 之间的随机数字数组。',\r\n 'a': '返回 0 到 1 之间的随机数字数组。',\r\n 'm': [0, 2],\r\n 'p': [{\r\n 'name': 'rows',\r\n 'detail': '[可选] - 要返回的行数。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cols',\r\n 'detail': '[可选] - 要返回的列数。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SEQUENCE',\r\n 't': '14',\r\n 'd': '生成数字序列的列表。',\r\n 'a': '生成数字序列的列表。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name': 'rows',\r\n 'detail': '要返回的行数。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'cols',\r\n 'detail': '[可选] - 要返回的列数。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'start',\r\n 'detail': '[可选] - 序列中的第一个数字。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }, {\r\n 'name': 'step',\r\n 'detail': '[可选] - 序列中每个序列值的增量。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat': 'n',\r\n 'type': 'rangenumber'\r\n }]\r\n },\r\n {\r\n \"n\": \"EVALUATE\",\r\n \"t\": \"3\",\r\n \"d\": \"对以文字表示的公式或者表达式求值,并返回结果。\",\r\n \"a\": \"根据文字公式或者表达式求值。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"公式\",\r\n \"example\": '\"A1+5*2^2\"',\r\n \"detail\": \"公式或表达式\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n ],\r\n toolbar: {\r\n undo: '撤销',\r\n redo: '重做',\r\n paintFormat: '格式刷',\r\n currencyFormat: '货币格式',\r\n percentageFormat: '百分比格式',\r\n numberDecrease: '减少小数位数',\r\n numberIncrease: '增加小数位数',\r\n moreFormats: '更多格式',\r\n font: '字体',\r\n fontSize: '字号大小',\r\n bold: '粗体 (Ctrl+B)',\r\n italic: '斜体 (Ctrl+I)',\r\n strikethrough: '删除线 (Alt+Shift+5)',\r\n underline: '下划线',\r\n textColor: '文本颜色',\r\n chooseColor: '颜色选择',\r\n resetColor: '重置颜色',\r\n customColor: '自定义',\r\n alternatingColors: '交替颜色',\r\n confirmColor: '确定颜色',\r\n cancelColor: '取消',\r\n collapse: '收起',\r\n fillColor: '单元格颜色',\r\n border: '边框',\r\n borderStyle: '边框类型',\r\n mergeCell: '合并单元格',\r\n chooseMergeType: '选择合并类型',\r\n horizontalAlign: '水平对齐',\r\n verticalAlign: '垂直对齐',\r\n alignment: '对齐方式',\r\n textWrap: '文本换行',\r\n textWrapMode: '换行方式',\r\n textRotate: '文本旋转',\r\n textRotateMode: '旋转方式',\r\n freezeTopRow: '冻结首行',\r\n sortAndFilter: '排序和筛选',\r\n findAndReplace: '查找替换',\r\n sum: '求和',\r\n autoSum: '自动求和',\r\n moreFunction: '更多函数',\r\n conditionalFormat: '条件格式',\r\n postil: '批注',\r\n pivotTable: '数据透视表', \r\n chart: '图表',\r\n screenshot: '截图',\r\n splitColumn: '分列',\r\n insertImage: '插入图片',\r\n insertLink: '插入链接',\r\n dataVerification: '数据验证',\r\n protection:\"保护工作表内容\",\r\n\r\n clearText:\"清除颜色选择\",\r\n noColorSelectedText:\"没有颜色被选择\",\r\n\r\n toolMore:\"更多\",\r\n toolLess:\"少于\",\r\n toolClose:\"收起\",\r\n toolMoreTip:\"更多功能\",\r\n moreOptions:\"更多选项\",\r\n\r\n cellFormat:\"设置单元格格式\",\r\n print:\"打印\",\r\n },\r\n alternatingColors:{\r\n applyRange: '应用范围',\r\n selectRange: '选择应用范围',\r\n header: '页眉',\r\n footer: '页脚',\r\n\r\n errorInfo:\"不能对多重选择区域执行此操作,请选择单个区域,然后再试\",\r\n textTitle:\"格式样式\",\r\n custom:\"自定义\",\r\n close:\"关闭\",\r\n selectionTextColor:\"选择文本颜色\",\r\n selectionCellColor:\"选择单元格颜色\",\r\n removeColor:\"移除交替颜色\",\r\n colorShow:\"颜色\",\r\n currentColor:\"当前颜色\",\r\n\r\n tipSelectRange:\"请选择交替颜色应用范围\",\r\n errorNoRange:\"您选择的应用范围不是选区!\",\r\n errorExistColors:\"您选择的应用范围已存在交替颜色且不属于你要编辑的应用范围!\",\r\n },\r\n button: {\r\n confirm: '确定',\r\n cancel: '取消',\r\n close:\"关闭\",\r\n update:\"Update\",\r\n delete:\"Delete\",\r\n insert:\"新建\",\r\n },\r\n paint: {\r\n start: '格式刷开启',\r\n end: 'ESC键退出',\r\n\r\n tipSelectRange:\"请选择需要复制格式的区域\",\r\n tipNotMulti:\"无法对多重选择区域执行此操作\",\r\n },\r\n format: {\r\n moreCurrency: '更多货币格式',\r\n moreDateTime: '更多日期与时间格式',\r\n moreNumber: '更多数字格式',\r\n\r\n titleCurrency: '货币格式',\r\n decimalPlaces: '小数位数',\r\n titleDateTime: '日期与时间格式',\r\n titleNumber: '数字格式'\r\n },\r\n info: {\r\n detailUpdate: '新打开',\r\n detailSave: '已恢复本地缓存',\r\n row: '行',\r\n column: '列',\r\n loading:\"渲染中\",\r\n\r\n copy:\"副本\",\r\n return:\"返回\",\r\n rename:\"重命名\",\r\n tips:\"表格重命名\",\r\n noName:\"无标题的电子表格\",\r\n wait:\"待更新\",\r\n\r\n add:\"添加\",\r\n addLast:\"在底部添加\",\r\n backTop:\"回到顶部\",\r\n pageInfo:'共${total}条,${totalPage}页,当前已显示${currentPage}页',\r\n nextPage:\"下一页\",\r\n\r\n tipInputNumber:\"请输入数字\",\r\n tipInputNumberLimit:\"增加范围限制在1-100\",\r\n\r\n tipRowHeightLimit:\"行高必须在0 ~ 545之间\",\r\n tipColumnWidthLimit:\"列宽必须在0 ~ 2038之间\",\r\n pageInfoFull:'共${total}条,${totalPage}页,已显示全部数据',\r\n\r\n },\r\n currencyDetail:{\r\n RMB:'人民币',\r\n USdollar:'美元',\r\n EUR:'欧元',\r\n GBP:'英镑',\r\n HK:'港元',\r\n JPY:'日元',\r\n AlbanianLek:'阿尔巴尼亚列克',\r\n AlgerianDinar:'阿尔及利亚第纳尔',\r\n Afghani:'阿富汗尼',\r\n ArgentinePeso:'阿根廷比索',\r\n UnitedArabEmiratesDirham:'阿拉伯联合酋长国迪拉姆',\r\n ArubanFlorin:'阿鲁巴弗罗林',\r\n OmaniRial:'阿曼里亚尔',\r\n Azerbaijanimanat:'阿塞拜疆马纳特',\r\n EgyptianPound:'埃及镑',\r\n EthiopianBirr:'埃塞俄比亚比尔',\r\n AngolaKwanza:'安哥拉宽扎',\r\n AustralianDollar:'澳大利亚元',\r\n Patacas:'澳门元',\r\n BarbadosDollar:'巴巴多斯元',\r\n PapuaNewGuineaKina:'巴布亚新几内亚基那',\r\n BahamianDollar:'巴哈马元',\r\n PakistanRupee:'巴基斯坦卢比',\r\n ParaguayanGuarani:'巴拉圭瓜拉尼',\r\n BahrainiDinar:'巴林第纳尔',\r\n PanamanianBalboa:'巴拿马巴波亚',\r\n Brazilianreal:'巴西里亚伊',\r\n Belarusianruble:'白俄罗斯卢布',\r\n BermudianDollar:'百慕大元',\r\n BulgarianLev:'保加利亚列弗',\r\n IcelandKrona:'冰岛克朗',\r\n BosniaHerzegovinaConvertibleMark:'波黑可兑换马克',\r\n PolishZloty:'波兰兹罗提',\r\n Boliviano:'玻利维亚诺',\r\n BelizeDollar:'伯利兹元',\r\n BotswanaPula:'博茨瓦纳普拉',\r\n NotDannuzhamu:'不丹努扎姆',\r\n BurundiFranc:'布隆迪法郎',\r\n NorthKoreanWon:'朝鲜圆',\r\n DanishKrone:'丹麦克朗',\r\n EastCaribbeanDollar:'东加勒比元',\r\n DominicaPeso:'多米尼加比索',\r\n RussianRuble:'俄国卢布',\r\n EritreanNakfa:'厄立特里亚纳克法',\r\n CFAfranc:'非洲金融共同体法郎',\r\n PhilippinePeso:'菲律宾比索',\r\n FijiDollar:'斐济元',\r\n CapeVerdeEscudo:'佛得角埃斯库多',\r\n FalklandIslandsPound:'福克兰群岛镑',\r\n GambianDalasi:'冈比亚达拉西',\r\n Congolesefranc:'刚果法郎',\r\n ColombianPeso:'哥伦比亚比索',\r\n CostaRicanColon:'哥斯达黎加科朗',\r\n CubanPeso:'古巴比索',\r\n Cubanconvertiblepeso:'古巴可兑换比索',\r\n GuyanaDollar:'圭亚那元',\r\n KazakhstanTenge:'哈萨克斯坦坚戈',\r\n Haitiangourde:'海地古德',\r\n won:'韩元',\r\n NetherlandsAntillesGuilder:'荷属安的列斯盾',\r\n Honduraslempiras:'洪都拉斯拉伦皮拉',\r\n DjiboutiFranc:'吉布提法郎',\r\n KyrgyzstanSom:'吉尔吉斯斯坦索姆',\r\n GuineaFranc:'几内亚法郎',\r\n CanadianDollar:'加拿大元',\r\n GhanaianCedi:'加纳塞地',\r\n Cambodianriel:'柬埔寨瑞尔',\r\n CzechKoruna:'捷克克朗',\r\n ZimbabweDollar:'津巴布韦元',\r\n QatariRiyal:'卡塔尔里亚尔',\r\n CaymanIslandsDollar:'开曼群岛元',\r\n Comorianfranc:'科摩罗法郎',\r\n KuwaitiDinar:'科威特第纳尔',\r\n CroatianKuna:'克罗地亚库纳',\r\n KenyanShilling:'肯尼亚先令',\r\n LesothoLoti:'莱索托洛蒂',\r\n LaoKip:'老挝基普',\r\n LebanesePound:'黎巴嫩镑',\r\n Lithuanianlitas:'立陶宛立特',\r\n LibyanDinar:'利比亚第纳尔',\r\n LiberianDollar:'利比亚元',\r\n RwandaFranc:'卢旺达法郎',\r\n RomanianLeu:'罗马尼亚列伊',\r\n MalagasyAriary:'马达加斯加阿里亚里',\r\n MaldivianRufiyaa:'马尔代夫拉菲亚',\r\n MalawiKwacha:'马拉维克瓦查',\r\n MalaysianRinggit:'马来西亚林吉特',\r\n MacedoniawearingDinar:'马其顿戴第纳尔',\r\n MauritiusRupee:'毛里求斯卢比',\r\n MauritanianOuguiya:'毛里塔尼亚乌吉亚',\r\n MongolianTugrik:'蒙古图格里克',\r\n BangladeshiTaka:'孟加拉塔卡',\r\n PeruvianNuevoSol:'秘鲁新索尔',\r\n MyanmarKyat:'缅甸开亚特',\r\n MoldovanLeu:'摩尔多瓦列伊',\r\n MoroccanDirham:'摩洛哥迪拉姆',\r\n MozambiqueMetical:'莫桑比克梅蒂卡尔',\r\n MexicanPeso:'墨西哥比索',\r\n NamibianDollar:'纳米比亚元',\r\n SouthAfricanRand:'南非兰特',\r\n SouthSudanesePound:'南苏丹镑',\r\n NicaraguaCordoba:'尼加拉瓜科多巴',\r\n NepaleseRupee:'尼泊尔卢比',\r\n NigerianNaira:'尼日利亚奈拉',\r\n NorwegianKrone:'挪威克朗',\r\n GeorgianLari:'乔治亚拉瑞',\r\n RMBOffshore:'人民币(离岸)',\r\n SwedishKrona:'瑞典克朗',\r\n SwissFranc:'瑞士法郎',\r\n SerbianDinar:'塞尔维亚第纳尔',\r\n SierraLeone:'塞拉利昂利昂',\r\n SeychellesRupee:'塞舌尔卢比',\r\n SaudiRiyal:'沙特里亚尔',\r\n SaoTomeDobra:'圣多美多布拉',\r\n SaintHelenapound:'圣赫勒拿群岛磅',\r\n SriLankaRupee:'斯里兰卡卢比',\r\n SwazilandLilangeni:'斯威士兰里兰吉尼',\r\n SudanesePound:'苏丹镑',\r\n Surinamesedollar:'苏里南元',\r\n SolomonIslandsDollar:'所罗门群岛元',\r\n SomaliShilling:'索马里先令',\r\n TajikistanSomoni:'塔吉克斯坦索莫尼',\r\n PacificFranc:'太平洋法郎',\r\n ThaiBaht:'泰国铢',\r\n TanzanianShilling:'坦桑尼亚先令',\r\n TonganPaanga:'汤加潘加',\r\n TrinidadandTobagoDollar:'特立尼达和多巴哥元',\r\n TunisianDinar:'突尼斯第纳尔',\r\n TurkishLira:'土耳其里拉',\r\n VanuatuVatu:'瓦努阿图瓦图',\r\n GuatemalanQuetzal:'危地马拉格查尔',\r\n CommissionBolivar:'委内瑞拉博利瓦',\r\n BruneiDollar:'文莱元',\r\n UgandanShilling:'乌干达先令',\r\n UkrainianHryvnia:'乌克兰格里夫尼亚',\r\n UruguayanPeso:'乌拉圭比索',\r\n Uzbekistansom:'乌兹别克斯坦苏姆',\r\n WesternSamoaTala:'西萨摩亚塔拉',\r\n SingaporeDollar:'新加坡元',\r\n NT:'新台币',\r\n NewZealandDollar:'新西兰元',\r\n HungarianForint:'匈牙利福林',\r\n SyrianPound:'叙利亚镑',\r\n JamaicanDollar:'牙买加元',\r\n ArmenianDram:'亚美尼亚德拉姆',\r\n YemeniRial:'也门里亚尔',\r\n IraqiDinar:'伊拉克第纳尔',\r\n IranianRial:'伊朗里亚尔',\r\n NewIsraeliShekel:'以色列新谢克尔',\r\n IndianRupee:'印度卢比',\r\n IndonesianRupiah:'印度尼西亚卢比',\r\n JordanianDinar:'约旦第纳尔',\r\n VND:'越南盾',\r\n ZambianKwacha:'赞比亚克瓦查',\r\n GibraltarPound:'直布罗陀镑',\r\n ChileanPeso:'智利比索',\r\n CFAFrancBEAC:'中非金融合作法郎',\r\n },\r\n defaultFmt:[\r\n { \"text\": '自动', \"value\": \"General\", \"example\": \"\" },\r\n { \"text\": '纯文本', \"value\": \"@\", \"example\": \"\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '数字', \"value\": \"##0.00\", \"example\": \"1000.12\" },\r\n { \"text\": '百分比', \"value\": \"#0.00%\", \"example\": \"12.21%\" },\r\n { \"text\": '科学计数', \"value\": \"0.00E+00\", \"example\": \"1.01E+5\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '会计', \"value\": \"¥(0.00)\", \"example\": \"¥(1200.09)\" },\r\n //{ \"text\": \"财务\", \"value\": \"(#.####)\", \"example\": \"(1200.09)\" },\r\n { \"text\": '万元', \"value\": \"w\", \"example\": \"1亿2000万2500\" },\r\n { \"text\": '货币', \"value\": \"¥0.00\", \"example\": \"¥1200.09\" },\r\n //{ \"text\": \"货币整数\", \"value\": \"¥####\", \"example\": \"¥1200\" },\r\n { \"text\": '万元2位小数', \"value\": \"w0.00\", \"example\": \"2万2500.55\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '日期', \"value\": \"yyyy-MM-dd\", \"example\": \"2017-11-29\" },\r\n { \"text\": '时间', \"value\": \"hh:mm AM/PM\", \"example\": \"3:00 PM\" },\r\n { \"text\": '时间24H', \"value\": \"hh:mm\", \"example\": \"15:00\" },\r\n { \"text\": '日期时间', \"value\": \"yyyy-MM-dd hh:mm AM/PM\", \"example\": \"2017-11-29 3:00 PM\" },\r\n { \"text\": '日期时间24H', \"value\": \"yyyy-MM-dd hh:mm\", \"example\": \"2017-11-29 15:00\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '自定义格式', \"value\": \"fmtOtherSelf\", \"example\": \"more\" }\r\n ],\r\n dateFmtList:[\r\n {\r\n \"name\": \"1930-08-05\",\r\n \"value\": \"yyyy-MM-dd\"\r\n },\r\n {\r\n \"name\": \"1930/8/5\",\r\n \"value\": \"yyyy/MM/dd\"\r\n },\r\n {\r\n \"name\": \"1930年8月5日\",\r\n \"value\": 'yyyy\"年\"M\"月\"d\"日\"'\r\n },\r\n {\r\n \"name\": \"08-05\",\r\n \"value\": \"MM-dd\"\r\n },\r\n {\r\n \"name\": \"8-5\",\r\n \"value\": \"M-d\"\r\n },\r\n {\r\n \"name\": \"8月5日\",\r\n \"value\": 'M\"月\"d\"日\"'\r\n },\r\n {\r\n \"name\": \"13:30:30\",\r\n \"value\": \"h:mm:ss\"\r\n },\r\n {\r\n \"name\": \"13:30\",\r\n \"value\": \"h:mm\"\r\n },\r\n {\r\n \"name\": \"下午01:30\",\r\n \"value\": '上午/下午 hh:mm'\r\n },\r\n {\r\n \"name\": \"下午1:30\",\r\n \"value\": '上午/下午 h:mm'\r\n },\r\n {\r\n \"name\": \"下午1:30:30\",\r\n \"value\": '上午/下午 h:mm:ss'\r\n },\r\n {\r\n \"name\": \"08-05 下午01:30\",\r\n \"value\": \"MM-dd 上午/下午 hh:mm\"\r\n },\r\n // {\r\n // \"name\": \"1930年8月5日星期二\",\r\n // \"value\": ''\r\n // },\r\n // {\r\n // \"name\": \"1930年8月5日星期二 下午1:30:30\",\r\n // \"value\": ''\r\n // },\r\n ],\r\n fontFamily:{\r\n MicrosoftYaHei:\"Microsoft YaHei\",\r\n },\r\n fontarray: [\"Times New Roman\",\"Arial\",\"Tahoma\",\"Verdana\",\"微软雅黑\",\"宋体\",\"黑体\",\"楷体\",\"仿宋\",\"新宋体\",\"华文新魏\",\"华文行楷\",\"华文隶书\"],\r\n fontjson: {\"times new roman\":0,\"arial\":1,\"tahoma\":2,\"verdana\":3,\"微软雅黑\":4,\"microsoft yahei\":4,\"宋体\":5,\"simsun\":5,\"黑体\":6,\"simhei\":6,\"楷体\":7,\"kaiti\":7,\"仿宋\":8,\"fangsong\":8,\"新宋体\":9,\"nsimsun\":9,\"华文新魏\":10,\"stxinwei\":10,\"华文行楷\":11,\"stxingkai\":11,\"华文隶书\":12,\"stliti\":12,},\r\n border:{\r\n borderTop:'上框线',\r\n borderBottom:'下框线',\r\n borderLeft:'左框线',\r\n borderRight:'右框线',\r\n borderNone:'无',\r\n borderAll:'所有',\r\n borderOutside:'外侧',\r\n borderInside:'内侧',\r\n borderHorizontal:'内侧横线',\r\n borderVertical:'内侧竖线',\r\n borderColor:'边框颜色',\r\n borderSize:'边框粗细'\r\n },\r\n merge:{\r\n mergeAll:\"全部合并\",\r\n mergeV:\"垂直合并\",\r\n mergeH:\"水平合并\",\r\n mergeCancel:\"取消合并\",\r\n overlappingError:\"不能合并重叠区域\",\r\n partiallyError:\"无法对部分合并单元格执行此操作\",\r\n },\r\n align:{\r\n left:\"左对齐\",\r\n center:\"中间对齐\",\r\n right:\"右对齐\",\r\n\r\n top:\"顶部对齐\",\r\n middle:\"居中对齐\",\r\n bottom:\"底部对齐\",\r\n },\r\n textWrap:{\r\n \"overflow\":\"溢出\",\r\n \"wrap\":\"自动换行\",\r\n \"clip\":\"截断\",\r\n },\r\n rotation:{\r\n \"none\":\"无旋转\",\r\n \"angleup\":\"向上倾斜\",\r\n \"angledown\":\"向下倾斜\",\r\n \"vertical\":\"竖排文字\",\r\n \"rotationUp\":\"向上90°\",\r\n \"rotationDown\":\"向下90°\"\r\n },\r\n freezen:{\r\n default:\"冻结首行\",\r\n freezenRow:\"冻结首行\",\r\n freezenColumn:\"冻结首列\",\r\n freezenRC:\"冻结行列\",\r\n freezenRowRange:\"冻结行到选区\",\r\n freezenColumnRange:\"冻结列到选区\",\r\n freezenRCRange:\"冻结行列到选区\",\r\n freezenCancel:\"取消冻结\",\r\n\r\n noSeletionError:\"没有选区\",\r\n },\r\n sort:{\r\n \"asc\":\"升序\",\r\n \"desc\":\"降序\",\r\n \"custom\":\"自定义排序\",\r\n\r\n \"hasTitle\":\"数据具有标题行\",\r\n \"sortBy\":\"排序依据\",\r\n \"addOthers\":\"添加其他排序列\",\r\n \"close\":\"关闭\",\r\n \"confirm\":\"排序\",\r\n\r\n \"columnOperation\":\"列\",\r\n \"secondaryTitle\":\"次要排序\",\r\n\r\n \"sortTitle\":\"排序范围\",\r\n\r\n \"sortRangeTitle\":\"排序范围从\",\r\n \"sortRangeTitleTo\":\"到\",\r\n\r\n\r\n \"noRangeError\":\"不能对多重选择区域执行此操作,请选择单个区域,然后再试\",\r\n \"mergeError\":\"选区有合并单元格,无法执行此操作!\",\r\n\r\n },\r\n filter:{\r\n \"filter\":\"筛选\", \r\n \"clearFilter\":\"清除筛选\", \r\n\r\n sortByAsc:\"以A-Z升序排列\",\r\n sortByDesc:\"以Z-A降序排列\",\r\n filterByColor:\"按颜色筛选\",\r\n filterByCondition:\"按条件过滤\",\r\n filterByValues:\"按值过滤\",\r\n\r\n filiterInputNone:\"无\",\r\n\r\n filiterInputTip:\"输入筛选值\",\r\n filiterRangeStartTip:\"范围开始\",\r\n filiterRangeEndTip:\"范围结束\",\r\n\r\n filterValueByAllBtn:\"全选\",\r\n filterValueByClearBtn:\"清除\",\r\n filterValueByInverseBtn:\"反选\",\r\n filterValueByTip:\"按照值进行筛选\",\r\n filterConform:\"确 认\",\r\n filterCancel:\"取 消\",\r\n clearFilter:\"清除筛选\",\r\n\r\n conditionNone:\"无\",\r\n conditionCellIsNull:\"单元格为空\",\r\n conditionCellNotNull:\"单元格有数据\",\r\n conditionCellTextContain:\"文本包含\",\r\n conditionCellTextNotContain:\"文本不包含\",\r\n conditionCellTextStart:\"文本开头为\",\r\n conditionCellTextEnd:\"文本结尾为\",\r\n conditionCellTextEqual:\"文本等于\",\r\n conditionCellDateEqual:\"日期等于\",\r\n conditionCellDateBefore:\"日期早于\",\r\n conditionCellDateAfter:\"日期晚于\",\r\n conditionCellGreater:\"大于\",\r\n conditionCellGreaterEqual:\"大于等于\",\r\n conditionCellLess:\"小于\",\r\n conditionCellLessEqual:\"小于等于\",\r\n conditionCellEqual:\"等于\",\r\n conditionCellNotEqual:\"不等于\",\r\n conditionCellBetween:\"介于\",\r\n conditionCellNotBetween:\"不在其中\",\r\n\r\n filiterMoreDataTip:\"数据量大!请稍后\",\r\n filiterMonthText:\"月\",\r\n filiterYearText:\"年\",\r\n filiterByColorTip:\"按单元格颜色筛选\",\r\n filiterByTextColorTip:\"按单元格字体颜色筛选\",\r\n filterContainerOneColorTip:\"本列仅包含一种颜色\",\r\n filterDateFormatTip:\"日期格式\",\r\n\r\n valueBlank:\"(空白)\",\r\n mergeError:\"筛选选区有合并单元格,无法执行此操作!\",\r\n },\r\n rightclick: {\r\n copy: '复制',\r\n copyAs: '复制为',\r\n paste: '粘贴',\r\n insert: '插入',\r\n delete: '删除',\r\n deleteCell: '删除单元格',\r\n deleteSelected: '删除选中',\r\n hide: '隐藏',\r\n hideSelected: '隐藏选中',\r\n showHide: '显示隐藏',\r\n to: '向',\r\n left: '左',\r\n right: '右',\r\n top: '上',\r\n bottom: '下',\r\n moveLeft: '左移',\r\n moveUp: '上移',\r\n add: '增加',\r\n row: '行',\r\n column: '列',\r\n width: '宽',\r\n height: '高',\r\n number: '数字',\r\n confirm: '确认',\r\n orderAZ: 'A-Z顺序排列',\r\n orderZA: 'Z-A降序排列',\r\n clearContent: '清除内容',\r\n matrix: '矩阵操作选区',\r\n sortSelection: '排序选区',\r\n filterSelection: '筛选选区',\r\n chartGeneration: '图表生成',\r\n firstLineTitle: '首行为标题',\r\n untitled: '无标题',\r\n array1: '一维数组',\r\n array2: '二维数组',\r\n array3: '多维数组',\r\n diagonal: '对角线',\r\n antiDiagonal: '反对角线',\r\n diagonalOffset: '对角偏移',\r\n offset: '偏移量',\r\n boolean: '布尔值',\r\n flip: '翻转',\r\n upAndDown: '上下',\r\n leftAndRight: '左右',\r\n clockwise: '顺时针',\r\n counterclockwise: '逆时针',\r\n transpose: '转置',\r\n matrixCalculation: '矩阵计算',\r\n plus: '加',\r\n minus: '减',\r\n multiply: '乘',\r\n divided: '除',\r\n power: '次方',\r\n root: '次方根',\r\n log: 'log',\r\n delete0: '删除两端0值',\r\n removeDuplicate: '删除重复值',\r\n byRow: '按行',\r\n byCol: '按列',\r\n generateNewMatrix: '生成新矩阵',\r\n },\r\n comment:{\r\n \"insert\":\"新建批注\",\r\n \"edit\":\"编辑批注\",\r\n \"delete\":\"删除\",\r\n \"showOne\":\"显示/隐藏批注\",\r\n \"showAll\":\"显示/隐藏所有批注\"\r\n },\r\n screenshot:{\r\n screenshotTipNoSelection:\"请框选需要截图的范围\",\r\n screenshotTipTitle:\"提示!\",\r\n screenshotTipHasMerge:\"无法对合并单元格执行此操作\",\r\n screenshotTipHasMulti:\"无法对多重选择区域执行此操作\",\r\n screenshotTipSuccess:\"截取成功\",\r\n screenshotImageName:\"截图\",\r\n\r\n downLoadClose:\"关闭\",\r\n downLoadCopy:\"复制到剪切板\",\r\n downLoadBtn:\"下载\",\r\n browserNotTip:\"下载功能IE浏览器不支持!\",\r\n rightclickTip:\"请在图片上右键点击'复制'\",\r\n successTip:\"已成功复制(如果粘贴失败,请在图片上右键点击'复制图片')\",\r\n },\r\n splitText:{\r\n splitDelimiters:\"分割符号\",\r\n splitOther:\"其它\",\r\n splitContinueSymbol:\"连续分隔符号视为单个处理\",\r\n splitDataPreview:\"数据预览\",\r\n splitTextTitle:\"文本分列\",\r\n splitConfirmToExe:\"此处已有数据,是否替换它?\",\r\n\r\n tipNoMulti:\"不能对多重选择区域执行此操作,请选择单个区域,然后再试\",\r\n tipNoMultiColumn:\"一次只能转换一列数据,选定区域可以有多行,但不能有多列,请在选定单列区域以后再试\",\r\n },\r\n imageText:{\r\n imageSetting: '图片设置',\r\n close: '关闭',\r\n conventional: '常规',\r\n moveCell1: '移动并调整单元格大小',\r\n moveCell2: '移动并且不调整单元格的大小',\r\n moveCell3: '不要移动单元格并调整其大小',\r\n fixedPos: '固定位置',\r\n border: '边框',\r\n width: '宽度',\r\n radius: '半径',\r\n style: '样式',\r\n solid: '实线',\r\n dashed: '虚线',\r\n dotted: '点状',\r\n double: '双线',\r\n color: '颜色',\r\n },\r\n punctuation:{\r\n \"tab\":\"Tab 键\",\r\n \"semicolon\":\"分号\",\r\n \"comma\":\"逗号\",\r\n \"space\":\"空格\",\r\n \r\n },\r\n findAndReplace:{\r\n find:\"查找\",\r\n replace:\"替换\",\r\n goto:\"转到\",\r\n location:\"定位条件\",\r\n formula:\"公式\",\r\n date:\"日期\",\r\n number:\"数字\",\r\n string:\"字符\",\r\n error:\"错误\",\r\n condition:\"条件格式\",\r\n rowSpan:\"间隔行\",\r\n columnSpan:\"间隔列\",\r\n locationExample:\"定位\",\r\n lessTwoRowTip:\"请选择最少两行\",\r\n lessTwoColumnTip:\"请选择最少两行\",\r\n\r\n findTextbox:\"查找内容\",\r\n replaceTextbox:\"替换内容\",\r\n\r\n regexTextbox:\"正则表达式匹配\",\r\n wholeTextbox:\"整词匹配\",\r\n distinguishTextbox:\"区分大小写匹配\",\r\n\r\n allReplaceBtn:\"全部替换\",\r\n replaceBtn:\"替换\",\r\n allFindBtn:\"查找全部\",\r\n findBtn:\"查找下一个\",\r\n\r\n noFindTip:\"没有查找到该内容\",\r\n modeTip:\"该模式下不可进行此操作\",\r\n\r\n searchTargetSheet:\"工作表\",\r\n searchTargetCell:\"单元格\",\r\n searchTargetValue:\"值\",\r\n\r\n searchInputTip:\"请输入查找内容\",\r\n\r\n noReplceTip:\"没有可替换的内容\",\r\n noMatchTip:\"找不到匹配项\",\r\n\r\n successTip:\"已经帮您搜索并进行了${xlength}处替换\",\r\n\r\n locationConstant:\"常量\",\r\n locationFormula:\"公式\",\r\n locationDate:\"日期\",\r\n locationDigital:\"数字\",\r\n locationString:\"字符\",\r\n locationBool:\"逻辑值\",\r\n locationError:\"错误\",\r\n locationNull:\"空值\",\r\n locationCondition:\"条件格式\",\r\n locationRowSpan:\"间隔行\",\r\n locationColumnSpan:\"间隔列\",\r\n\r\n locationTiplessTwoRow:\"请选择最少两行\",\r\n locationTiplessTwoColumn:\"请选择最少两列\",\r\n locationTipNotFindCell:\"未找到单元格\"\r\n\r\n },\r\n sheetconfig: {\r\n delete: '删除',\r\n copy: '复制',\r\n rename: '重命名',\r\n changeColor: '更改颜色',\r\n hide: '隐藏',\r\n unhide: '取消隐藏',\r\n moveLeft: '向左移',\r\n moveRight: '向右移',\r\n resetColor: '重置颜色',\r\n cancelText: '取消',\r\n chooseText: '确定颜色',\r\n\r\n tipNameRepeat:\"标签页的名称不能重复!请重新修改\",\r\n noMoreSheet:\"工作薄内至少含有一张可视工作表。若需删除选定的工作表,请先插入一张新工作表或显示一张隐藏的工作表。\",\r\n confirmDelete:\"是否删除\",\r\n redoDelete:\"可以通过Ctrl+Z撤销删除\",\r\n noHide:\"不能隐藏, 至少保留一个sheet标签\",\r\n chartEditNoOpt:\"图表编辑模式下不允许该操作!\",\r\n sheetNameSpecCharError:\"名称不能超过31个字符,首尾不能是' 且名称不能包含:\\r\\n[ ] : \\\\ ? * /\",\r\n sheetNamecannotIsEmptyError:\"名称不能为空\"\r\n },\r\n conditionformat: {\r\n conditionformat_greaterThan: '条件格式——大于',\r\n conditionformat_greaterThan_title: '为大于以下值的单元格设置格式',\r\n conditionformat_lessThan: '条件格式——小于',\r\n conditionformat_lessThan_title: '为小于以下值的单元格设置格式',\r\n conditionformat_betweenness: '条件格式——介于',\r\n conditionformat_betweenness_title: '为介于以下值的单元格设置格式',\r\n conditionformat_equal: '条件格式——等于',\r\n conditionformat_equal_title: '为等于以下值的单元格设置格式',\r\n conditionformat_textContains: '条件格式——文本包含',\r\n conditionformat_textContains_title: '为包含以下文本的单元格设置格式',\r\n conditionformat_occurrenceDate: '条件格式——发生日期',\r\n conditionformat_occurrenceDate_title: '为包含以下日期的单元格设置格式',\r\n conditionformat_duplicateValue: '条件格式——重复值',\r\n conditionformat_duplicateValue_title: '为包含以下类型值的单元格设置格式',\r\n conditionformat_top10: '条件格式——前 10 项',\r\n conditionformat_top10_percent: '条件格式——前 10%',\r\n conditionformat_top10_title: '为值最大的那些单元格设置格式',\r\n conditionformat_last10: '条件格式——最后 10 项',\r\n conditionformat_last10_percent: '条件格式——最后 10%',\r\n conditionformat_last10_title: '为值最小的那些单元格设置格式',\r\n conditionformat_AboveAverage: '条件格式——高于平均值',\r\n conditionformat_AboveAverage_title: '为高于平均值的单元格设置格式',\r\n conditionformat_SubAverage: '条件格式——低于平均值',\r\n conditionformat_SubAverage_title: '为低于平均值的单元格设置格式',\r\n rule: '规则',\r\n newRule: '新建规则',\r\n editRule: '编辑规则',\r\n deleteRule: '删除规则',\r\n deleteCellRule: '清除所选单元格的规则',\r\n deleteSheetRule: '清除整个工作表的规则',\r\n manageRules: '管理规则',\r\n showRules: '显示其格式规则',\r\n highlightCellRules: '突出显示单元格规则',\r\n itemSelectionRules: '项目选取规则',\r\n conditionformatManageRules: '条件格式规则管理器',\r\n format: '格式',\r\n setFormat: '设置格式',\r\n setAs: '设置为',\r\n setAsByArea: '针对选定区域,设置为',\r\n applyRange: '应用范围',\r\n selectRange: '点击选择应用范围',\r\n selectRange_percent: '所选范围的百分比',\r\n selectRange_average: '选定范围的平均值',\r\n selectRange_value: '选定范围中的数值',\r\n pleaseSelectRange: '请选择应用范围',\r\n selectDataRange: '点击选择数据范围',\r\n selectCell: '选择单元格',\r\n pleaseSelectCell: '请选择单元格',\r\n pleaseSelectADate: '请选择日期',\r\n pleaseEnterInteger: '请输入一个介于 1 和 1000 之间的整数',\r\n onlySingleCell: '只能对单个单元格进行引用',\r\n conditionValueCanOnly: '条件值只能是数字或者单个单元格',\r\n ruleTypeItem1: '基于各自值设置所有单元格的格式',\r\n ruleTypeItem2: '只为包含以下内容的单元格设置格式',\r\n ruleTypeItem2_title: '只为满足以下条件的单元格',\r\n ruleTypeItem3: '仅对排名靠前或靠后的数值设置格式',\r\n ruleTypeItem3_title: '为以下排名内的值',\r\n ruleTypeItem4: '仅对高于或低于平均值的数值设置格式',\r\n ruleTypeItem4_title: '为满足以下条件的值',\r\n ruleTypeItem5: '仅对唯一值或重复值设置格式',\r\n ruleTypeItem6: '使用公式确定要设置格式的单元格',\r\n formula: '公式',\r\n textColor: '文本颜色',\r\n cellColor: '单元格颜色',\r\n confirm: '确定',\r\n confirmColor: '确定颜色',\r\n cancel: '取消',\r\n close: '关闭',\r\n clearColorSelect: '清除颜色选择',\r\n sheet: '表',\r\n currentSheet: '当前工作表',\r\n dataBar: '数据条',\r\n dataBarColor: '数据条颜色',\r\n gradientDataBar_1: '蓝-白渐变数据条',\r\n gradientDataBar_2: '绿-白渐变数据条',\r\n gradientDataBar_3: '红-白渐变数据条',\r\n gradientDataBar_4: '橙-白渐变数据条',\r\n gradientDataBar_5: '浅蓝-白渐变数据条',\r\n gradientDataBar_6: '紫-白渐变数据条',\r\n solidColorDataBar_1: '蓝色数据条',\r\n solidColorDataBar_2: '绿色数据条',\r\n solidColorDataBar_3: '红色数据条',\r\n solidColorDataBar_4: '橙色数据条',\r\n solidColorDataBar_5: '浅蓝色数据条',\r\n solidColorDataBar_6: '紫色数据条',\r\n colorGradation: '色阶',\r\n colorGradation_1: '绿-黄-红色阶',\r\n colorGradation_2: '红-黄-绿色阶',\r\n colorGradation_3: '绿-白-红色阶',\r\n colorGradation_4: '红-白-绿色阶',\r\n colorGradation_5: '蓝-白-红色阶',\r\n colorGradation_6: '红-白-蓝色阶',\r\n colorGradation_7: '白-红色阶',\r\n colorGradation_8: '红-白色阶',\r\n colorGradation_9: '绿-白色阶',\r\n colorGradation_10: '白-绿色阶',\r\n colorGradation_11: '绿-黄色阶',\r\n colorGradation_12: '黄-绿色阶',\r\n icons: '图标集',\r\n pleaseSelectIcon: '请点击选择一组图标:',\r\n cellValue: '单元格值',\r\n specificText: '特定文本',\r\n occurrence: '发生日期',\r\n greaterThan: '大于',\r\n lessThan: '小于',\r\n between: '介于',\r\n equal: '等于',\r\n in: '和',\r\n to: '到',\r\n between2: '之间',\r\n contain: '包含',\r\n textContains: '文本包含',\r\n duplicateValue: '重复值',\r\n uniqueValue: '唯一值',\r\n top: '前',\r\n top10: '前 10 项',\r\n top10_percent: '前 10%',\r\n last: '后',\r\n last10: '后 10 项',\r\n last10_percent: '后 10%',\r\n oneself: '个',\r\n above: '高于',\r\n aboveAverage: '高于平均值',\r\n below: '低于',\r\n belowAverage: '低于平均值',\r\n all: '全部',\r\n yesterday: '昨天',\r\n today: '今天',\r\n tomorrow: '明天',\r\n lastWeek: '上周',\r\n thisWeek: '本周',\r\n lastMonth: '上月',\r\n thisMonth: '本月',\r\n lastYear: '去年',\r\n thisYear: '本年',\r\n last7days: '最近7天',\r\n last30days: '最近30天',\r\n next7days: '未来7天',\r\n next30days: '未来30天',\r\n next60days: '未来60天',\r\n chooseRuleType: '选择规则类型',\r\n editRuleDescription: '编辑规则说明',\r\n newFormatRule: '新建格式规则',\r\n editFormatRule: '编辑格式规则',\r\n formatStyle: '格式样式',\r\n fillType: '填充类型',\r\n color: '颜色',\r\n twocolor: '双色',\r\n tricolor: '三色',\r\n multicolor: '彩色',\r\n grayColor: '灰色',\r\n gradient: '渐变',\r\n solid: '实心',\r\n maxValue: '最大值',\r\n medianValue: '中间值',\r\n minValue: '最小值',\r\n direction: '方向',\r\n threeWayArrow: '三向箭头',\r\n fourWayArrow: '四向箭头',\r\n fiveWayArrow: '五向箭头',\r\n threeTriangles: '3个三角形',\r\n shape: '形状',\r\n threeColorTrafficLight: '三色交通灯',\r\n fourColorTrafficLight: '四色交通灯',\r\n threeSigns: '三标志',\r\n greenRedBlackGradient: '绿-红-黑渐变',\r\n rimless: '无边框',\r\n bordered: '有边框',\r\n mark: '标记',\r\n threeSymbols: '三个符号',\r\n tricolorFlag: '三色旗',\r\n circled: '有圆圈',\r\n noCircle: '无圆圈',\r\n grade: '等级',\r\n grade4: '四等级',\r\n grade5: '五等级',\r\n threeStars: '3个星形',\r\n fiveQuadrantDiagram: '五象限图',\r\n fiveBoxes: '5个框',\r\n },\r\n insertLink: {\r\n linkText: \"文本\",\r\n linkType: \"链接类型\",\r\n external: \"外部链接\",\r\n internal: \"内部链接\",\r\n linkAddress: \"链接地址\",\r\n linkSheet: \"工作表\",\r\n linkCell: \"单元格引用\",\r\n linkTooltip: \"提示\",\r\n placeholder1: \"请输入网页链接地址\",\r\n placeholder2: \"请输入要引用的单元格,例A1\",\r\n placeholder3: \"请输入提示内容\",\r\n tooltipInfo1: \"请输入有效的链接\",\r\n tooltipInfo2: \"请输入正确的单元格引用\",\r\n },\r\n dataVerification: {\r\n cellRange: '单元格范围',\r\n selectCellRange: '点击选择单元格范围',\r\n selectCellRange2: '请选择单元格范围',\r\n verificationCondition: '验证条件',\r\n dropdown: '下拉列表',\r\n checkbox: '复选框',\r\n number: '数字',\r\n number_integer: '数字-整数',\r\n number_decimal: '数字-小数',\r\n text_content: '文本-内容',\r\n text_length: '文本-长度',\r\n date: '日期',\r\n validity: '有效性',\r\n placeholder1: '请输入选项,以英文逗号分隔,如1,2,3,4,5',\r\n placeholder2: '请输入内容',\r\n placeholder3: '数值,如10',\r\n placeholder4: '请输入指定的文本',\r\n placeholder5: '请输入选中单元格时显示的提示语',\r\n selected: '选择时',\r\n notSelected: '未选择',\r\n between: '介于',\r\n notBetween: '不介于',\r\n equal: '等于',\r\n notEqualTo: '不等于',\r\n moreThanThe: '大于',\r\n lessThan: '小于',\r\n greaterOrEqualTo: '大于等于',\r\n lessThanOrEqualTo: '小于等于',\r\n include: '包括',\r\n exclude: '不包括',\r\n earlierThan: '早于',\r\n noEarlierThan: '不早于',\r\n laterThan: '晚于',\r\n noLaterThan: '不晚于',\r\n identificationNumber: '身份证号码',\r\n phoneNumber: '手机号',\r\n remote: '自动远程获取选项',\r\n prohibitInput: '输入数据无效时禁止输入',\r\n hintShow: '选中单元格时显示提示语',\r\n deleteVerification: '删除验证',\r\n tooltipInfo1: '下拉列表选项不可为空',\r\n tooltipInfo2: '复选框内容不可为空',\r\n tooltipInfo3: '输入的值不是数值类型',\r\n tooltipInfo4: '数值2不能小于数值1',\r\n tooltipInfo5: '文本内容不能为空',\r\n tooltipInfo6: '输入的值不是日期类型',\r\n tooltipInfo7: '日期2不能小于日期1',\r\n },\r\n formula:{\r\n sum:\"求和\",\r\n average:\"平均值\",\r\n count:\"计数\",\r\n max:\"最大值\",\r\n min:\"最小值\",\r\n ifGenerate:\"if公式生成器\",\r\n find:\"更多函数\",\r\n\r\n tipNotBelongToIf:\"该单元格函数不属于if公式!\",\r\n tipSelectCell:\"请选择单元格插入函数\",\r\n\r\n ifGenCompareValueTitle:\"比较值\",\r\n ifGenSelectCellTitle:\"点击选择单元格\",\r\n ifGenRangeTitle:\"范围\",\r\n ifGenRangeTo:\"至\",\r\n ifGenRangeEvaluate:\"范围评估\",\r\n ifGenSelectRangeTitle:\"点击选择范围\",\r\n ifGenCutWay:\"划分方式\",\r\n ifGenCutSame:\"划分值相同\",\r\n ifGenCutNpiece:\"划分为N份\",\r\n ifGenCutCustom:\"自定义输入\",\r\n ifGenCutConfirm:\"生成\",\r\n\r\n ifGenTipSelectCell:\"选择单元格\",\r\n ifGenTipSelectCellPlace:\"请选择单元格\",\r\n\r\n ifGenTipSelectRange:\"选择单范围\",\r\n ifGenTipSelectRangePlace:\"请选择范围\",\r\n\r\n ifGenTipNotNullValue:\"比较值不能为空!\",\r\n ifGenTipLableTitile:\"标签\",\r\n ifGenTipRangeNotforNull:\"范围不能为空!\",\r\n ifGenTipCutValueNotforNull:\"划分值不能为空!\",\r\n ifGenTipNotGenCondition:\"没有生成可用的条件!\",\r\n },\r\n formulaMore:{\r\n valueTitle:\"值\",\r\n tipSelectDataRange:\"选取数据范围\",\r\n tipDataRangeTile:\"数据范围\",\r\n findFunctionTitle:\"查找函数\",\r\n tipInputFunctionName:\"请输入您要查找的函数名称或函数功能的简要描述\",\r\n\r\n \"Array\":\"数组\",\r\n \"Database\":\"数据源\",\r\n \"Date\":\"日期\",\r\n \"Engineering\":\"工程计算\",\r\n \"Filter\":\"过滤器\",\r\n \"Financial\":\"财务\",\r\n \"luckysheet\":\"Luckysheet内置\",\r\n \"other\":\"其它\",\r\n \"Logical\":\"逻辑\",\r\n \"Lookup\":\"查找\",\r\n \"Math\":\"数学\",\r\n \"Operator\":\"运算符\",\r\n \"Parser\":\"转换工具\",\r\n \"Statistical\":\"统计\",\r\n \"Text\":\"文本\",\r\n \"dataMining\":\"数据挖掘\",\r\n\r\n \"selectFunctionTitle\":\"选择函数\",\r\n \"calculationResult\":\"计算结果\",\r\n\r\n tipSuccessText:\"成功\",\r\n tipParamErrorText:\"参数类型错误\",\r\n\r\n \"helpClose\":\"关闭\",\r\n \"helpCollapse\":\"收起\",\r\n \"helpExample\":\"示例\",\r\n \"helpAbstract\":\"摘要\",\r\n\r\n \"execfunctionError\":'提示\", \"公式存在错误',\r\n \"execfunctionSelfError\":'公式不可引用其本身的单元格',\r\n \"execfunctionSelfErrorResult\":'公式不可引用其本身的单元格,会导致计算结果不准确',\r\n\r\n \"allowRepeatText\":\"可重复\",\r\n \"allowOptionText\":\"可选\",\r\n\r\n \"selectCategory\":\"或选择类别\",\r\n },\r\n drag:{\r\n noMerge:\"无法对合并单元格执行此操作\",\r\n affectPivot:\"无法对所选单元格进行此更改,因为它会影响数据透视表!\",\r\n noMulti:\"无法对多重选择区域执行此操作,请选择单个区域\",\r\n noPaste:\"无法在此处粘贴此内容,请选择粘贴区域的一个单元格,然后再次尝试粘贴\",\r\n noPartMerge:\"无法对部分合并单元格执行此操作\",\r\n\r\n inputCorrect:\"请输入正确的数值\",\r\n notLessOne:\"行列数不能小于1\",\r\n offsetColumnLessZero:\"偏移列不能为负数!\",\r\n\r\n pasteMustKeybordAlert:\"Copy and paste in the Sheet: Ctrl + C to copy, Ctrl + V to paste, Ctrl + X to cut\",\r\n pasteMustKeybordAlertHTMLTitle:\"Copy and paste in the Sheet\",\r\n pasteMustKeybordAlertHTML:\"Ctrl + C  to copy
Ctrl + V  to paste
Ctrl + X  to cut\",\r\n },\r\n pivotTable:{\r\n title:\"数据透视表\",\r\n closePannel:\"关闭\",\r\n editRange:\"编辑范围\",\r\n tipPivotFieldSelected:\"选择需要添加到数据透视表的字段\",\r\n tipClearSelectedField:\"清除所有已选字段\",\r\n btnClearSelectedField:\"清除\",\r\n btnFilter:\"筛选\",\r\n titleRow:\"行\",\r\n titleColumn:\"列\",\r\n titleValue:\"数值\",\r\n tipShowColumn:\"统计字段显示为列\",\r\n tipShowRow:\"统计字段显示为行\",\r\n\r\n titleSelectionDataRange:\"选取数据范围\",\r\n titleDataRange:\"数据范围\",\r\n\r\n valueSum:\"总计\",\r\n\r\n valueStatisticsSUM:\"求和\",\r\n valueStatisticsCOUNT:\"数值计数\",\r\n valueStatisticsCOUNTA:\"计数\",\r\n valueStatisticsCOUNTUNIQUE:\"去重计数\",\r\n valueStatisticsAVERAGE:\"平均值\",\r\n valueStatisticsMAX:\"最大值\",\r\n valueStatisticsMIN:\"最小值\",\r\n valueStatisticsMEDIAN:\"中位数\",\r\n valueStatisticsPRODUCT:\"乘积\",\r\n valueStatisticsSTDEV:\"标准差\",\r\n\r\n valueStatisticsSTDEVP:\"整体标准差\",\r\n valueStatisticslet:\"方差\",\r\n valueStatisticsVARP:\"整体方差\",\r\n\r\n errorNotAllowEdit:\"非编辑模式下禁止该操作!\",\r\n errorNotAllowMulti:\"不能对多重选择区域执行此操作,请选择单个区域,然后再试\",\r\n errorSelectRange:\"请选择新建透视表的区域\",\r\n errorIsDamage:\"此数据透视表的源数据已损坏!\",\r\n errorNotAllowPivotData:\"不可选择数据透视表为源数据!\",\r\n errorSelectionRange:\"选择失败, 输入范围错误!\",\r\n errorIncreaseRange:\"请扩大选择的数据范围!\",\r\n\r\n titleAddColumn:\"添加列到数据透视表\",\r\n titleMoveColumn:\"移动该列到下方白框\",\r\n titleClearColumnFilter:\"清除该列的筛选条件\",\r\n titleFilterColumn:\"筛选该列\",\r\n\r\n titleSort:\"排序\",\r\n titleNoSort:\"无排序\",\r\n titleSortAsc:\"升序\",\r\n titleSortDesc:\"降序\",\r\n titleSortBy:\"排序依据\",\r\n titleShowSum:\"显示总计\",\r\n titleStasticTrue:\"是\",\r\n titleStasticFalse:\"否\",\r\n },\r\n dropCell:{\r\n copyCell:\"复制单元格\",\r\n sequence:\"填充序列\",\r\n onlyFormat:\"仅填充格式\",\r\n noFormat:\"不带格式填充\",\r\n day:\"以天数填充\",\r\n workDay:\"以工作日填充\",\r\n month:\"以月填充\",\r\n year:\"以年填充\",\r\n chineseNumber:\"以中文小写数字填充\"\r\n },\r\n imageCtrl:{\r\n borderTile:\"图片边框颜色选择\",\r\n borderCur:\"当前颜色\",\r\n },\r\n protection:{\r\n protectiontTitle:\"保护工作表\",\r\n enterPassword:\"请输入密码(可留空)\",\r\n enterHint:\"您试图更改的单元格或图表位于受保护的工作表中。若要更改,请取消工作表保护。您可能需要输入密码\",\r\n swichProtectionTip:\"保护工作表及锁定的单元格内容\",\r\n authorityTitle:\"允许此工作表的用户进行:\",\r\n selectLockedCells:\"选定锁定单元格\",\r\n selectunLockedCells:\"选定解除锁定的单元格\",\r\n formatCells:\"设置单元格格式\",\r\n formatColumns:\"设置列格式\",\r\n formatRows:\"设置行格式\",\r\n insertColumns:\"插入列\",\r\n insertRows:\"插入行\",\r\n insertHyperlinks:\"插入超链接\",\r\n deleteColumns:\"删除列\",\r\n deleteRows:\"删除行\",\r\n sort:\"排序\",\r\n filter:\"使用自动筛选\",\r\n usePivotTablereports:\"使用数据透视表和报表\",\r\n editObjects:\"编辑对象\",\r\n editScenarios:\"编辑方案\",\r\n\r\n allowRangeTitle:\"允许用户编辑区域\",\r\n allowRangeAdd:\"新建...\",\r\n\r\n allowRangeAddTitle:\"标题\",\r\n allowRangeAddSqrf:\"引用单元格\",\r\n selectCellRange: '点击选择单元格范围',\r\n selectCellRangeHolder:\"请输入单元格范围\",\r\n allowRangeAddTitlePassword:\"密码\",\r\n allowRangeAddTitleHint:\"提示\",\r\n allowRangeAddTitleHintTitle:\"设置密码后,提示用户输入密码(可留空)\",\r\n allowRangeAddtitleDefault:\"请输入区域名称\",\r\n\r\n rangeItemDblclick:\"双击进行编辑\",\r\n rangeItemHasPassword:\"已设置密码\",\r\n\r\n rangeItemErrorTitleNull:\"标题不能为空\",\r\n rangeItemErrorRangeNull:\"单元格范围不能为空\",\r\n rangeItemErrorRange:\"单元格范围格式错误\",\r\n\r\n validationTitle:\"验证提示\",\r\n validationTips:\"需要输入密码来撤销工作表的保护\",\r\n validationInputHint:\"请输入密码\",\r\n\r\n checkPasswordNullalert:\"密码不能为空!\",\r\n checkPasswordWrongalert:\"密码错误,请重试!\",\r\n\r\n checkPasswordSucceedalert:\"解锁成功,可以编辑该区域!\",\r\n defaultRangeHintText:\"该单元格正在受密码保护。\",\r\n defaultSheetHintText:\"该单元格或图表位于受保护的工作表中,若要进行更改,请取消工作表保护,您可能需要输入密码。\",\r\n },\r\n cellFormat:{\r\n cellFormatTitle:\"设置单元格格式\",\r\n protection:\"保护\",\r\n locked:\"锁定单元格\",\r\n hidden:\"隐藏公式\",\r\n protectionTips:\"只有保护工作表功能(在菜单栏点击保护工作表按钮进行设置)开启后,锁定单元格或隐藏公式才能生效\",\r\n tipsPart:\"部分选中\",\r\n tipsAll:\"全部选中\",\r\n selectionIsNullAlert:\"请选择一个范围!\",\r\n sheetDataIsNullAlert:\"数据为空无法设置!\",\r\n },\r\n print:{\r\n normalBtn:\"常规视图\",\r\n layoutBtn:\"页面布局\",\r\n pageBtn:\"分页预览\",\r\n\r\n menuItemPrint:\"打印(Ctrl+P)\",\r\n menuItemAreas:\"打印区域\",\r\n menuItemRows:\"打印标题行\",\r\n menuItemColumns:\"打印标题列\",\r\n },\r\n edit:{\r\n typing:\"正在输入\",\r\n },\r\n websocket:{\r\n success: 'WebSocket连接成功',\r\n refresh: 'WebSocket连接发生错误, 请刷新页面!',\r\n wait: 'WebSocket连接发生错误, 请耐心等待!',\r\n close: 'WebSocket连接关闭',\r\n contact: '服务器通信发生错误,请刷新页面后再试,如若不行请联系管理员!',\r\n support: '当前浏览器不支持WebSocket',\r\n }\r\n\r\n};\r\n","export default {\r\n functionlist:[{\r\n \"n\": \"SUMIF\",\r\n \"t\": 0,\r\n \"d\": \"Returns a conditional sum across a range.\",\r\n \"a\": \"A conditional sum across a range.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range which is tested against `criterion`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion\",\r\n \"detail\": \"The pattern or test to apply to `range`.\",\r\n \"example\": \"\\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"sum_range\",\r\n \"detail\": \"The range to be summed, if different from `range`.\",\r\n \"example\": \"B1:B10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"TAN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the tangent of an angle provided in radians.\",\r\n \"a\": \"Tangent of an angle provided in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to find the tangent of, in radians.\",\r\n \"example\": \"45*PI()/180\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TANH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the hyperbolic tangent of any real number.\",\r\n \"a\": \"Hyperbolic tangent of any real number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Any real value to calculate the hyperbolic tangent of.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CEILING\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number up to the nearest integer multiple of specified significance `factor`.\",\r\n \"a\": \"Rounds number up to nearest multiple of a factor.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round up to the nearest integer multiple of `factor`.\",\r\n \"example\": \"23.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The number to whose multiples `value` will be rounded.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ATAN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse tangent of a value, in radians.\",\r\n \"a\": \"Inverse tangent of a value, in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse tangent.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ASINH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse hyperbolic sine of a number.\",\r\n \"a\": \"Inverse hyperbolic sine of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse hyperbolic sine.\",\r\n \"example\": \"0.9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ABS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the absolute value of a number.\",\r\n \"a\": \"Absolute value of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number of which to return the absolute value.\",\r\n \"example\": \"-2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ACOS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse cosine of a value, in radians.\",\r\n \"a\": \"Inverse cosine of a value, in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse cosine. Must be between `-1` and `1`, inclusive.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ACOSH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse hyperbolic cosine of a number.\",\r\n \"a\": \"Inverse hyperbolic cosine of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse hyperbolic cosine. Must be greater than or equal to `1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MULTINOMIAL\",\r\n \"t\": 0,\r\n \"d\": \"Returns the factorial of the sum of values divided by the product of the values' factorials.\",\r\n \"a\": \"Multinomial distribution function.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ATANH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse hyperbolic tangent of a number.\",\r\n \"a\": \"Inverse hyperbolic tangent of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse hyperbolic tangent. Must be between -1 and 1, exclusive.\",\r\n \"example\": \"0.9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ATAN2\",\r\n \"t\": 0,\r\n \"d\": \"Returns the angle between the x-axis and a line segment from the origin (0,0) to specified coordinate pair (`x`,`y`), in radians.\",\r\n \"a\": \"Arctangent of a value.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The x coordinate of the endpoint of the line segment for which to calculate the angle from the x-axis.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"y\",\r\n \"detail\": \"The y coordinate of the endpoint of the line segment for which to calculate the angle from the x-axis.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTBLANK\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of empty values in a list of values and ranges.\",\r\n \"a\": \"Number of empty values.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range in which to count the number of blanks.\",\r\n \"example\": \"A2:C100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"COSH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the hyperbolic cosine of any real number.\",\r\n \"a\": \"Hyperbolic cosine of any real number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Any real value to calculate the hyperbolic cosine of.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"INT\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number down to the nearest integer that is less than or equal to it.\",\r\n \"a\": \"Rounds number down to nearest integer.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round down to the nearest integer.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISEVEN\",\r\n \"t\": 0,\r\n \"d\": \"Checks whether the provided value is even.\",\r\n \"a\": \"Whether the provided value is even.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as even.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISODD\",\r\n \"t\": 0,\r\n \"d\": \"Checks whether the provided value is odd.\",\r\n \"a\": \"Whether the provided value is odd.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as odd.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LCM\",\r\n \"t\": 0,\r\n \"d\": \"Returns the least common multiple of one or more integers.\",\r\n \"a\": \"Least common multiple of one or more integers.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range whose factors to consider in a calculation to find the least common multiple.\",\r\n \"example\": \"A2:A5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges whose factors to consider to find the least common multiple.\",\r\n \"example\": \"3\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the logarithm of a number, base e (Euler's number).\",\r\n \"a\": \"The logarithm of a number, base e (euler's number).\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the logarithm, base e.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOG\",\r\n \"t\": 0,\r\n \"d\": \"Returns the logarithm of a number with respect to a base.\",\r\n \"a\": \"The logarithm of a number with respect to a base.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the logarithm.\",\r\n \"example\": \"128\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"base\",\r\n \"detail\": \"The base to use for calculation of the logarithm.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOG10\",\r\n \"t\": 0,\r\n \"d\": \"Returns the logarithm of a number, base 10.\",\r\n \"a\": \"The logarithm of a number, base 10.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the logarithm, base 10.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MOD\",\r\n \"t\": 0,\r\n \"d\": \"Returns the result of the modulo operator, the remainder after a division operation.\",\r\n \"a\": \"Modulo (remainder) operator.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The number to be divided to find the remainder.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The number to divide by.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MROUND\",\r\n \"t\": 0,\r\n \"d\": \"Rounds one number to the nearest integer multiple of another.\",\r\n \"a\": \"Rounds a number to the nearest integer multiple.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number to round to the nearest integer multiple of another.\",\r\n \"example\": \"21\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The number to whose multiples `value` will be rounded.\",\r\n \"example\": \"14\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ODD\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number up to the nearest odd integer.\",\r\n \"a\": \"Rounds a number up to the nearest odd integer.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to the next greatest odd number.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMSQ\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sum of the squares of a series of numbers and/or cells.\",\r\n \"a\": \"Sum of squares.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first number or range whose squares to add together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional numbers or ranges whose squares to add to the square(s) of `value1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COMBIN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the number of ways to choose some number of objects from a pool of a given size of objects.\",\r\n \"a\": \"Number of combinations from a set of objects.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"n\",\r\n \"detail\": \"The size of the pool of objects to choose from.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"k\",\r\n \"detail\": \"The number of objects to choose.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUM\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sum of a series of numbers and/or cells.\",\r\n \"a\": \"Sum of a series of numbers and/or cells.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first number or range to add together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional numbers or ranges to add to `value1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SUBTOTAL\",\r\n \"t\": 0,\r\n \"d\": \"Returns a subtotal for a vertical range of cells using a specified aggregation function.\",\r\n \"a\": \"Subtotal for a range using a specific function.\",\r\n \"m\": [2, 256],\r\n \"p\": [{\r\n \"name\": \"function_code\",\r\n \"detail\": \"The function to use in subtotal aggregation.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"range1\",\r\n \"detail\": \"The first range over which to calculate a subtotal.\",\r\n \"example\": \"A2:A5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"range2\",\r\n \"detail\": \"Additional ranges over which to calculate subtotals.\",\r\n \"example\": \"B2:B8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"ASIN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the inverse sine of a value, in radians.\",\r\n \"a\": \"Inverse sine of a value, in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse sine. Must be between `-1` and `1`, inclusive.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTIF\",\r\n \"t\": 1,\r\n \"d\": \"Returns a conditional count across a range.\",\r\n \"a\": \"A conditional count across a range.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range that is tested against `criterion`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion\",\r\n \"detail\": \"The pattern or test to apply to `range`.\",\r\n \"example\": \"\\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RADIANS\",\r\n \"t\": 0,\r\n \"d\": \"Converts an angle value in degrees to radians.\",\r\n \"a\": \"Converts an angle value in degrees to radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to convert from degrees to radians.\",\r\n \"example\": \"180\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RAND\",\r\n \"t\": 0,\r\n \"d\": \"Returns a random number between 0 inclusive and 1 exclusive.\",\r\n \"a\": \"A random number between 0 inclusive and 1 exclusive.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"COUNTUNIQUE\",\r\n \"t\": 0,\r\n \"d\": \"Counts the number of unique values in a list of specified values and ranges.\",\r\n \"a\": \"Counts number of unique values in a range.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider for uniqueness.\",\r\n \"example\": \"A1:C100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider for uniqueness.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DEGREES\",\r\n \"t\": 0,\r\n \"d\": \"Converts an angle value in radians to degrees.\",\r\n \"a\": \"Converts an angle value in radians to degrees.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to convert from radians to degrees.\",\r\n \"example\": \"PI()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ERFC\",\r\n \"t\": 9,\r\n \"d\": \"Returns the complementary Gauss error function of a value.\",\r\n \"a\": \"Complementary gauss error function of a value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"z\",\r\n \"detail\": \"The number for which to calculate the complementary Gauss error function.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EVEN\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number up to the nearest even integer.\",\r\n \"a\": \"Rounds a number up to the nearest even integer.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to the next greatest even number.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EXP\",\r\n \"t\": 0,\r\n \"d\": \"Returns Euler's number, e (~2.718) raised to a power.\",\r\n \"a\": \"Euler's number, e (~2.718) raised to a power.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"exponent\",\r\n \"detail\": \"The exponent to raise e to.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FACT\",\r\n \"t\": 0,\r\n \"d\": \"Returns the factorial of a number.\",\r\n \"a\": \"Factorial of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number or reference to a number whose factorial will be calculated and returned.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FACTDOUBLE\",\r\n \"t\": 0,\r\n \"d\": \"Returns the \\\"double factorial\\\" of a number.\",\r\n \"a\": \"\\\"double factorial\\\" of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number or reference to a number whose double factorial will be calculated and returned.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PI\",\r\n \"t\": 0,\r\n \"d\": \"Returns the value of Pi to 14 decimal places.\",\r\n \"a\": \"The number pi.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"FLOOR\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number down to the nearest integer multiple of specified significance `factor`.\",\r\n \"a\": \"Rounds number down to nearest multiple of a factor.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round down to the nearest integer multiple of `factor`.\",\r\n \"example\": \"23.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The number to whose multiples `value` will be rounded.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GCD\",\r\n \"t\": 0,\r\n \"d\": \"Returns the greatest common divisor of one or more integers.\",\r\n \"a\": \"Greatest common divisor of one or more integers.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range whose factors to consider in a calculation to find the greatest common divisor.\",\r\n \"example\": \"A2:A5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges whose factors to consider to find the greatest common divisor.\",\r\n \"example\": \"96\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANDBETWEEN\",\r\n \"t\": 0,\r\n \"d\": \"Returns a uniformly random integer between two values, inclusive.\",\r\n \"a\": \"Random integer between two values, inclusive.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"low\",\r\n \"detail\": \"The low end of the random range.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"high\",\r\n \"detail\": \"The high end of the random range.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ROUND\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number to a certain number of decimal places according to standard rules.\",\r\n \"a\": \"Rounds a number according to standard rules.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to `places` number of places.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of decimal places to which to round.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ROUNDDOWN\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number to a certain number of decimal places, always rounding down to the next valid increment.\",\r\n \"a\": \"Rounds down a number.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to `places` number of places, always rounding down.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of decimal places to which to round.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ROUNDUP\",\r\n \"t\": 0,\r\n \"d\": \"Rounds a number to a certain number of decimal places, always rounding up to the next valid increment.\",\r\n \"a\": \"Rounds up a number.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to round to `places` number of places, always rounding up.\",\r\n \"example\": \"99.44\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of decimal places to which to round.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SERIESSUM\",\r\n \"t\": 0,\r\n \"d\": \"Given parameters `x`, `n`, `m`, and `a`, returns the power series sum a\",\r\n \"a\": \"Sum of a power series.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the power series. Varies depending on the type of approximation, may be angle, exponent, or some other value.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"n\",\r\n \"detail\": \"The initial power to which to raise `x` in the power series.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"m\",\r\n \"detail\": \"The additive increment by which to increase `x`.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"a\",\r\n \"detail\": \"The array or range containing the coefficients of the power series.\",\r\n \"example\": \"{FACT(0)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SIGN\",\r\n \"t\": 0,\r\n \"d\": \"Given an input number, returns `-1` if it is negative, `1` if positive, and `0` if it is zero.\",\r\n \"a\": \"Sign of a provided number (+/-/0).\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose sign will be evaluated.\",\r\n \"example\": \"-42\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SIN\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sine of an angle provided in radians.\",\r\n \"a\": \"Sine of an angle provided in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to find the sine of, in radians.\",\r\n \"example\": \"PI()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SINH\",\r\n \"t\": 0,\r\n \"d\": \"Returns the hyperbolic sine of any real number.\",\r\n \"a\": \"Hyperbolic sine of any real number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Any real value to calculate the hyperbolic sine of.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SQRT\",\r\n \"t\": 0,\r\n \"d\": \"Returns the positive square root of a positive number.\",\r\n \"a\": \"Positive square root of a positive number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number for which to calculate the positive square root.\",\r\n \"example\": \"9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SQRTPI\",\r\n \"t\": 0,\r\n \"d\": \"Returns the positive square root of the product of Pi and the given positive number.\",\r\n \"a\": \"Square root of the product of pi and number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The number which will be multiplied by Pi and have the product's square root returned\",\r\n \"example\": \"9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GAMMALN\",\r\n \"t\": 1,\r\n \"d\": \"Returns the logarithm of a specified Gamma function, base e (Euler's number).\",\r\n \"a\": \"Logarithm of gamma function.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The input to the Gamma function. The natural logarithm of Gamma(`value`) will be returned.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the cosine of an angle provided in radians.\",\r\n \"a\": \"Cosine of an angle provided in radians.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"angle\",\r\n \"detail\": \"The angle to find the cosine of, in radians.\",\r\n \"example\": \"PI()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TRUNC\",\r\n \"t\": 0,\r\n \"d\": \"Truncates a number to a certain number of significant digits by omitting less significant digits.\",\r\n \"a\": \"Truncates a number.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be truncated.\",\r\n \"example\": \"3.141592654\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"places\",\r\n \"detail\": \"The number of significant digits to the right of the decimal point to retain.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"QUOTIENT\",\r\n \"t\": 0,\r\n \"d\": \"Returns one number divided by another.\",\r\n \"a\": \"One number divided by another.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The number to be divided.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The number to divide by.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"POWER\",\r\n \"t\": 0,\r\n \"d\": \"Returns a number raised to a power.\",\r\n \"a\": \"A number raised to a power.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"base\",\r\n \"detail\": \"The number to raise to the `exponent` power.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"exponent\",\r\n \"detail\": \"The exponent to raise `base` to.\",\r\n \"example\": \"0.5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMIFS\",\r\n \"t\": 0,\r\n \"d\": \"Returns the sum of a range depending on multiple criteria.\",\r\n \"a\": \"Sums a range depending on multiple criteria.\",\r\n \"m\": [3, 257],\r\n \"p\": [{\r\n \"name\": \"sum_range\",\r\n \"detail\": \"The range to sum.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criteria_range1\",\r\n \"detail\": \"The range to check against criterion1.\",\r\n \"example\": \" B1:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion1\",\r\n \"detail\": \"The pattern or test to apply to criteria_range1.\",\r\n \"example\": \" \\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range2\",\r\n \"detail\": \"Additional ranges to check.\",\r\n \"example\": \" C1:C10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTIFS\",\r\n \"t\": 1,\r\n \"d\": \"Returns the count of a range depending on multiple criteria.\",\r\n \"a\": \"Count values depending on multiple criteria.\",\r\n \"m\": [2, 256],\r\n \"p\": [{\r\n \"name\": \"criteria_range1\",\r\n \"detail\": \"The range to check against `criterion1`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"criterion1\",\r\n \"detail\": \"The pattern or test to apply to `criteria_range1`.\",\r\n \"example\": \" \\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range2\",\r\n \"detail\": \"Additional ranges to check.\",\r\n \"example\": \" B1:B10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PRODUCT\",\r\n \"t\": 0,\r\n \"d\": \"Returns the result of multiplying a series of numbers together.\",\r\n \"a\": \"Result of multiplying a series of numbers together.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"factor1\",\r\n \"detail\": \"The first number or range to calculate for the product.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor2\",\r\n \"detail\": \"More numbers or ranges to calculate for the product.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HARMEAN\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the harmonic mean of a dataset.\",\r\n \"a\": \"The harmonic mean of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HYPGEOMDIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability of drawing a certain number of successes in a certain number of tries given a population of a certain size containing a certain number of successes, without replacement of draws.\",\r\n \"a\": \"Hypergeometric distribution probability.\",\r\n \"m\": [5, 5],\r\n \"p\": [{\r\n \"name\": \"num_successes\",\r\n \"detail\": \"The desired number of successes.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"num_draws\",\r\n \"detail\": \"The number of permitted draws.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"successes_in_pop\",\r\n \"detail\": \"The total number of successes in the population.\",\r\n \"example\": \"20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"pop_size\",\r\n \"detail\": \"The total size of the population\",\r\n \"example\": \"40\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf cumulative is TRUE(), HYPGEOM.DIST returns the cumulative distribution function;\\n\\nif FALSE(), it returns the probability density function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"INTERCEPT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the y-value at which the line resulting from linear regression of a dataset will intersect the y-axis (x=0).\",\r\n \"a\": \"Y-intercept of line derived via linear regression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"KURT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the kurtosis of a dataset, which describes the shape, and in particular the \\\"peakedness\\\" of that dataset.\",\r\n \"a\": \"Kurtosis of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the dataset.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the dataset.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LARGE\",\r\n \"t\": 1,\r\n \"d\": \"Returns the nth largest element from a data set, where n is user-defined.\",\r\n \"a\": \"Nth largest element from a data set.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"Array or range containing the dataset to consider.\",\r\n \"example\": \"A2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"n\",\r\n \"detail\": \"The rank from largest to smallest of the element to return.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STDEVA\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the standard deviation based on a sample, setting text to the value `0`.\",\r\n \"a\": \"Standard deviation of sample (text as 0).\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STDEVP\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the standard deviation based on an entire population.\",\r\n \"a\": \"Standard deviation of an entire population.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GEOMEAN\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the geometric mean of a dataset.\",\r\n \"a\": \"The geometric mean of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANK_EQ\",\r\n \"t\": 1,\r\n \"d\": \"Returns the rank of a specified value in a dataset. If there is more than one entry of the same value in the dataset, the top rank of the entries will be returned.\",\r\n \"a\": \"Top rank of a specified value in a dataset.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose rank will be determined.\",\r\n \"example\": \"A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"is_ascending\",\r\n \"detail\": \"Whether to consider the values in `data` in descending or ascending order. If omitted, the default is descending (FALSE).\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANK_AVG\",\r\n \"t\": 1,\r\n \"d\": \"Returns the rank of a specified value in a dataset. If there is more than one entry of the same value in the dataset, the average rank of the entries will be returned.\",\r\n \"a\": \"Average rank of a specified value in a dataset.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose rank will be determined.\",\r\n \"example\": \"A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"is_ascending\",\r\n \"detail\": \"Whether to consider the values in `data` in descending or ascending order. If omitted, the default is descending (FALSE).\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTRANK_EXC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the percentage rank (percentile) from 0 to 1 exclusive of a specified value in a dataset.\",\r\n \"a\": \"Percentage rank (percentile) from 0 to 1 exclusive.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose percentage rank will be determined.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant figures to use in the calculation. Default is 3.\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTRANK_INC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the percentage rank (percentile) from 0 to 1 inclusive of a specified value in a dataset.\",\r\n \"a\": \"Percentage rank (percentile) from 0 to 1 inclusive.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose percentage rank will be determined.\",\r\n \"example\": \" A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant figures to use in the calculation. Default is 3.\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FORECAST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the expected y-value for a specified x based on a linear regression of a dataset.\",\r\n \"a\": \"Expected y-value based of linear regression.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The value on the x-axis to forecast.\",\r\n \"example\": \"A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FISHERINV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the inverse Fisher transformation of a specified value.\",\r\n \"a\": \"Inverse fisher transformation of a specified value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the inverse Fisher transformation.\",\r\n \"example\": \"0.962\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FISHER\",\r\n \"t\": 1,\r\n \"d\": \"Returns the Fisher transformation of a specified value.\",\r\n \"a\": \"Fisher transformation of a specified value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value for which to calculate the Fisher transformation.\",\r\n \"example\": \"0.962\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MODE_SNGL\",\r\n \"t\": 1,\r\n \"d\": \"Returns the most commonly occurring value in a dataset.\",\r\n \"a\": \"Most commonly occurring value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating mode.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating mode.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"WEIBULL_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the Weibull distribution function (or Weibull cumulative distribution function) for a specified shape and scale.\",\r\n \"a\": \"Weibull distribution function.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the Weibull distribution function.\",\r\n \"example\": \"2.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"shape\",\r\n \"detail\": \"The shape parameter of the Weibull distribution function.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"scale\",\r\n \"detail\": \"The scale parameter of the Weibull distribution function.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the cumulative distribution function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COUNT\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of numeric values in a dataset.\",\r\n \"a\": \"The number of numeric values in dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when counting.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when counting.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COUNTA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of values in a dataset.\",\r\n \"a\": \"The number of values in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when counting.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when counting.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVEDEV\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the average of the magnitudes of deviations of data from a dataset's mean.\",\r\n \"a\": \"Average magnitude of deviations from mean.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGE\",\r\n \"t\": 1,\r\n \"d\": \"Returns the numerical average value in a dataset, ignoring text.\",\r\n \"a\": \"Numerical average value in a dataset, ignoring text.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the average value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the average value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGEA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the numerical average value in a dataset.\",\r\n \"a\": \"Numerical average value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the average value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the average value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BINOM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability of drawing a certain number of successes (or a maximum number of successes) in a certain number of tries given a population of a certain size containing a certain number of successes, with replacement of draws.\",\r\n \"a\": \"Binomial distribution probability.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"num_successes\",\r\n \"detail\": \"The number of successes for which to calculate the probability in `num_trials` trials.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"num_trials\",\r\n \"detail\": \"The number of independent trials.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"prob_success\",\r\n \"detail\": \"The probability of success in any given trial.\",\r\n \"example\": \"0.005\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the binomial cumulative distribution.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BINOM_INV\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the smallest value for which the cumulative binomial distribution is greater than or equal to a specified criteria.\",\r\n \"a\": \"Inverse cumulative binomial distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"num_trials\",\r\n \"detail\": \"The number of independent trials.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"prob_success\",\r\n \"detail\": \"The probability of success in any given trial.\",\r\n \"example\": \"0.005\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"target_prob\",\r\n \"detail\": \"The desired threshold probability.\",\r\n \"example\": \"0.8\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CONFIDENCE_NORM\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the width of half the confidence interval for a normal distribution.\",\r\n \"a\": \"Confidence interval for a normal distribution.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"alpha\",\r\n \"detail\": \"One minus the desired confidence level. E.g. `0.1` for `0.9`, or 90%, confidence.\",\r\n \"example\": \"0.05\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation of the population.\",\r\n \"example\": \"1.6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"pop_size\",\r\n \"detail\": \"The size of the population.\",\r\n \"example\": \"250\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CORREL\",\r\n \"t\": 1,\r\n \"d\": \"Calculates r, the Pearson product-moment correlation coefficient of a dataset.\",\r\n \"a\": \"Pearson Product-Moment Correlation Coefficient.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COVARIANCE_P\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the covariance of a dataset.\",\r\n \"a\": \"The covariance of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COVARIANCE_S\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the sample covariance of a dataset.\",\r\n \"a\": \"The sample covariance of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEVSQ\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the sum of squares of deviations based on a sample.\",\r\n \"a\": \"The sum of squares of deviations based on a sample.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EXPON_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the exponential distribution function with a specified lambda at a specified value.\",\r\n \"a\": \"Exponential distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the exponential distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"lambda\",\r\n \"detail\": \"The lambda to specify the exponential distribution function.\",\r\n \"example\": \"0.5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the exponential cumulative distribution.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGEIF\",\r\n \"t\": 1,\r\n \"d\": \"Returns the average of a range depending on criteria.\",\r\n \"a\": \"Average of values depending on criteria.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"criteria_range\",\r\n \"detail\": \"The range to check against `criterion`.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criterion\",\r\n \"detail\": \"The pattern or test to apply to `criteria_range`.\",\r\n \"example\": \"\\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"average_range\",\r\n \"detail\": \"The range to average. If not included, `criteria_range` is used for the average instead.\",\r\n \"example\": \"B1:B10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AVERAGEIFS\",\r\n \"t\": 1,\r\n \"d\": \"Returns the average of a range depending on multiple criteria.\",\r\n \"a\": \"Average of values depending on multiple criteria.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"average_range\",\r\n \"detail\": \"The range to average.\",\r\n \"example\": \"A1:A10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range1\",\r\n \"detail\": \"The range to check against `criterion1`.\",\r\n \"example\": \" B1:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criterion1\",\r\n \"detail\": \"The pattern or test to apply to `criteria_range1`.\",\r\n \"example\": \" \\\">20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria_range2\",\r\n \"detail\": \"Additional ranges to check.\",\r\n \"example\": \" C1:C10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PERMUT\",\r\n \"t\": 1,\r\n \"d\": \"Returns the number of ways to choose some number of objects from a pool of a given size of objects, considering order.\",\r\n \"a\": \"Number of permutations from a number of objects.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"n\",\r\n \"detail\": \"The size of the pool of objects to choose from.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"k\",\r\n \"detail\": \"The number of objects to choose.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TRIMMEAN\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the mean of a dataset excluding some proportion of data from the high and low ends of the dataset.\",\r\n \"a\": \"Mean of a dataset excluding high/low ends.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"Array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"exclude_proportion\",\r\n \"detail\": \"The proportion of the dataset to exclude, from the extremities of the set.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTILE_EXC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value at a given percentile of a dataset exclusive of 0 and 1.\",\r\n \"a\": \"Value at a given percentile of a dataset exclusive of 0 and 1.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"percentile\",\r\n \"detail\": \"The percentile, exclusive of 0 and 1, whose value within 'data' will be calculated and returned.\",\r\n \"example\": \"0.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PERCENTILE_INC\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value at a given percentile of a dataset.\",\r\n \"a\": \"Value at a given percentile of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"percentile\",\r\n \"detail\": \"The percentile whose value within `data` will be calculated and returned.`\",\r\n \"example\": \"0.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PEARSON\",\r\n \"t\": 1,\r\n \"d\": \"Calculates r, the Pearson product-moment correlation coefficient of a dataset.\",\r\n \"a\": \"Pearson Product-Moment Correlation Coefficient.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_S_INV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the inverse standard normal distribution function for a specified value.\",\r\n \"a\": \"Inverse standard normal distribution function.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the inverse standard normal distribution function.\",\r\n \"example\": \"0.75\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_S_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the standard normal cumulative distribution function for a specified value.\",\r\n \"a\": \"Standard normal cumulative distribution function.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the standard normal cumulative distribution function.\",\r\n \"example\": \"2.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf TRUE(), it returns the cumulative distribution function;\\n\\nIf it is FALSE(), it returns the probability density function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_INV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the inverse normal distribution function for a specified value, mean, and standard deviation.\",\r\n \"a\": \"Inverse normal distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the inverse normal distribution function.\",\r\n \"example\": \"0.75\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the normal distribution function.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the normal distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NORM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the normal distribution function (or normal cumulative distribution function) for a specified value, mean, and standard deviation.\",\r\n \"a\": \"Normal distribution function.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the normal distribution function.\",\r\n \"example\": \"2.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the normal distribution function.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the normal distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the normal cumulative distribution function rather than the distribution function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NEGBINOM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability of drawing a certain number of failures before a certain number of successes given a probability of success in independent trials.\",\r\n \"a\": \"Negative binomial distribution probability.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"num_failures\",\r\n \"detail\": \"The number of failures to model.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"num_successes\",\r\n \"detail\": \"The number of successes to model.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"prob_success\",\r\n \"detail\": \"The probability of success in any given trial.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf TRUE(), it returns the cumulative distribution function;\\n\\nIf it is FALSE(), it returns the probability density function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"MINA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the minimum numeric value in a dataset.\",\r\n \"a\": \"Minimum numeric value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the minimum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the minimum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MIN\",\r\n \"t\": 1,\r\n \"d\": \"Returns the minimum value in a numeric dataset.\",\r\n \"a\": \"Minimum value in a numeric dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the minimum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the minimum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MEDIAN\",\r\n \"t\": 1,\r\n \"d\": \"Returns the median value in a numeric dataset.\",\r\n \"a\": \"Median value in a numeric dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the median value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the median value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MAXA\",\r\n \"t\": 1,\r\n \"d\": \"Returns the maximum numeric value in a dataset.\",\r\n \"a\": \"Maximum numeric value in a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the maximum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the maximum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MAX\",\r\n \"t\": 1,\r\n \"d\": \"Returns the maximum value in a numeric dataset.\",\r\n \"a\": \"Maximum value in a numeric dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range to consider when calculating the maximum value.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to consider when calculating the maximum value.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOGNORM_INV\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the inverse log-normal cumulative distribution with given mean and standard deviation at a specified value.\",\r\n \"a\": \"Inverse log-normal cumulative distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the inverse log-normal cumulative distribution function.\",\r\n \"example\": \"0.4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the inverse log-normal cumulative distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the inverse log-normal cumulative distribution function.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LOGNORM_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the log-normal cumulative distribution with given mean and standard deviation at a specified value.\",\r\n \"a\": \"Log-normal cumulative distribution probability.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the log-normal cumulative distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the log-normal cumulative distribution function.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation (sigma) of the log-normal cumulative distribution function.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Determine the logical value of the function form. \\n\\nIf TRUE(), it returns the cumulative distribution function;\\n\\nIf it is FALSE(), it returns the probability density function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"Z_TEST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the one-tailed p-value of a Z-test with standard distribution.\",\r\n \"a\": \"One-tailed p-value of a z-test.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"value\",\r\n \"detail\": \"The test statistic to use in the Z-test.\",\r\n \"example\": \"B2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation to assume for the Z-test. If this is not provided, the standard deviation of the data will be used.\",\r\n \"example\": \"3\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PROB\",\r\n \"t\": 1,\r\n \"d\": \"Given a set of values and corresponding probabilities, calculates the probability that a value chosen at random falls between two limits.\",\r\n \"a\": \"Probability values lie in a range.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"Array or range containing the dataset to consider.\",\r\n \"example\": \"A3:A6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"probabilities\",\r\n \"detail\": \"Array or range containing probabilities corresponding to `data`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"low_limit\",\r\n \"detail\": \"The lower bound on the value range for which to calculate the probability.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"high_limit\",\r\n \"detail\": \"The upper bound on the value range for which to calculate the probability.\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"QUARTILE_EXC\",\r\n \"t\": 1,\r\n \"d\": \"Returns a value nearest to a specified quartile of a dataset exclusive of 0 and 4.\",\r\n \"a\": \"Value nearest to a specific quartile of a dataset exclusive of 0 and 4.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"quartile_number\",\r\n \"detail\": \"Which quartile to return.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"QUARTILE_INC\",\r\n \"t\": 1,\r\n \"d\": \"Returns a value nearest to a specified quartile of a dataset.\",\r\n \"a\": \"Value nearest to a specific quartile of a dataset.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"quartile_number\",\r\n \"detail\": \"Which quartile value to return.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"POISSON_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Returns the value of the Poisson distribution function (or Poisson cumulative distribution function) for a specified value and mean.\",\r\n \"a\": \"Poisson distribution function.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the Poisson distribution function.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean (mu) of the Poisson distribution function.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Whether to use the Poisson cumulative distribution function rather than the distribution function.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RSQ\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the square of r, the Pearson product-moment correlation coefficient of a dataset.\",\r\n \"a\": \"Square of the correlation coefficient.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the left tail probability for a Student's t-distribution with a given input (x).\",\r\n \"a\": \"The left-tailed Student's t-distribution\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the t-distribution function.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"30\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"If cumulative is TRUE, T.DIST returns the cumulative distribution function; if FALSE, it returns the probability density function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"T_DIST_2T\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the probability for two tailed Student's t-distribution with a given input (x).\",\r\n \"a\": \"The two tailed Student's t-distribution\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the t-distribution function.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"30\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_DIST_RT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the right tail probability for a Student's t-distribution with a given input (x).\",\r\n \"a\": \"The right-tailed Student's t-distribution\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the t-distribution function.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"30\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_INV\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the negative inverse of the one-tailed TDIST function.\",\r\n \"a\": \"T.INV\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"probability\",\r\n \"detail\": \"The probability associated with the two-tailed t-distribution.\",\r\n \"example\": \"0.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_INV_2T\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the inverse of the two-tailed TDIST function.\",\r\n \"a\": \"T.INV.2T\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"probability\",\r\n \"detail\": \"The probability associated with the two-tailed t-distribution.\",\r\n \"example\": \"0.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom\",\r\n \"detail\": \"The number of degrees of freedom.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"T_TEST\",\r\n \"t\": 1,\r\n \"d\": \"t-test. Returns the probability associated with Student's t-test. Determines whether two samples are likely to have come from the same two underlying populations that have the same mean.\",\r\n \"a\": \"Returns the probability associated with t-test.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"range1\",\r\n \"detail\": \"The first sample of data or group of cells to consider for the t-test.\",\r\n \"example\": \"A1:A4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"range2\",\r\n \"detail\": \"The second sample of data or group of cells to consider for the t-test.\",\r\n \"example\": \"B1:B4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"tails\",\r\n \"detail\": \"Specifies the number of distribution tails.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"type\",\r\n \"detail\": \"Specifies the type of t-test.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"F_DIST\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the left-tailed F probability distribution (degree of diversity) for two data sets with given input x. Alternately called Fisher-Snedecor distribution or Snedecor's F distribution.\",\r\n \"a\": \"F probability distribution (left-tailed).\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the F probability distribution function. The value at which to evaluate the function.\",\r\n \"example\": \"15.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom1\",\r\n \"detail\": \"The numerator of the number of degrees of freedom.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom2\",\r\n \"detail\": \"The denominator of the number of degrees of freedom.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cumulative\",\r\n \"detail\": \"Logical value that determines the form of the function.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"F_DIST_RT\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the right-tailed F probability distribution (degree of diversity) for two data sets with given input x. Alternately called Fisher-Snedecor distribution or Snedecor's F distribution.\",\r\n \"a\": \"F probability distribution.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"x\",\r\n \"detail\": \"The input to the F probability distribution function. The value at which to evaluate the function.\",\r\n \"example\": \"15.35\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom1\",\r\n \"detail\": \"The numerator of the number of degrees of freedom.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"degrees_freedom2\",\r\n \"detail\": \"The denominator of the number of degrees of freedom.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VAR_P\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on an entire population.\",\r\n \"a\": \"Variance of entire population.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VAR_S\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on a sample.\",\r\n \"a\": \"Variance.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VARA\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on a sample, setting text to the value `0`.\",\r\n \"a\": \"Variance of sample (text as 0).\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the sample.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the sample.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"VARPA\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the variance based on an entire population, setting text to the value `0`.\",\r\n \"a\": \"Variance of entire population (text as 0).\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the population.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the population.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STEYX\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the standard error of the predicted y-value for each x in the regression of a dataset.\",\r\n \"a\": \"Standard error of predicted y-values in regression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"STANDARDIZE\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the normalized equivalent of a random variable given mean and standard deviation of the distribution.\",\r\n \"a\": \"Normalized equivalent of a random variable.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value of the random variable to normalize.\",\r\n \"example\": \"96\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"mean\",\r\n \"detail\": \"The mean of the distribution.\",\r\n \"example\": \"80\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"standard_deviation\",\r\n \"detail\": \"The standard deviation of the distribution.\",\r\n \"example\": \"6.7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SMALL\",\r\n \"t\": 1,\r\n \"d\": \"Returns the nth smallest element from a data set, where n is user-defined.\",\r\n \"a\": \"Nth smallest element in a data set.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the dataset to consider.\",\r\n \"example\": \"A2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"n\",\r\n \"detail\": \"The rank from smallest to largest of the element to return.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SLOPE\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the slope of the line resulting from linear regression of a dataset.\",\r\n \"a\": \"Slope of line from linear regression of data.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data_y\",\r\n \"detail\": \"The range representing the array or matrix of dependent data.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"data_x\",\r\n \"detail\": \"The range representing the array or matrix of independent data.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SKEW\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the skewness of a dataset, which describes the symmetry of that dataset about the mean.\",\r\n \"a\": \"Skewness of a dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the dataset.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the dataset.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SKEW_P\",\r\n \"t\": 1,\r\n \"d\": \"Calculates the skewness of a dataset, which describes the symmetry of that dataset about the mean. This assumes the dataset is for the population.\",\r\n \"a\": \"Skewness of a population's dataset.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value or range of the dataset.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional values or ranges to include in the dataset.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"VLOOKUP\",\r\n \"t\": 2,\r\n \"d\": \"Vertical lookup. Searches down the first column of a range for a key and returns the value of a specified cell in the row found.\",\r\n \"a\": \"Vertical lookup.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"10003\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"range\",\r\n \"detail\": \"The range to consider for the search. The first column in the range is searched for the key specified in `search_key`.\",\r\n \"example\": \"A2:B26\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"index\",\r\n \"detail\": \"The column index of the value to be returned, where the first column in `range` is numbered 1.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"is_sorted\",\r\n \"detail\": \"Indicates whether the column to be searched (the first column of the specified range) is sorted, in which case the closest match for `search_key` will be returned.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HLOOKUP\",\r\n \"t\": 2,\r\n \"d\": \"Horizontal lookup. Searches across the first row of a range for a key and returns the value of a specified cell in the column found.\",\r\n \"a\": \"Horizontal lookup\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"10003\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"range\",\r\n \"detail\": \"The range to consider for the search. The first row in the range is searched for the key specified in `search_key`.\",\r\n \"example\": \"A2:Z6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"index\",\r\n \"detail\": \"The row index of the value to be returned, where the first row in `range` is numbered 1.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"is_sorted\",\r\n \"detail\": \"Indicates whether the row to be searched (the first row of the specified range) is sorted.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LOOKUP\",\r\n \"t\": 2,\r\n \"d\": \"Looks through a sorted row or column for a key and returns the value of the cell in a result range located in the same position as the search row or column.\",\r\n \"a\": \"Look up a value.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for in the row or column. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"10003\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"search_range|search_result_array\",\r\n \"detail\": \"One method of using this function is to provide a single sorted row or column `search_range` to look through for the `search_key` with a second argument `result_range`. The other way is to combine these two arguments into one `search_result_array` where the first row or column is searched and a value is returned from the last row or column in the array. If `search_key` is not found, a non-exact match may be returned.\",\r\n \"example\": \"A1:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"result_range\",\r\n \"detail\": \"The range from which to return a result. The value returned corresponds to the location where `search_key` is found in `search_range`. This range must be only a single row or column and should not be used if using the `search_result_array` method.\",\r\n \"example\": \"B1:B100\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ADDRESS\",\r\n \"t\": 2,\r\n \"d\": \"Returns a cell reference as a string.\",\r\n \"a\": \"Cell reference as a string.\",\r\n \"m\": [2, 5],\r\n \"p\": [{\r\n \"name\": \"row\",\r\n \"detail\": \"The row number of the cell reference\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"column\",\r\n \"detail\": \"The column number (not name) of the cell reference. `A` is column number `1`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"absolute_relative_mode\",\r\n \"detail\": \"An indicator of whether the reference is row/column absolute. `1` is row and column absolute (e.g. $A$1), `2` is row absolute and column relative (e.g. A$1), `3` is row relative and column absolute (e.g. $A1), and `4` is row and column relative (e.g. A1).\",\r\n \"example\": \"4\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"use_a1_notation\",\r\n \"detail\": \"A boolean indicating whether to use `A1` style notation (TRUE) or `R1C1` style notation (FALSE).\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"sheet\",\r\n \"detail\": \"Text indicating the name of the sheet into which the address points.\",\r\n \"example\": \"\\\"Sheet2\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"INDIRECT\",\r\n \"t\": 2,\r\n \"d\": \"Returns a cell reference specified by a string.\",\r\n \"a\": \"A cell reference specified by a string.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"cell_reference_as_string\",\r\n \"detail\": \"A cell reference, written as a string with surrounding quotation marks.\",\r\n \"example\": \"\\\"Sheet2!\\\"&B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"is_A1_notation\",\r\n \"detail\": \"Indicates if the cell reference is in A1 notation (TRUE) or R1C1 notation (FALSE).\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ROW\",\r\n \"t\": 2,\r\n \"d\": \"Returns the row number of a specified cell.\",\r\n \"a\": \"Row number of a specified cell.\",\r\n \"m\": [0, 1],\r\n \"p\": [{\r\n \"name\": \"cell_reference\",\r\n \"detail\": \"The cell whose row number will be returned.\",\r\n \"example\": \"A9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ROWS\",\r\n \"t\": 2,\r\n \"d\": \"Returns the number of rows in a specified array or range.\",\r\n \"a\": \"Number of rows in a specified array or range.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range whose row count will be returned.\",\r\n \"example\": \"A9:A62\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COLUMN\",\r\n \"t\": 2,\r\n \"d\": \"Returns the column number of a specified cell, with `A=1`.\",\r\n \"a\": \"Column number of a specified cell.\",\r\n \"m\": [0, 1],\r\n \"p\": [{\r\n \"name\": \"cell_reference\",\r\n \"detail\": \"The cell whose column number will be returned. Column `A` corresponds to `1`.\",\r\n \"example\": \"A9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COLUMNS\",\r\n \"t\": 2,\r\n \"d\": \"Returns the number of columns in a specified array or range.\",\r\n \"a\": \"Number of columns in a specified array or range.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The range whose column count will be returned.\",\r\n \"example\": \"A9:W62\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"OFFSET\",\r\n \"t\": 2,\r\n \"d\": \"Returns a range reference shifted a specified number of rows and columns from a starting cell reference.\",\r\n \"a\": \"A range reference offset relative to a cell.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"cell_reference\",\r\n \"detail\": \"The starting point from which to count the offset rows and columns.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"offset_rows\",\r\n \"detail\": \"The number of rows to offset by.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"offset_columns\",\r\n \"detail\": \"The number of columns to offset by.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"height\",\r\n \"detail\": \"The height of the range to return starting at the offset target.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"width\",\r\n \"detail\": \"The width of the range to return starting at the offset target.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MATCH\",\r\n \"t\": 2,\r\n \"d\": \"Returns the relative position of an item in a range that matches a specified value.\",\r\n \"a\": \"Position of item in range that matches value.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_key\",\r\n \"detail\": \"The value to search for. For example, `42`, `\\\"Cats\\\"`, or `I24`.\",\r\n \"example\": \"\\\"Sunday\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"range\",\r\n \"detail\": \"The one-dimensional array to be searched.\",\r\n \"example\": \"A2:A9\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"search_type\",\r\n \"detail\": \"The search method. `1` (default) finds the largest value less than or equal to `search_key` when `range` is sorted in ascending order. `0` finds the exact value when `range` is unsorted. `-1` finds the smallest value greater than or equal to `search_key` when `range` is sorted in descending order.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"INDEX\",\r\n \"t\": 2,\r\n \"d\": \"Returns the content of a cell, specified by row and column offset.\",\r\n \"a\": \"Content of cell specified by row and column offset.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"reference\",\r\n \"detail\": \"The array of cells to be offset into.\",\r\n \"example\": \"A1:C20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"row\",\r\n \"detail\": \"The number of offset rows.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"column\",\r\n \"detail\": \"The number of offset columns.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GETPIVOTDATA\",\r\n \"t\": 2,\r\n \"d\": \"Extracts an aggregated value from a pivot table that corresponds to the specified row and column headings.\",\r\n \"a\": \"Extracts an aggregated value from a pivot table that corresponds to the specified row and column headings.\",\r\n \"m\": [2, 254],\r\n \"p\": [{\r\n \"name\": \"value_name\",\r\n \"detail\": \"The name of the value in the pivot table for which you want to get data.\",\r\n \"example\": \"\\\"SUM of number of units\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"any_pivot_table_cell\",\r\n \"detail\": \"Any reference to a cell in the desired pivot table (top corner recommended).\",\r\n \"example\": \"'Pivot table'!A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"original_column\",\r\n \"detail\": \"The name of the column in the original data set (not the pivot table).\",\r\n \"example\": \"\\\"division\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"pivot_item\",\r\n \"detail\": \"The name of the row or column shown in the pivot table corresponding to *original_column* that you want to retrieve.\",\r\n \"example\": \"\\\"east\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CHOOSE\",\r\n \"t\": 2,\r\n \"d\": \"Returns an element from a list of choices based on index.\",\r\n \"a\": \"An element from a list of choices based on index.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"index\",\r\n \"detail\": \"Which choice (of the up to 30 provided) to return.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"choice1\",\r\n \"detail\": \"A potential value to return. Required. May be a reference to a cell or an individual value.\",\r\n \"example\": \"\\\"A\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"choice2\",\r\n \"detail\": \"Additional values among which to choose.\",\r\n \"example\": \"\\\"B\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HYPERLINK\",\r\n \"t\": 2,\r\n \"d\": \"Creates a hyperlink inside a cell.\",\r\n \"a\": \"Creates a hyperlink inside a cell.\",\r\n \"p\": [{\r\n \"name\": \"url\",\r\n \"detail\": \"The full URL of the link location enclosed in quotation marks, or a reference to a cell containing such a URL.\",\r\n \"example\": \"\\\"http://www.luckysheet.com/\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"link_label\",\r\n \"detail\": \"The text to display in the cell as the link, enclosed in quotation marks, or a reference to a cell containing such a label.\",\r\n \"example\": \"\\\"luckysheet\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TIME\",\r\n \"t\": 6,\r\n \"d\": \"Converts a provided hour, minute, and second into a time.\",\r\n \"a\": \"Converts hour/minute/second into a time.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"hour\",\r\n \"detail\": \"The hour component of the time.\",\r\n \"example\": \"11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"minute\",\r\n \"detail\": \"The minute component of the time.\",\r\n \"example\": \"40\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"second\",\r\n \"detail\": \"The second component of the time.\",\r\n \"example\": \"59\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TIMEVALUE\",\r\n \"t\": 6,\r\n \"d\": \"Returns the fraction of a 24-hour day the time represents.\",\r\n \"a\": \"Converts a time string into its serial number representation.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time_string\",\r\n \"detail\": \"The string that holds the time representation.\",\r\n \"example\": \"\\\"2:15 PM\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EOMONTH\",\r\n \"t\": 6,\r\n \"d\": \"Returns a date on the last day of a month that falls a specified number of months before or after another date.\",\r\n \"a\": \"Last day of a month before or after a date.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to calculate the result.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"months\",\r\n \"detail\": \"The number of months before (negative) or after (positive) 'start_date' to consider.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"EDATE\",\r\n \"t\": 6,\r\n \"d\": \"Returns a date a specified number of months before or after another date.\",\r\n \"a\": \"Date a number of months before/after another date.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to calculate the result.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"months\",\r\n \"detail\": \"The number of months before (negative) or after (positive) 'start_date' to calculate.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SECOND\",\r\n \"t\": 6,\r\n \"d\": \"Returns the second component of a specific time, in numeric format.\",\r\n \"a\": \"Second component of a specific time.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time\",\r\n \"detail\": \"The time from which to calculate the second component\",\r\n \"example\": \"TIME(11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"MINUTE\",\r\n \"t\": 6,\r\n \"d\": \"Returns the minute component of a specific time, in numeric format.\",\r\n \"a\": \"Minute component of a specific time.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time\",\r\n \"detail\": \"The time from which to calculate the minute component.\",\r\n \"example\": \"TIME(11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HOUR\",\r\n \"t\": 6,\r\n \"d\": \"Returns the hour component of a specific time, in numeric format.\",\r\n \"a\": \"Hour component of a specific time.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"time\",\r\n \"detail\": \"The time from which to calculate the hour component.\",\r\n \"example\": \"TIME(11\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NOW\",\r\n \"t\": 6,\r\n \"d\": \"Returns the current date and time as a date value.\",\r\n \"a\": \"Current date and time as a date value.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"NETWORKDAYS\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of net working days between two provided days.\",\r\n \"a\": \"Net working days between two provided days.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the date serial numbers to consider holidays.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NETWORKDAYS_INTL\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of net working days between two provided days excluding specified weekend days and holidays.\",\r\n \"a\": \"Net working days between two dates (specifying weekends).\",\r\n \"m\": [2, 4],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date of the period from which to calculate the number of net working days.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"weekend\",\r\n \"detail\": \"A number or string representing which days of the week are considered weekends.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the dates to consider as holidays.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISOWEEKNUM\",\r\n \"t\": 6,\r\n \"d\": \"Returns a number representing the ISO week of the year where the provided date falls.\",\r\n \"a\": \"ISO week number of the year.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date for which to determine the ISO week number. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"WEEKNUM\",\r\n \"t\": 6,\r\n \"d\": \"Returns a number representing the week of the year where the provided date falls.\",\r\n \"a\": \"Week number of the year.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date for which to determine the week number. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"type\",\r\n \"detail\": \"A number representing the day that a week starts on. Sunday = 1.\",\r\n \"example\": \"7\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"WEEKDAY\",\r\n \"t\": 6,\r\n \"d\": \"Returns a number representing the day of the week of the date provided.\",\r\n \"a\": \"Day of the week of the date provided (as number).\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date for which to determine the day of the week. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"type\",\r\n \"detail\": \"A number indicating which numbering system to use to represent weekdays. By default, counts starting with Sunday = 1.\",\r\n \"example\": \"7\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DAY\",\r\n \"t\": 6,\r\n \"d\": \"Returns the day of the month that a specific date falls on, in numeric format.\",\r\n \"a\": \"Day of the month that a specific date falls on.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date from which to extract the day.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DAYS\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of days between two dates.\",\r\n \"a\": \"Number of days between two dates.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end of the date range.\",\r\n \"example\": \"2011-3-15\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start of the date range.\",\r\n \"example\": \"2011-2-1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DAYS360\",\r\n \"t\": 6,\r\n \"d\": \"Returns the difference between two days based on the 360 day year used in some financial interest calculations.\",\r\n \"a\": \"Days between two dates on a 360-day year.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"method\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DATE\",\r\n \"t\": 6,\r\n \"d\": \"Converts a provided year, month, and day into a date.\",\r\n \"a\": \"Converts year/month/day into a date.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"year\",\r\n \"detail\": \"The year component of the date.\",\r\n \"example\": \"1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"month\",\r\n \"detail\": \"The month component of the date.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day\",\r\n \"detail\": \"The day component of the date.\",\r\n \"example\": \"20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATEVALUE\",\r\n \"t\": 6,\r\n \"d\": \"Converts a provided date string in a known format to a date value.\",\r\n \"a\": \"Converts a date string to a date value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date_string\",\r\n \"detail\": \"The string representing the date.\",\r\n \"example\": \"\\\"1969-7-20\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DATEDIF\",\r\n \"t\": 6,\r\n \"d\": \"Calculates the number of days, months, or years between two dates.\",\r\n \"a\": \"Date Difference.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"unit\",\r\n \"detail\": \"A string abbreviation for unit of time. For example, \\\"M\\\" for month. Accepted values are \\\"Y\\\",\\\"M\\\",\\\"D\\\",\\\"MD\\\",\\\"YM\\\",\\\"YD\\\".\",\r\n \"example\": \"16)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"WORKDAY\",\r\n \"t\": 6,\r\n \"d\": \"Calculates the date after a number of working days from a specified start date.\",\r\n \"a\": \"Number of working days from start date.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to begin counting.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"num_days\",\r\n \"detail\": \"The number of working days to advance from `start_date`. If negative, counts backwards.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the dates to consider holidays.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"WORKDAY_INTL\",\r\n \"t\": 6,\r\n \"d\": \"Calculates the date after a specified number of workdays excluding specified weekend days and holidays.\",\r\n \"a\": \"Date after a number of workdays (specifying weekends).\",\r\n \"m\": [2, 4],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The date from which to begin counting.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"num_days\",\r\n \"detail\": \"The number of working days to advance from `start_date`. If negative, counts backwards.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"weekend\",\r\n \"detail\": \"A number or string representing which days of the week are considered weekends.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"holidays\",\r\n \"detail\": \"A range or array constant containing the dates to consider holidays.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"YEAR\",\r\n \"t\": 6,\r\n \"d\": \"Returns the year specified by a given date.\",\r\n \"a\": \"Year specified by a given date.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date from which to extract the year.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"YEARFRAC\",\r\n \"t\": 6,\r\n \"d\": \"Returns the number of years, including fractional years, between two dates using a specified day count convention.\",\r\n \"a\": \"Exact number of years between two dates.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"start_date\",\r\n \"detail\": \"The start date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_date\",\r\n \"detail\": \"The end date to consider in the calculation. Must be a reference to a cell containing a date, a function returning a date type, or a number.\",\r\n \"example\": \"7\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"16)\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TODAY\",\r\n \"t\": 6,\r\n \"d\": \"Returns the current date as a date value.\",\r\n \"a\": \"Current date as a date value.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"MONTH\",\r\n \"t\": 6,\r\n \"d\": \"Returns the month of the year a specific date falls in, in numeric format.\",\r\n \"a\": \"Month of the year a specific date falls in.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"date\",\r\n \"detail\": \"The date from which to extract the month.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EFFECT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual effective interest rate given the nominal rate and number of compounding periods per year.\",\r\n \"a\": \"Annual effective interest rate.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"nominal_rate\",\r\n \"detail\": \"The nominal interest rate per year.\",\r\n \"example\": \"0.99\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"periods_per_year\",\r\n \"detail\": \"The number of compounding periods per year.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DOLLAR\",\r\n \"t\": 12,\r\n \"d\": \"Formats a number into the currency specific to your spreadsheet locale.\",\r\n \"a\": \"Formats a number as currency specific to your spreadsheet locale.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The value to be formatted.\",\r\n \"example\": \"1.2351\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_places\",\r\n \"detail\": \"The number of decimal places to display.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DOLLARDE\",\r\n \"t\": 8,\r\n \"d\": \"Converts a price quotation given as a decimal fraction into a decimal value.\",\r\n \"a\": \"Converts a decimal fraction to decimal value.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"fractional_price\",\r\n \"detail\": \"The price quotation given using fractional decimal conventions.\",\r\n \"example\": \"100.10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"unit\",\r\n \"detail\": \"The units of the fraction, e.g. `8` for 1/8ths or `32` for 1/32nds.\",\r\n \"example\": \"32\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DOLLARFR\",\r\n \"t\": 8,\r\n \"d\": \"Converts a price quotation given as a decimal value into a decimal fraction.\",\r\n \"a\": \"Converts a decimal value to decimal fraction.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_price\",\r\n \"detail\": \"The price quotation given as a decimal value.\",\r\n \"example\": \"100.125\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"unit\",\r\n \"detail\": \"The units of the desired fraction, e.g. `8` for 1/8ths or `32` for 1/32nds.\",\r\n \"example\": \"32\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DB\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for a specified period using the arithmetic declining balance method.\",\r\n \"a\": \"Depreciation via declining balance method.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"50\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The single period within `life` for which to calculate depreciation.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"month\",\r\n \"detail\": \"The number of months in the first year of depreciation.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DDB\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for a specified period using the double-declining balance method.\",\r\n \"a\": \"Depreciation via double-declining balance method.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"50\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The single period within `life` for which to calculate depreciation.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor\",\r\n \"detail\": \"The factor by which depreciation decreases.\",\r\n \"example\": \"2.25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RATE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the interest rate of an annuity investment based on constant-amount periodic payments and the assumption of a constant interest rate.\",\r\n \"a\": \"Interest rate of an annuity investment.\",\r\n \"m\": [3, 6],\r\n \"p\": [{\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_per_period\",\r\n \"detail\": \"The amount per period to be paid.\",\r\n \"example\": \"-100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"400\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"rate_guess\",\r\n \"detail\": \"An estimate for what the interest rate will be.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CUMPRINC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the cumulative principal paid over a range of payment periods for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Cumulative principal paid over a set of periods.\",\r\n \"m\": [6, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"first_period\",\r\n \"detail\": \"The number of the payment period to begin the cumulative calculation.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"last_period\",\r\n \"detail\": \"The number of the payment period to end the cumulative calculation.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPNUM\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of coupons, or interest payments, between the settlement date and the maturity date of the investment.\",\r\n \"a\": \"Number of coupons between settlement and maturity.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"02\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SYD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for a specified period using the sum of years digits method.\",\r\n \"a\": \"Depreciation via sum of years digits method.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"50\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The single period within `life` for which to calculate depreciation.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TBILLEQ\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the equivalent annualized rate of return of a US Treasury Bill based on discount rate.\",\r\n \"a\": \"Equivalent rate of return for a Treasury bill.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the bill at time of purchase.\",\r\n \"example\": \"2)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TBILLYIELD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the yield of a US Treasury Bill based on price.\",\r\n \"a\": \"The yield of a us treasury bill based on price.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"95\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TBILLPRICE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a US Treasury Bill based on discount rate.\",\r\n \"a\": \"Price of US treasury bill.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the bill at time of purchase.\",\r\n \"example\": \"0.09\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the present value of an annuity investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Present value of an annuity investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_amount\",\r\n \"detail\": \"The amount per period to be paid.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"D2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ACCRINT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the accrued interest of a security that has periodic payments.\",\r\n \"a\": \"Accrued interest of security with periodic payments.\",\r\n \"m\": [6, 8],\r\n \"p\": [{\r\n \"name\": \"issue\",\r\n \"detail\": \"The date the security was initially issued.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"first_payment\",\r\n \"detail\": \"The first date interest will be paid.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"10000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"calc_method\",\r\n \"detail\": \"[Optional-defaults to TRUE()] - A logical value that specifies the method used to calculate the total accrued interest when the settlement date is later than the first interest accrual date. \\n\\nIf the value is TRUE, the total accrued interest from the issue date to the settlement date is returned. \\n\\nIf the value is FALSE, return the accrued interest from the first interest accrual date to the settlement date.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ACCRINTM\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the accrued interest of a security that pays interest at maturity.\",\r\n \"a\": \"Accrued interest of security paying at maturity.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"issue\",\r\n \"detail\": \"The date the security was initially issued.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity date of the security.\",\r\n \"example\": \"DATE(1969\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"1000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPDAYBS\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of days from the first coupon, or interest payment, until settlement.\",\r\n \"a\": \"Number of days from first coupon to settlement.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPDAYS\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of days in the coupon, or interest payment, period that contains the specified settlement date.\",\r\n \"a\": \"Days in coupon period containing settlement date.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPDAYSNC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of days from the settlement date until the next coupon, or interest payment.\",\r\n \"a\": \"Days from settlement until next coupon.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPNCD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates next coupon, or interest payment, date after the settlement date.\",\r\n \"a\": \"Next coupon date after the settlement date.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"01)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"DATE(2019\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COUPPCD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates last coupon, or interest payment, date before the settlement date.\",\r\n \"a\": \"Last coupon date before settlement date.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"01)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"DATE(2019\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the future value of an annuity investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Future value of an annuity investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_amount\",\r\n \"detail\": \"The amount per period to be paid.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"400\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FVSCHEDULE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the future value of some principal based on a specified series of potentially varying interest rates.\",\r\n \"a\": \"Future value of principal from series of rates.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"principal\",\r\n \"detail\": \"The amount of initial capital or value to compound against.\",\r\n \"example\": \"10000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"rate_schedule\",\r\n \"detail\": \"A series of interest rates to compound against the `principal`.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"YIELD\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual yield of a security paying periodic interest, such as a US Treasury Bond, based on price.\",\r\n \"a\": \"Annual yield of a security paying periodic interest.\",\r\n \"m\": [6, 7],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.057\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"95\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"YIELDDISC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual yield of a discount (non-interest-bearing) security, based on price.\",\r\n \"a\": \"Annual yield of a discount security.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"95\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NOMINAL\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the annual nominal interest rate given the effective rate and number of compounding periods per year.\",\r\n \"a\": \"Annual nominal interest rate.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"effective_rate\",\r\n \"detail\": \"The effective interest rate per year.\",\r\n \"example\": \"0.85\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"periods_per_year\",\r\n \"detail\": \"The number of compounding periods per year.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"XIRR\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the internal rate of return of an investment based on a specified series of potentially irregularly spaced cash flows.\",\r\n \"a\": \"Internal rate of return given non-periodic cashflows.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"An array or range containing the income or payments associated with the investment.\",\r\n \"example\": \"B2:B25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"cashflow_dates\",\r\n \"detail\": \"An array or range with dates corresponding to the cash flows in `cashflow_amounts`.\",\r\n \"example\": \"C2:C25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"rate_guess\",\r\n \"detail\": \"An estimate for what the internal rate of return will be.\",\r\n \"example\": \"250\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MIRR\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the modified internal rate of return on an investment based on a series of periodic cash flows and the difference between the interest rate paid on financing versus the return received on reinvested income.\",\r\n \"a\": \"Modified internal rate of return.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"An array or range containing the income or payments associated with the investment.\",\r\n \"example\": \"A2:A25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"financing_rate\",\r\n \"detail\": \"The interest rate paid on funds invested.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"reinvestment_return_rate\",\r\n \"detail\": \"The return (as a percentage) earned on reinvestment of income received from the investment.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"IRR\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the internal rate of return on an investment based on a series of periodic cash flows.\",\r\n \"a\": \"Internal rate of return given periodic cashflows.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"An array or range containing the income or payments associated with the investment.\",\r\n \"example\": \"A2:A25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"rate_guess\",\r\n \"detail\": \"An estimate for what the internal rate of return will be.\",\r\n \"example\": \"200\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NPV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the net present value of an investment based on a series of periodic cash flows and a discount rate.\",\r\n \"a\": \"The net present value of an investment based on a series of periodic cash flows and a discount rate.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the investment over one period.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cashflow1\",\r\n \"detail\": \"The first future cash flow.\",\r\n \"example\": \"200\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"cashflow2\",\r\n \"detail\": \"Additional future cash flows.\",\r\n \"example\": \"250\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"XNPV\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the net present value of an investment based on a specified series of potentially irregularly spaced cash flows and a discount rate.\",\r\n \"a\": \"Net present value given non-periodic cashflows.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the investment over one period.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"cashflow_amounts\",\r\n \"detail\": \"A range of cells containing the income or payments associated with the investment.\",\r\n \"example\": \"B2:B25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"cashflow_dates\",\r\n \"detail\": \"A range of cells with dates corresponding to the cash flows in `cashflow_amounts`.\",\r\n \"example\": \"C2:C25\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"CUMIPMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the cumulative interest over a range of payment periods for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Cumulative interest paid over a set of periods.\",\r\n \"m\": [6, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"first_period\",\r\n \"detail\": \"The number of the payment period to begin the cumulative calculation.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"last_period\",\r\n \"detail\": \"The number of the payment period to end the cumulative calculation.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the periodic payment for an annuity investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Periodic payment for an annuity investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.08\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \" 100000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"D2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"IPMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the payment on interest for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Payment on interest for an investment.\",\r\n \"m\": [4, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The amortization period, in terms of number of periods.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"80000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"E2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PPMT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the payment on the principal of an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Payment on the principal of an investment.\",\r\n \"m\": [4, 6],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"period\",\r\n \"detail\": \"The amortization period, in terms of number of periods.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_periods\",\r\n \"detail\": \"The number of payments to be made.\",\r\n \"example\": \"3*12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"100000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"INTRATE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the effective interest rate generated when an investment is purchased at one price and sold at another with no interest or dividends generated by the investment itself.\",\r\n \"a\": \"Calculates effective interest rate.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"buy_date\",\r\n \"detail\": \"The date of purchase of the investment.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"sell_date\",\r\n \"detail\": \"The date of sale of the investment.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"buy_price\",\r\n \"detail\": \"The price at which the investment was purchased.\",\r\n \"example\": \"100000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"sell_price\",\r\n \"detail\": \"The price at which the investment was sold.\",\r\n \"example\": \"101200\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PRICE\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a security paying periodic interest, such as a US Treasury Bond, based on expected yield.\",\r\n \"a\": \"Price of a security paying periodic interest.\",\r\n \"m\": [6, 7],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.057\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.065\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PRICEDISC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a discount (non-interest-bearing) security, based on expected yield.\",\r\n \"a\": \"Price of a discount security.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the security at time of purchase.\",\r\n \"example\": \"0.0525\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"PRICEMAT\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the price of a security paying interest at maturity, based on expected yield.\",\r\n \"a\": \"Price of security paying interest at maturity.\",\r\n \"m\": [5, 6],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"issue\",\r\n \"detail\": \"The date the security was initially issued.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.061\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.061\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RECEIVED\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the amount received at maturity for an investment in fixed-income securities purchased on a given date.\",\r\n \"a\": \"Amount received at maturity for a security.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"investment\",\r\n \"detail\": \"The amount invested (irrespective of face value of each security).\",\r\n \"example\": \"10000000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"discount\",\r\n \"detail\": \"The discount rate of the security invested in.\",\r\n \"example\": \"0.0575\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DISC\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the discount rate of a security based on price.\",\r\n \"a\": \"The discount rate of a security based on price.\",\r\n \"m\": [4, 5],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"price\",\r\n \"detail\": \"The price at which the security is bought per 100 face value.\",\r\n \"example\": \"97.975\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"redemption\",\r\n \"detail\": \"The redemption amount per 100 face value, or par.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"12\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"NPER\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of payment periods for an investment based on constant-amount periodic payments and a constant interest rate.\",\r\n \"a\": \"Number of payment periods for an investment.\",\r\n \"m\": [3, 5],\r\n \"p\": [{\r\n \"name\": \"rate\",\r\n \"detail\": \"The interest rate.\",\r\n \"example\": \"0.12\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"payment_amount\",\r\n \"detail\": \"The amount of each payment made.\",\r\n \"example\": \"500\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"present_value\",\r\n \"detail\": \"The current value of the annuity.\",\r\n \"example\": \"40000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"future_value\",\r\n \"detail\": \"The future value remaining after the final payment has been made.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"end_or_beginning\",\r\n \"detail\": \"Whether payments are due at the end (`0`) or beginning (`1`) of each period.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SLN\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the depreciation of an asset for one period using the straight-line method.\",\r\n \"a\": \"Depreciation of asset using the straight-line method.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"cost\",\r\n \"detail\": \"The initial cost of the asset.\",\r\n \"example\": \"300000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"salvage\",\r\n \"detail\": \"The value of the asset at the end of depreciation.\",\r\n \"example\": \"75000\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"life\",\r\n \"detail\": \"The number of periods over which the asset is depreciated.\",\r\n \"example\": \"10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DURATION\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the number of compounding periods required for an investment of a specified present value appreciating at a given rate to reach a target value.\",\r\n \"a\": \"Number of periods for an investment to reach a value.\",\r\n \"m\": [5, 6],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.08\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.09\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MDURATION\",\r\n \"t\": 8,\r\n \"d\": \"Calculates the modified Macaulay duration of a security paying periodic interest, such as a US Treasury Bond, based on expected yield.\",\r\n \"a\": \"Modified Macaulay duration.\",\r\n \"m\": [5, 6],\r\n \"p\": [{\r\n \"name\": \"settlement\",\r\n \"detail\": \"The settlement date of the security, the date after issuance when the security is delivered to the buyer.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"maturity\",\r\n \"detail\": \"The maturity or end date of the security, when it can be redeemed at face, or par value.\",\r\n \"example\": \"DATE(2010\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"rate\",\r\n \"detail\": \"The annualized rate of interest.\",\r\n \"example\": \"0.08\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"yield\",\r\n \"detail\": \"The expected annual yield of the security.\",\r\n \"example\": \"0.09\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"frequency\",\r\n \"detail\": \"The number of interest or coupon payments per year (1, 2, or 4).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"day_count_convention\",\r\n \"detail\": \"An indicator of what day count method to use.\",\r\n \"example\": \"0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"BIN2DEC\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed binary number to decimal format.\",\r\n \"a\": \"Converts a signed binary number to decimal format.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"signed_binary_number\",\r\n \"detail\": \"The signed 10-bit binary value to be converted to decimal, provided as a string.\",\r\n \"example\": \"101\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BIN2HEX\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed binary number to signed hexadecimal format.\",\r\n \"a\": \"Converts a binary number to hexadecimal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_binary_number\",\r\n \"detail\": \"The signed 10-bit binary value to be converted to signed hexademical, provided as a string.\",\r\n \"example\": \"101\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"BIN2OCT\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed binary number to signed octal format.\",\r\n \"a\": \"Converts a binary number to octal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_binary_number\",\r\n \"detail\": \"The signed 10-bit binary value to be converted to signed octal, provided as a string.\",\r\n \"example\": \"101\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEC2BIN\",\r\n \"t\": 9,\r\n \"d\": \"Converts a decimal number to signed binary format.\",\r\n \"a\": \"Converts a decimal number to signed binary format.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_number\",\r\n \"detail\": \"The decimal value to be converted to signed binary, provided as a string.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEC2HEX\",\r\n \"t\": 9,\r\n \"d\": \"Converts a decimal number to signed hexadecimal format.\",\r\n \"a\": \"Converts a decimal number to hexadecimal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_number\",\r\n \"detail\": \"The decimal value to be converted to signed hexadecimal, provided as a string.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DEC2OCT\",\r\n \"t\": 9,\r\n \"d\": \"Converts a decimal number to signed octal format.\",\r\n \"a\": \"Converts a decimal number to signed octal format.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"decimal_number\",\r\n \"detail\": \"The decimal value to be converted to signed octal, provided as a string.\",\r\n \"example\": \"100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HEX2BIN\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed hexadecimal number to signed binary format.\",\r\n \"a\": \"Converts a hexadecimal number to binary.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_hexadecimal_number\",\r\n \"detail\": \"The signed 40-bit hexadecimal value to be converted to signed binary, provided as a string.\",\r\n \"example\": \"\\\"f3\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"HEX2DEC\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed hexadecimal number to decimal format.\",\r\n \"a\": \"Converts a hexadecimal number to decimal.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"signed_hexadecimal_number\",\r\n \"detail\": \"The signed 40-bit hexadecimal value to be converted to decimal, provided as a string.\",\r\n \"example\": \"\\\"f3\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"HEX2OCT\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed hexadecimal number to signed octal format.\",\r\n \"a\": \"Converts a hexadecimal number to octal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_hexadecimal_number\",\r\n \"detail\": \"The signed 40-bit hexadecimal value to be converted to signed octal, provided as a string.\",\r\n \"example\": \"\\\"f3\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"OCT2BIN\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed octal number to signed binary format.\",\r\n \"a\": \"Converts an octal number to binary.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_octal_number\",\r\n \"detail\": \"The signed 30-bit octal value to be converted to signed binary, provided as a string.\",\r\n \"example\": \"37\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"OCT2DEC\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed octal number to decimal format.\",\r\n \"a\": \"Converts a signed octal number to decimal format.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"signed_octal_number\",\r\n \"detail\": \"The signed 30-bit octal value to be converted to decimal, provided as a string.\",\r\n \"example\": \"37\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"OCT2HEX\",\r\n \"t\": 9,\r\n \"d\": \"Converts a signed octal number to signed hexadecimal format.\",\r\n \"a\": \"Converts an octal number to hexadecimal.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"signed_octal_number\",\r\n \"detail\": \"The signed 30-bit octal value to be converted to signed hexadecimal, provided as a string.\",\r\n \"example\": \"37\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"significant_digits\",\r\n \"detail\": \"The number of significant digits to ensure in the result.\",\r\n \"example\": \"8\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"COMPLEX\",\r\n \"t\": 9,\r\n \"d\": \"Creates a complex number given real and imaginary coefficients.\",\r\n \"a\": \"Creates a complex number.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"real_part\",\r\n \"detail\": \"The real coefficient.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"imaginary_part\",\r\n \"detail\": \"The imaginary coefficient.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"suffix\",\r\n \"detail\": \"The suffix for the imaginary coefficient, can only be 'i' or 'j'. If omitted, 'i' will be used.\",\r\n \"example\": \"\\\"j\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangestring\"\r\n }]\r\n }, {\r\n \"n\": \"IMREAL\",\r\n \"t\": 9,\r\n \"d\": \"Returns the real coefficient of a complex number.\",\r\n \"a\": \"The real coefficient of a complex number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"complex_number\",\r\n \"detail\": \"The complex number, in the a+bi or a+bj format.\",\r\n \"example\": \"\\\"4+5i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMAGINARY\",\r\n \"t\": 9,\r\n \"d\": \"Returns the imaginary coefficient of a complex number.\",\r\n \"a\": \"The imaginary coefficient of a complex number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"complex_number\",\r\n \"detail\": \"The complex number, in the a+bi or a+bj format.\",\r\n \"example\": \"\\\"4+5i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMCONJUGATE\",\r\n \"t\": 9,\r\n \"d\": \"Returns the complex conjugate of a number.\",\r\n \"a\": \"The complex conjugate of a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The complex number to calculate the conjugate for.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMABS\",\r\n \"t\": 9,\r\n \"d\": \"Returns absolute value (or modulus) of a complex number.\",\r\n \"a\": \"The absolute value of a complex number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The complex number to calculate the absolute value of.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DELTA\",\r\n \"t\": 9,\r\n \"d\": \"Compare two numeric values, returning 1 if they're equal.\",\r\n \"a\": \"Compare two numeric values.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"number1\",\r\n \"detail\": \"The first number to compare.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number2\",\r\n \"detail\": \"The second number to compare.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"IMSUM\",\r\n \"t\": 9,\r\n \"d\": \"Returns the sum of a series of complex numbers.\",\r\n \"a\": \"Sum of a series of complex numbers.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first complex number or range to add together.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"Additional complex numbers or ranges to add to `value1`.\",\r\n \"example\": \"\\\"5-3i\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMSUB\",\r\n \"t\": 9,\r\n \"d\": \"Returns the difference between two complex numbers.\",\r\n \"a\": \"The difference between two complex numbers.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"first_number\",\r\n \"detail\": \"The complex number to subtract second_number from.\",\r\n \"example\": \"\\\"6+5i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"second_number\",\r\n \"detail\": \"The complex number to subtract from first_number.\",\r\n \"example\": \"\\\"2+3i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMPRODUCT\",\r\n \"t\": 9,\r\n \"d\": \"Returns the result of multiplying a series of complex numbers together.\",\r\n \"a\": \"Result of multiplying a series of complex numbers together.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"factor1\",\r\n \"detail\": \"The first number or range to calculate for the product.\",\r\n \"example\": \"\\\"3+4i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"factor2\",\r\n \"detail\": \"Additional complex numbers or ranges to calculate for the product.\",\r\n \"example\": \"\\\"5-3i\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IMDIV\",\r\n \"t\": 9,\r\n \"d\": \"Returns one complex number divided by another.\",\r\n \"a\": \"One complex number divided by another.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The complex number to be divided.\",\r\n \"example\": \"\\\"11+16i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The complex number to divide by.\",\r\n \"example\": \"\\\"3+2i\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NOT\",\r\n \"t\": 10,\r\n \"d\": \"Returns the opposite of a logical value - `NOT(TRUE)` returns `FALSE`; `NOT(FALSE)` returns `TRUE`.\",\r\n \"a\": \"Returns opposite of provided logical value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"logical_expression\",\r\n \"detail\": \"An expression or reference to a cell holding an expression that represents some logical value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TRUE\",\r\n \"t\": 10,\r\n \"d\": \"Returns the logical value `TRUE`.\",\r\n \"a\": \"Logical value `true`.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"FALSE\",\r\n \"t\": 10,\r\n \"d\": \"Returns the logical value `FALSE`.\",\r\n \"a\": \"Logical value `false`.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"AND\",\r\n \"t\": 10,\r\n \"d\": \"Returns true if all of the provided arguments are logically true, and false if any of the provided arguments are logically false.\",\r\n \"a\": \"Logical `and` operator.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"logical_expression1\",\r\n \"detail\": \"An expression or reference to a cell containing an expression that represents some logical value, i.e. `TRUE` or `FALSE`, or an expression that can be coerced to a logical value.\",\r\n \"example\": \"A2 = \\\"foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"logical_expression2\",\r\n \"detail\": \"More expressions that represent logical values.\",\r\n \"example\": \"A3 = \\\"bar\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IFERROR\",\r\n \"t\": 10,\r\n \"d\": \"Returns the first argument if it is not an error value, otherwise returns the second argument if present, or a blank if the second argument is absent.\",\r\n \"a\": \"Value if it is not an error, otherwise 2nd argument.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to return if `value` itself is not an error.\",\r\n \"example\": \"A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_if_error\",\r\n \"detail\": \"The value the function returns if `value` is an error.\",\r\n \"example\": \"\\\"Error in cell A1\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"IF\",\r\n \"t\": 10,\r\n \"d\": \"Returns one value if a logical expression is `TRUE` and another if it is `FALSE`.\",\r\n \"a\": \"Returns value depending on logical expression.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"logical_expression\",\r\n \"detail\": \"An expression or reference to a cell containing an expression that represents some logical value, i.e. `TRUE` or `FALSE`.\",\r\n \"example\": \"A2 = \\\"foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_if_true\",\r\n \"detail\": \"The value the function returns if `logical_expression` is `TRUE`.\",\r\n \"example\": \"\\\"A2 is foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_if_false\",\r\n \"detail\": \"The value the function returns if `logical_expression` is `FALSE`.\",\r\n \"example\": \"\\\"A2 was false\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"OR\",\r\n \"t\": 10,\r\n \"d\": \"Returns true if any of the provided arguments are logically true, and false if all of the provided arguments are logically false.\",\r\n \"a\": \"Logical `or` operator.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"logical_expression1\",\r\n \"detail\": \"An expression or reference to a cell containing an expression that represents some logical value, i.e. `TRUE` or `FALSE`, or an expression that can be coerced to a logical value.\",\r\n \"example\": \"A2 = \\\"foo\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"logical_expression2\",\r\n \"detail\": \"More expressions that evaluate to logical values.\",\r\n \"example\": \" A3 = \\\"bar\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"NE\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if two specified values are not equal and `FALSE` otherwise. Equivalent to the `!=` operator.\",\r\n \"a\": \"Not equal.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The value to test against `value1` for inequality.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EQ\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if two specified values are equal and `FALSE` otherwise. Equivalent to the `==` operator.\",\r\n \"a\": \"Equal.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The value to test against `value1` for equality.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"GT\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is strictly greater than the second, and `FALSE` otherwise. Equivalent to the `>` operator.\",\r\n \"a\": \"Strictly greater than.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being greater than `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"GTE\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is greater than or equal to the second, and `FALSE` otherwise. Equivalent to the `>=` operator.\",\r\n \"a\": \"Greater than or equal to.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being greater than or equal to `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LT\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is strictly less than the second, and `FALSE` otherwise. Equivalent to the `<` operator.\",\r\n \"a\": \"Less than.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being less than `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LTE\",\r\n \"t\": 11,\r\n \"d\": \"Returns `TRUE` if the first argument is less than or equal to the second, and `FALSE` otherwise. Equivalent to the `<=` operator.\",\r\n \"a\": \"Less than or equal to.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to test as being less than or equal to `value2`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second value.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ADD\",\r\n \"t\": 11,\r\n \"d\": \"Returns the sum of two numbers. Equivalent to the `+` operator.\",\r\n \"a\": \"Sum of two numbers\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The first addend.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The second addend.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MINUS\",\r\n \"t\": 11,\r\n \"d\": \"Returns the difference of two numbers. Equivalent to the `-` operator.\",\r\n \"a\": \"Difference of two numbers\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The minuend, or number to be subtracted from.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The subtrahend, or number to subtract from `value1`.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MULTIPLY\",\r\n \"t\": 11,\r\n \"d\": \"Returns the product of two numbers. Equivalent to the `*` operator.\",\r\n \"a\": \"Product of two numbers\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"factor1\",\r\n \"detail\": \"The first multiplicand.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"factor2\",\r\n \"detail\": \"The second multiplicand.\",\r\n \"example\": \"B2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DIVIDE\",\r\n \"t\": 11,\r\n \"d\": \"Returns one number divided by another. Equivalent to the `/` operator.\",\r\n \"a\": \"One number divided by another\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"dividend\",\r\n \"detail\": \"The number to be divided.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"divisor\",\r\n \"detail\": \"The number to divide by.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CONCAT\",\r\n \"t\": 11,\r\n \"d\": \"Returns the concatenation of two values. Equivalent to the `&` operator.\",\r\n \"a\": \"Concatenation of two values\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"value1\",\r\n \"detail\": \"The value to which `value2` will be appended.\",\r\n \"example\": \"\\\"de\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value2\",\r\n \"detail\": \"The value to append to `value1`.\",\r\n \"example\": \"\\\"mystify\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"UNARY_PERCENT\",\r\n \"t\": 11,\r\n \"d\": \"Returns a value interpreted as a percentage; that is, `UNARY_PERCENT(100)` equals `1`.\",\r\n \"a\": \"Value interpreted as a percentage.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"percentage\",\r\n \"detail\": \"The value to interpret as a percentage.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CONCATENATE\",\r\n \"t\": 12,\r\n \"d\": \"Appends strings to one another.\",\r\n \"a\": \"Appends strings to one another.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"string1\",\r\n \"detail\": \"The initial string.\",\r\n \"example\": \"\\\"Super\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"string2\",\r\n \"detail\": \"More strings to append in sequence.\",\r\n \"example\": \"\\\"calla\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CODE\",\r\n \"t\": 12,\r\n \"d\": \"Returns the numeric Unicode map value of the first character in the string provided.\",\r\n \"a\": \"Numeric unicode map value of character.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string whose first character's Unicode map value will be returned.\",\r\n \"example\": \"\\\"a\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CHAR\",\r\n \"t\": 12,\r\n \"d\": \"Convert a number into a character according to the current Unicode table.\",\r\n \"a\": \"Gets character associated with number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"table_number\",\r\n \"detail\": \"The number of the character to look up from the current Unicode table in decimal format.\",\r\n \"example\": \"97\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ARABIC\",\r\n \"t\": 12,\r\n \"d\": \"Computes the value of a Roman numeral.\",\r\n \"a\": \"Computes the value of a roman numeral.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"roman_numeral\",\r\n \"detail\": \"The Roman numeral to format, whose value must be between 1 and 3999, inclusive.\",\r\n \"example\": \"\\\"XIV\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ROMAN\",\r\n \"t\": 12,\r\n \"d\": \"Formats a number in Roman numerals.\",\r\n \"a\": \"Formats a number in Roman numerals.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The number to format, between 1 and 3999, inclusive.\",\r\n \"example\": \"499\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"REGEXEXTRACT\",\r\n \"t\": 12,\r\n \"d\": \"Extracts matching substrings according to a regular expression.\",\r\n \"a\": \"Extracts matching substrings with regular expression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The input text.\",\r\n \"example\": \"\\\"Needle in a haystack\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"regular_expression\",\r\n \"detail\": \"The first part of `text` that matches this expression will be returned.\",\r\n \"example\": \"\\\".e{2}dle\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REGEXMATCH\",\r\n \"t\": 12,\r\n \"d\": \"Whether a piece of text matches a regular expression.\",\r\n \"a\": \"Whether a piece of text matches regular expression.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text to be tested against the regular expression.\",\r\n \"example\": \"\\\"Spreadsheets\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"regular_expression\",\r\n \"detail\": \"The regular expression to test the text against.\",\r\n \"example\": \"\\\"S.r\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REGEXREPLACE\",\r\n \"t\": 12,\r\n \"d\": \"Replaces part of a text string with a different text string using regular expressions.\",\r\n \"a\": \"Replaces text with regular expressions.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text, a part of which will be replaced.\",\r\n \"example\": \"\\\"Spreadsheets\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"regular_expression\",\r\n \"detail\": \"The regular expression. All matching instances in `text` will be replaced.\",\r\n \"example\": \"\\\"S.*d\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"replacement\",\r\n \"detail\": \"The text which will be inserted into the original text.\",\r\n \"example\": \"\\\"Bed\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"T\",\r\n \"t\": 12,\r\n \"d\": \"Returns string arguments as text, or the empty string if the value is not text.\",\r\n \"a\": \"String arguments as text.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument to be converted to text.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FIXED\",\r\n \"t\": 12,\r\n \"d\": \"Formats a number with a fixed number of decimal places.\",\r\n \"a\": \"Formats number with fixed number of decimal places.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The number to format.\",\r\n \"example\": \"3.141592653\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"number_of_places\",\r\n \"detail\": \"The number of decimal places to display in the result.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"suppress_separator\",\r\n \"detail\": \"Whether or not to suppress the thousands separator used in some locales (e.g. `1,000` becomes `1000`). Separators will be present if this value is 0 or omitted, and absent otherwise.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FIND\",\r\n \"t\": 12,\r\n \"d\": \"Returns the position at which a string is first found within text where the capitalization of letters matters. Returns `#VALUE!` if the string is not found.\",\r\n \"a\": \"First position of string found in text, case-sensitive.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to look for within `text_to_search`.\",\r\n \"example\": \"\\\"n\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text to search for the first occurrence of `search_for`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The character within `text_to_search` at which to start the search.\",\r\n \"example\": \"14\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"FINDB\",\r\n \"t\": 12,\r\n \"d\": \"Returns the position at which a string is first found within text counting each double-character as 2.\",\r\n \"a\": \"Position at which a string is first found within text (binary).\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to look for within `text_to_search`.\",\r\n \"example\": \"\\\"new\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text to search for the first occurrence of `search_for`.\",\r\n \"example\": \"\\\"new year\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The character within `text_to_search` at which to start the search.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"JOIN\",\r\n \"t\": 12,\r\n \"d\": \"Concatenates the elements of one or more one-dimensional arrays using a specified delimiter.\",\r\n \"a\": \"Concatenates elements of arrays with delimiter.\",\r\n \"m\": [2, 255],\r\n \"p\": [{\r\n \"name\": \"delimiter\",\r\n \"detail\": \"The character or string to place between each concatenated value.\",\r\n \"example\": \"\\\" and-a \\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_or_array1\",\r\n \"detail\": \"The value or values to be appended using `delimiter`.\",\r\n \"example\": \"{1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"value_or_array2\",\r\n \"detail\": \"More values to be appended using `delimiter`.\",\r\n \"example\": \"2\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LEFT\",\r\n \"t\": 12,\r\n \"d\": \"Returns a substring from the beginning of a specified string.\",\r\n \"a\": \"Substring from beginning of specified string.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string from which the left portion will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"number_of_characters\",\r\n \"detail\": \"The number of characters to return from the left side of `string`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"RIGHT\",\r\n \"t\": 12,\r\n \"d\": \"Returns a substring from the end of a specified string.\",\r\n \"a\": \"A substring from the end of a specified string.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string from which the right portion will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"number_of_characters\",\r\n \"detail\": \"The number of characters to return from the right side of `string`.\",\r\n \"example\": \"2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MID\",\r\n \"t\": 12,\r\n \"d\": \"Returns a segment of a string.\",\r\n \"a\": \"A segment of a string.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"string\",\r\n \"detail\": \"The string to extract a segment from.\",\r\n \"example\": \"\\\"get this\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The index from the left of `string` from which to begin extracting. The first character in `string` has the index 1.\",\r\n \"example\": \"5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"extract_length\",\r\n \"detail\": \"The length of the segment to extract.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"LEN\",\r\n \"t\": 12,\r\n \"d\": \"Returns the length of a string.\",\r\n \"a\": \"Length of a string.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string whose length will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LENB\",\r\n \"t\": 12,\r\n \"d\": \"Returns the length of a string in bytes.\",\r\n \"a\": \"Length of a string in bytes.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string whose length will be returned.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LOWER\",\r\n \"t\": 12,\r\n \"d\": \"Converts a specified string to lowercase.\",\r\n \"a\": \"Converts a specified string to lowercase.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string to convert to lowercase.\",\r\n \"example\": \"\\\"LOREM IPSUM\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"UPPER\",\r\n \"t\": 12,\r\n \"d\": \"Converts a specified string to uppercase.\",\r\n \"a\": \"Converts a specified string to uppercase.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string to convert to uppercase.\",\r\n \"example\": \"\\\"lorem ipsum\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"EXACT\",\r\n \"t\": 12,\r\n \"d\": \"Tests whether two strings are identical.\",\r\n \"a\": \"Tests whether two strings are identical.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"string1\",\r\n \"detail\": \"The first string to compare\",\r\n \"example\": \"A1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"string2\",\r\n \"detail\": \"The second string to compare\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REPLACE\",\r\n \"t\": 12,\r\n \"d\": \"Replaces part of a text string with a different text string.\",\r\n \"a\": \"Replaces part of a text string with different text.\",\r\n \"m\": [4, 4],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text, a part of which will be replaced.\",\r\n \"example\": \"\\\"Spreadsheets\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"position\",\r\n \"detail\": \"The position where the replacement will begin (starting from 1).\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"length\",\r\n \"detail\": \"The number of characters in the text to be replaced.\",\r\n \"example\": \"6\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"new_text\",\r\n \"detail\": \"The text which will be inserted into the original text.\",\r\n \"example\": \"\\\"Bed\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"REPT\",\r\n \"t\": 12,\r\n \"d\": \"Returns specified text repeated a number of times.\",\r\n \"a\": \"Specified text repeated a number of times.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"text_to_repeat\",\r\n \"detail\": \"The character or string to repeat.\",\r\n \"example\": \"\\\"ha\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"number_of_repetitions\",\r\n \"detail\": \"The number of times `text_to_repeat` should appear in the value returned.\",\r\n \"example\": \"4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SEARCH\",\r\n \"t\": 12,\r\n \"d\": \"Returns the position at which a string is first found within text and ignores capitalization of letters. Returns `#VALUE!` if the string is not found.\",\r\n \"a\": \"First position of string found in text, ignoring case.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to look for within `text_to_search`.\",\r\n \"example\": \"\\\"n\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text to search for the first occurrence of `search_for`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"starting_at\",\r\n \"detail\": \"The character within `text_to_search` at which to start the search.\",\r\n \"example\": \"14\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUBSTITUTE\",\r\n \"t\": 12,\r\n \"d\": \"Replaces existing text with new text in a string.\",\r\n \"a\": \"Replaces existing text with new text in a string.\",\r\n \"m\": [3, 4],\r\n \"p\": [{\r\n \"name\": \"text_to_search\",\r\n \"detail\": \"The text within which to search and replace.\",\r\n \"example\": \"\\\"search for it\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"search_for\",\r\n \"detail\": \"The string to search for within `text_to_search`.\",\r\n \"example\": \"\\\"search for\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"replace_with\",\r\n \"detail\": \"The string that will replace `search_for`.\",\r\n \"example\": \"\\\"Google\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"occurrence_number\",\r\n \"detail\": \"The instance of `search_for` within `text_to_search` to replace with `replace_with`. By default, all occurrences of `search_for` are replaced; however, if `occurrence_number` is specified, only the indicated instance of `search_for` is replaced.\",\r\n \"example\": \"3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"CLEAN\",\r\n \"t\": 12,\r\n \"d\": \"Returns the text with the non-printable ASCII characters removed.\",\r\n \"a\": \"Removes non-printable characters from a piece of text.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text whose non-printable characters are to be removed.\",\r\n \"example\": \"\\\"AF\\\"&CHAR(31)\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TEXT\",\r\n \"t\": 12,\r\n \"d\": \"Converts a number into text according to a specified format.\",\r\n \"a\": \"Formats a number into text.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"number\",\r\n \"detail\": \"The number, date, or time to format.\",\r\n \"example\": \"1.23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"format\",\r\n \"detail\": \"The pattern by which to format the number, enclosed in quotation marks.\",\r\n \"example\": \"\\\"$0.00\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TRIM\",\r\n \"t\": 12,\r\n \"d\": \"Removes leading, trailing, and repeated spaces in text.\",\r\n \"a\": \"Removes space characters.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The text or reference to a cell containing text to be trimmed.\",\r\n \"example\": \"\\\" lorem ipsum\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"VALUE\",\r\n \"t\": 12,\r\n \"d\": \"Converts a string in any of the date, time or number formats that Google Sheets understands into a number.\",\r\n \"a\": \"Converts a date/time/number string into a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text\",\r\n \"detail\": \"The string containing the value to be converted.\",\r\n \"example\": \"\\\"123\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PROPER\",\r\n \"t\": 12,\r\n \"d\": \"Capitalizes each word in a specified string.\",\r\n \"a\": \"Capitalizes each word in a specified string.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"text_to_capitalize\",\r\n \"detail\": \"The text which will be returned with the first letter of each word in uppercase and all other letters in lowercase.\",\r\n \"example\": \"\\\"united states\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CONVERT\",\r\n \"t\": 13,\r\n \"d\": \"Converts a numeric value to a different unit of measure.\",\r\n \"a\": \"Unit conversion for numbers.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The numeric value in `start_unit` to convert to `end_unit`.\",\r\n \"example\": \"5.1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"start_unit\",\r\n \"detail\": \"The starting unit, the unit currently assigned to `value`.\",\r\n \"example\": \"\\\"g\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"end_unit\",\r\n \"detail\": \"The unit of measure into which to convert the argument, `value`.\",\r\n \"example\": \"\\\"kg\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SUMX2MY2\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the differences of the squares of values in two arrays.\",\r\n \"a\": \"Sum of the differences of squares.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"array_x\",\r\n \"detail\": \"The array or range of values whose squares will be reduced by the squares of corresponding entries in `array_y` and added together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array_y\",\r\n \"detail\": \"The array or range of values whose squares will be subtracted from the squares of corresponding entries in `array_x` and added together.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMX2PY2\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the sums of the squares of values in two arrays.\",\r\n \"a\": \"Sum of the sums of squares.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"array_x\",\r\n \"detail\": \"The array or range of values whose squares will be added to the squares of corresponding entries in `array_y` and added together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array_y\",\r\n \"detail\": \"The array or range of values whose squares will be added to the squares of corresponding entries in `array_x` and added together.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMXMY2\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the squares of differences of values in two arrays.\",\r\n \"a\": \"Sum of the squares of differences.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"array_x\",\r\n \"detail\": \"The array or range of values that will be reduced by corresponding entries in `array_y`, squared, and added together.\",\r\n \"example\": \"A2:A100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array_y\",\r\n \"detail\": \"The array or range of values that will be subtracted from corresponding entries in `array_x`, the result squared, and all such results added together.\",\r\n \"example\": \"B2:B100\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TRANSPOSE\",\r\n \"t\": 14,\r\n \"d\": \"Transposes the rows and columns of an array or range of cells.\",\r\n \"a\": \"Transposes the rows and columns of an array.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"array_or_range\",\r\n \"detail\": \"The array or range whose rows and columns will be swapped.\",\r\n \"example\": \"{1,2}\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"TREND\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about a linear trend, fits an ideal linear trend using the least squares method and/or predicts further values.\",\r\n \"a\": \"Fits points to linear trend derived via least-squares.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal linear trend.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"new_data_x\",\r\n \"detail\": \"The data points to return the `y` values for on the ideal curve fit.\",\r\n \"example\": \"A11:A13\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"b\",\r\n \"detail\": \"Given a general linear form of `y = m*x+b` for a curve fit, calculates `b` if `TRUE` or forces `b` to be `0` and only calculates the `m` values if `FALSE`, i.e. forces the curve fit to pass through the origin.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FREQUENCY\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the frequency distribution of a one-column array into specified classes.\",\r\n \"a\": \"The frequency distribution of array.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"data\",\r\n \"detail\": \"The array or range containing the values to be counted.\",\r\n \"example\": \"A2:A40\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"classes\",\r\n \"detail\": \"The array or range containing the set of classes.\",\r\n \"example\": \"B2:B5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"GROWTH\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about an exponential growth trend, fits an ideal exponential growth trend and/or predicts further values.\",\r\n \"a\": \"Fits points to exponential growth trend.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal exponential growth curve.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"new_data_x\",\r\n \"detail\": \"The data points to return the `y` values for on the ideal curve fit.\",\r\n \"example\": \"A11:A13\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"b\",\r\n \"detail\": \"Given a general exponential form of `y = b*m^x` for a curve fit, calculates `b` if `TRUE` or forces `b` to be `1` and only calculates the `m` values if `FALSE`.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LINEST\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about a linear trend, calculates various parameters about the ideal linear trend using the least-squares method.\",\r\n \"a\": \"Best-fit linear trend via least-squares.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal linear trend.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"calculate_b\",\r\n \"detail\": \"Given a linear form of `y = m*x+b`, calculates the y-intercept (`b`) if `TRUE`. Otherwise, forces `b` to be `0` and only calculates the `m` values if `FALSE`, i.e. forces the curve fit to pass through the origin.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"verbose\",\r\n \"detail\": \"A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept (default).\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LOGEST\",\r\n \"t\": 14,\r\n \"d\": \"Given partial data about an exponential growth curve, calculates various parameters about the best fit ideal exponential growth curve.\",\r\n \"a\": \"Best-fit exponential growth curve.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"known_data_y\",\r\n \"detail\": \"The array or range containing dependent (y) values that are already known, used to curve fit an ideal exponential growth curve.\",\r\n \"example\": \"B2:B10\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"known_data_x\",\r\n \"detail\": \"The values of the independent variable(s) corresponding with `known_data_y`.\",\r\n \"example\": \"A2:A10\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"b\",\r\n \"detail\": \"Given a general exponential form of `y = b*m^x` for a curve fit, calculates `b` if `TRUE` or forces `b` to be `1` and only calculates the `m` values if `FALSE`.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"verbose\",\r\n \"detail\": \"A flag specifying whether to return additional regression statistics or only the calculated coefficient and exponents.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"MDETERM\",\r\n \"t\": 14,\r\n \"d\": \"Returns the matrix determinant of a square matrix specified as an array or range.\",\r\n \"a\": \"Matrix determinant of a square matrix.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"square_matrix\",\r\n \"detail\": \"An array or range with an equal number of rows and columns representing a matrix whose determinant will be calculated.\",\r\n \"example\": \"A1:D4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MINVERSE\",\r\n \"t\": 14,\r\n \"d\": \"Returns the multiplicative inverse of a square matrix specified as an array or range.\",\r\n \"a\": \"Multiplicative inverse of square matrix.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"square_matrix\",\r\n \"detail\": \"An array or range with an equal number of rows and columns representing a matrix whose multiplicative inverse will be calculated.\",\r\n \"example\": \"A1:D4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"MMULT\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the matrix product of two matrices specified as arrays or ranges.\",\r\n \"a\": \"The matrix product of two matrices.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"matrix1\",\r\n \"detail\": \"The first matrix in the matrix multiplication operation, represented as an array or range.\",\r\n \"example\": \"A1:B3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"matrix2\",\r\n \"detail\": \"The second matrix in the matrix multiplication operation, represented as an array or range.\",\r\n \"example\": \"C1:F2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SUMPRODUCT\",\r\n \"t\": 14,\r\n \"d\": \"Calculates the sum of the products of corresponding entries in two equal-sized arrays or ranges.\",\r\n \"a\": \"Sum of products of elements in two arrays.\",\r\n \"m\": [1, 255],\r\n \"p\": [{\r\n \"name\": \"array1\",\r\n \"detail\": \"The first array or range whose entries will be multiplied with corresponding entries in the second such array or range.\",\r\n \"example\": \"A2:C5\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"array2\",\r\n \"detail\": \"The second array or range whose entries will be multiplied with corresponding entries in the first such array or range.\",\r\n \"example\": \"D2:F5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISFORMULA\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is a formula.\",\r\n \"a\": \"Whether a value is a formula.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"cell\",\r\n \"detail\": \"The cell to be verified as containing a formula.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"CELL\",\r\n \"t\": 15,\r\n \"d\": \"Returns the requested information about the specified cell.\",\r\n \"a\": \"Gets information about a cell.\",\r\n \"m\": [2, 2],\r\n \"p\": [{\r\n \"name\": \"info_type\",\r\n \"detail\": \"The type of information requested (see article for available types)\",\r\n \"example\": \"\\\"type\\\"\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"reference\",\r\n \"detail\": \"The reference to the cell.\",\r\n \"example\": \"C2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"NA\",\r\n \"t\": 15,\r\n \"d\": \"Returns the \\\"value not available\\\" error, `#N/A`.\",\r\n \"a\": \"The `#N/A` error.\",\r\n \"m\": [0, 0],\r\n \"p\": []\r\n }, {\r\n \"n\": \"ERROR_TYPE\",\r\n \"t\": 15,\r\n \"d\": \"Returns a number corresponding to the error value in a different cell.\",\r\n \"a\": \"Error value of cell (as number).\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"reference\",\r\n \"detail\": \"The cell to find the error number for although you can also provide the error value directly.\",\r\n \"example\": \"A3\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISBLANK\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether the referenced cell is empty.\",\r\n \"a\": \"Whether the referenced cell is empty.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"Reference to the cell that will be checked for emptiness.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"ISERR\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is an error other than `#N/A`.\",\r\n \"a\": \"Whether a value is an error other than `#n/a`.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as an error type other than `#N/A`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISERROR\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is an error.\",\r\n \"a\": \"Whether a value is an error.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as an error type.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISLOGICAL\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is `TRUE` or `FALSE`.\",\r\n \"a\": \"Whether a value is `true` or `false`.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as a logical `TRUE` or `FALSE`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISNA\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is the error `#N/A`.\",\r\n \"a\": \"Whether a value is the error `#n/a`.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be compared with the error value `#N/A`.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISNONTEXT\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is non-textual.\",\r\n \"a\": \"Whether a value is non-textual.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be checked.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISNUMBER\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is a number.\",\r\n \"a\": \"Whether a value is a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as a number.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISREF\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is a valid cell reference.\",\r\n \"a\": \"Whether a value is a valid cell reference.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as a cell reference.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"ISTEXT\",\r\n \"t\": 15,\r\n \"d\": \"Checks whether a value is text.\",\r\n \"a\": \"Whether a value is text.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value to be verified as text.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TYPE\",\r\n \"t\": 15,\r\n \"d\": \"Returns a number associated with the type of data passed into the function.\",\r\n \"a\": \"Get the type of a value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The value whose type is to be determined.\",\r\n \"example\": \"C4\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"N\",\r\n \"t\": 15,\r\n \"d\": \"Returns the argument provided as a number. Text is converted to 0 and errors are returned as-is.\",\r\n \"a\": \"Argument provided as a number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument to be converted to a number.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TO_DATE\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided number to a date.\",\r\n \"a\": \"Converts a provided number to a date.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a date.\",\r\n \"example\": \"25405\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TO_PURE_NUMBER\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided date/time, percentage, currency or other formatted numeric value to a pure number without formatting.\",\r\n \"a\": \"Converts any numeric value to a pure number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a pure number.\",\r\n \"example\": \"50%\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TO_TEXT\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided numeric value to a text value.\",\r\n \"a\": \"Converts a provided numeric value to a text value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to text.\",\r\n \"example\": \"24\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TO_DOLLARS\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided number to a dollar value.\",\r\n \"a\": \"Converts a provided number to a dollar value.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a dollar value.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"TO_PERCENT\",\r\n \"t\": 16,\r\n \"d\": \"Converts a provided number to a percentage.\",\r\n \"a\": \"Converts a provided number to a percentage.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"detail\": \"The argument or reference to a cell to be converted to a percentage.\",\r\n \"example\": \"A2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DGET\",\r\n \"t\": 17,\r\n \"d\": \"Returns a single value from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Single value from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DMAX\",\r\n \"t\": 17,\r\n \"d\": \"Returns the maximum value selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Maximum of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DMIN\",\r\n \"t\": 17,\r\n \"d\": \"Returns the minimum value selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Minimum of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DAVERAGE\",\r\n \"t\": 17,\r\n \"d\": \"Returns the average of a set of values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Average of a set of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DCOUNT\",\r\n \"t\": 17,\r\n \"d\": \"Counts numeric values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Counts values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DCOUNTA\",\r\n \"t\": 17,\r\n \"d\": \"Counts values, including text, selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Counts values and text from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DPRODUCT\",\r\n \"t\": 17,\r\n \"d\": \"Returns the product of values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Product of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DSTDEV\",\r\n \"t\": 17,\r\n \"d\": \"Returns the standard deviation of a population sample selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Standard deviation of population sample from table.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DSTDEVP\",\r\n \"t\": 17,\r\n \"d\": \"Returns the standard deviation of an entire population selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Standard deviation of entire population from table.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DSUM\",\r\n \"t\": 17,\r\n \"d\": \"Returns the sum of values selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Sum of values from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DVAR\",\r\n \"t\": 17,\r\n \"d\": \"Returns the variance of a population sample selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Variance of population sample from table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"DVARP\",\r\n \"t\": 17,\r\n \"d\": \"Returns the variance of an entire population selected from a database table-like array or range using a SQL-like query.\",\r\n \"a\": \"Variance of a population from a table-like range.\",\r\n \"m\": [3, 3],\r\n \"p\": [{\r\n \"name\": \"database\",\r\n \"detail\": \"The array or range containing the data to consider, structured in such a way that the first row contains the labels for each column's values.\",\r\n \"example\": \"A2:F20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"field\",\r\n \"detail\": \"Indicates which column in `database` contains the values to be extracted and operated on.\",\r\n \"example\": \"G2\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"criteria\",\r\n \"detail\": \"An array or range containing zero or more criteria to filter the `database` values by before operating.\",\r\n \"example\": \"A22:D23\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }]\r\n }, {\r\n \"n\": \"AGE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the age based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get age based on ID number.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"A1\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Deadline\",\r\n \"example\": \"\\\"2017-10-01\\\"\",\r\n \"detail\": \"The deadline or range of age calculation. The default is the current day.\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedatetime\"\r\n }]\r\n }, {\r\n \"n\": \"SEX_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate gender based on Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get gender based on ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BIRTHDAY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the birthday based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the birthday based on the ID number.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Birthday format\",\r\n \"example\": \"0\",\r\n \"detail\": \"Date type, default:0:[1900/01/01], 1:[1900-01-01], 2:[1900年1月1日]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PROVINCE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the province of birthplace based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the province of birthplace based on the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"CITY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the city of birthplace based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the city of birthplace based on the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"STAR_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the constellation based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the constellation based on the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ANIMAL_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Calculate the zodiac (rat, ox, tiger, rabbit...) based on the Chinese ID number. Support 15 or 18\",\r\n \"a\": \"Get the zodiac according to the ID number.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"ISIDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"Verify that the format of the ID card is correct. Support 15 or 18\",\r\n \"a\": \"Verify the correctness of the ID card format.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"ID number\",\r\n \"example\": \"\\\"31033519900101XXXX\\\"\",\r\n \"detail\": \"15-digit or 18-digit ID number or range.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DM_TEXT_CUTWORD\",\r\n \"t\": \"4\",\r\n \"d\": \"Text segmentation. Split a series of words into a series of individual words\",\r\n \"a\": \"Chinese text segmentation.\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\": \"Text\",\r\n \"example\": \"\\\"I came to Beijing Tsinghua University\\\"\",\r\n \"detail\": \"Any text that needs word segmentation.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Word segmentation mode\",\r\n \"example\": \"0\",\r\n \"detail\": \"The default is 0[precision mode], 1[full mode], 2[search engine mode].\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DM_TEXT_TFIDF\",\r\n \"t\": \"4\",\r\n \"d\": \"Use tf-idf algorithm for keyword extraction. Identify keywords from a series of text\",\r\n \"a\": \"tf-idf keyword recognition.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Text\",\r\n \"example\": \"\\\"I came to Beijing Tsinghua University\\\"\",\r\n \"detail\": \"Any text that needs word segmentation.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Number of keywords\",\r\n \"example\": \"20\",\r\n \"detail\": \"The number of keywords returned by the algorithm, the default is 20\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"Corpus\",\r\n \"example\": \"1\",\r\n \"detail\": \"Select a corpus in a specific field, the default is 0[General], 1[Finance], 2[Medical]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DM_TEXT_TEXTRANK\",\r\n \"t\": \"4\",\r\n \"d\": \"Use TextRank algorithm to extract keywords. Identify keywords from a series of text\",\r\n \"a\": \"TextRank keyword recognition.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Text\",\r\n \"example\": \"\\\"I came to Beijing Tsinghua University\\\"\",\r\n \"detail\": \"Any text that needs word segmentation.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Number of keywords\",\r\n \"example\": \"20\",\r\n \"detail\": \"The number of keywords returned by the algorithm, the default is 20\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"Corpus\",\r\n \"example\": \"1\",\r\n \"detail\": \"Select a corpus in a specific field, the default is 0[General], 1[Finance], 2[Medical]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_CLOSE\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the corresponding stock closing price of A shares.\",\r\n \"a\": \"Returns the closing price of stock.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_OPEN\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the opening price of stock.\",\r\n \"a\": \"Return the opening price of a shares.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_MAX\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the highest price of stock.\",\r\n \"a\": \"Return the highest price of stock.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_MIN\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the lowest price of stock.\",\r\n \"a\": \"Returns the lowest price of stock.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_VOLUMN\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the corresponding stock trading volume of A shares.\",\r\n \"a\": \"Returns the corresponding stock trading volume of A shares.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"DATA_CN_STOCK_AMOUNT\",\r\n \"t\": \"5\",\r\n \"d\": \"According to the stock code and date, return the corresponding stock turnover of A shares.\",\r\n \"a\": \"Returns the corresponding stock turnover of A shares.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"Stock code\",\r\n \"example\": \"\\\"000001\\\"\",\r\n \"detail\": \"6-digit stock code, required.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Date\",\r\n \"example\": \"2015-01-08\",\r\n \"detail\": \"The trading day of the stock, the default is the latest trading day\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangedate\"\r\n }, {\r\n \"name\": \"Reversion and exclusion\",\r\n \"example\": \"0\",\r\n \"detail\": \"Select the ex right restoration type of the stock, default to 0 [former reversion], 1 [original price], 2 [post reversion]\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"ISDATE\",\r\n \"t\": \"6\",\r\n \"d\": \"Returns whether a value is a date.\",\r\n \"a\": \"Whether a value is a date.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"value\",\r\n \"example\": \"\\\"1990-01-01\\\"\",\r\n \"detail\": \"The value to be verified as a date.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"LINESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell to describe the continuous trend of data\",\r\n \"a\": \"Generate sparklines line chart\",\r\n \"m\": [1, 8],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line color\",\r\n \"example\": \"#2ec7c9\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line thickness\",\r\n \"example\": \"1\",\r\n \"detail\": \"Line thickness of the line graph, the default is 1px\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line\",\r\n \"example\": \"avg\",\r\n \"detail\": \"A horizontal line, which can be min, max, avg, median, range or custom value, default 0 none\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line color\",\r\n \"example\": \"#000\",\r\n \"detail\": \"Color setting of auxiliary line, same as line color configuration, default #000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Maximum mark\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"Identifies the maximum value of the line graph, the same line color configuration, default 0 does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Minimum mark\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"Identify the minimum value of the line graph, the same line color configuration, default 0 does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Mark size\",\r\n \"example\": \"1.5\",\r\n \"detail\": \"The maximum and minimum mark size settings, the default is 1.5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"AREASPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell area chart, generally used to describe the continuous cumulative value trend of the data\",\r\n \"a\": \"Generate sparklines area chart\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line color\",\r\n \"example\": \"#2ec7c9\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Fill color\",\r\n \"example\": \"#CCF3F4\",\r\n \"detail\": \"Form an area chart, the same line color configuration, default 0 does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Line thickness\",\r\n \"example\": \"1\",\r\n \"detail\": \"Line thickness of the line graph, the default is 1px\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line\",\r\n \"example\": \"avg\",\r\n \"detail\": \"A horizontal line, which can be min, max, avg, median, range or custom value, default 0 none\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Auxiliary line color\",\r\n \"example\": \"#000\",\r\n \"detail\": \"Color setting of auxiliary line, same as line color configuration, default #000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the vertical histogram of cells, generally used to describe the size of discrete data\",\r\n \"a\": \"Generate sparklines vertical histogram\",\r\n \"m\": [1, 6],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Negative bar color\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"Negative bar color setting, representing the color of negative value, same as the bar color configuration, default #97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the bar chart, used to standardize the length of the bar chart, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can set the color of each bar individually, multiple settings can be set, and two formats are supported: 1 color such as #000, which means that the color of the first bar is black; 2 value range: color, such as -2:# 000 indicates that the bar with a value of -2 is black, 0:5:#000 indicates that the bar with a value of 0-5 is black, and the default is empty\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"STACKCOLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines, a cumulative vertical histogram embedded in a cell, generally used to describe the numerical size of multiple dimensions of discrete data\",\r\n \"a\": \"Generate sparklines cumulative vertical histogram\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Stack by column\",\r\n \"example\": \"1\",\r\n \"detail\": \"If you need to stack by row, set this item to false or 0, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the cumulative bar, used to regulate the length of the bar, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can individually set the bar color of each dimension, which can be set to the range of A1:A10, etc. The default is #2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell, generally used to describe the size of discrete data\",\r\n \"a\": \"Generate sparklines horizontal bar graph\",\r\n \"m\": [1, 6],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Negative bar color\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"Negative bar color setting, representing the color of negative value, same as the bar color configuration, default #97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the bar chart, used to standardize the length of the bar chart, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can set the color of each bar individually, multiple settings can be set, and two formats are supported: 1 color such as #000, which means that the color of the first bar is black; 2 value range: color, such as -2:# 000 indicates that the bar with a value of -2 is black, 0:5:#000 indicates that the bar with a value of 0-5 is black, and the default is empty\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"STACKBARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines, a cumulative horizontal bar graph embedded in a cell, which is generally used to describe the numerical size of multiple dimensions of discrete data\",\r\n \"a\": \"Generate sparklines cumulative horizontal bar graph\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Stack by column\",\r\n \"example\": \"1\",\r\n \"detail\": \"If you need to stack by row, set this item to false or 0, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Max\",\r\n \"example\": \"100\",\r\n \"detail\": \"The maximum value of the cumulative bar, used to regulate the length of the bar, the default is to automatically calculate false, auto, null\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can individually set the bar color of each dimension, which can be set to the range of A1:A10, etc. The default is #2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"DISCRETESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell, generally used to describe the trend of discrete data\",\r\n \"a\": \"Generate sparklines discrete graph\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Segmentation threshold\",\r\n \"example\": \"1\",\r\n \"detail\": \"Discrete graph column color distinction, for example: if the value is 0, blue is greater than 0, red is less than 0, and the default is 0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Above threshold color\",\r\n \"example\": \"#2ec7c9\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Below threshold color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The color setting of the bar below the threshold, the same as the color above the threshold, default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"TRISTATESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines, a three-state graph embedded in the cell, which is generally used to describe the trend of three situations, such as winning, losing, or drawing.\",\r\n \"a\": \"Generate sparklines three-state graph\",\r\n \"m\": [1, 6],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar interval\",\r\n \"example\": \"1\",\r\n \"detail\": \"The distance between bars, the default is 1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Bar color\",\r\n \"example\": \"#fc5c5c\",\r\n \"detail\": \"The line color of the line graph can be range A1, color table index value or specific color value. Set it to 0 or false to not display it. It supports regx, rgb, rgba, etc. Default #fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Negative bar color\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"Negative bar color setting, representing the color of negative value, same as the bar color configuration, default #97b552\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Zero value bar color\",\r\n \"example\": \"#999\",\r\n \"detail\": \"Zero value bar color setting, representing 0 value color, the same color configuration of the bar, default #999\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color palette can set the color of each bar individually, multiple settings can be set, and two formats are supported: 1 color such as #000, which means that the color of the first bar is black; 2 value range: color, such as -2:# 000 indicates that the bar with a value of -2 is black, 0:5:#000 indicates that the bar with a value of 0-5 is black, and the default is empty\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"PIESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines pie chart embedded in the cell, generally used to describe the proportion of data\",\r\n \"a\": \"Generate sparklines pie chart\",\r\n \"m\": [1, 5],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Rotation angle\",\r\n \"example\": \"0\",\r\n \"detail\": \"The rotation angle of the pie chart, the default is 0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"border\",\r\n \"example\": \"0\",\r\n \"detail\": \"Pie chart border size, default is none 0\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Border color\",\r\n \"example\": \"#000\",\r\n \"detail\": \"The border color of the pie chart, the default is #000\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Color palette\",\r\n \"example\": \"#97b552\",\r\n \"detail\": \"The color of the slice can be set in the palette, which can be set to the range of A1:A10, etc. The default is #2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BOXSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell box plot, generally used to describe the statistical distribution of the data set\",\r\n \"a\": \"Generate sparklines box plot\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"Range\",\r\n \"example\": \"A1:A20\",\r\n \"detail\": \"Range,Values can be calculated effectively, such as A1:A20, {1,2,3,4,5}, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Outlier ratio\",\r\n \"example\": \"1.5\",\r\n \"detail\": \"The threshold range of outliers, if it is 0 or false, it will not be displayed, the default is 1.5 times\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Target value\",\r\n \"example\": \"10\",\r\n \"detail\": \"The target value setting on the box plot, the default is false and does not display\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Point size\",\r\n \"example\": \"1.5\",\r\n \"detail\": \"The radius of the target point and outlier is set, the default is 1.5\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"BULLETSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Generate sparklines embedded in the cell, generally used to describe the task achievement rate\",\r\n \"a\": \"Generating sparklines bullets\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"Target\",\r\n \"example\": \"10\",\r\n \"detail\": \"The numerical value can be calculated effectively for the achieved target value, such as A1, 100, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"achieved\",\r\n \"example\": \"8\",\r\n \"detail\": \"Only when the value is completed can the value be calculated effectively, such as A1, 100, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"Contrast\",\r\n \"example\": \"12\",\r\n \"detail\": \"Comparative values, such as excess, minimum, and bottom line for awards, can be effectively calculated, such as A1, 100, etc. You can set up to 9 comparison values\",\r\n \"require\": \"o\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"COMPOSESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"Support multiple types of pictures in the same cell, each parameter represents a sparklines diagram\",\r\n \"a\": \"Combine sparklines graphs into one cell\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"config\",\r\n \"example\": \"PIESPLINES(A1:A20)\",\r\n \"detail\": \"Sparklines chart settings, such as A1:A20, a completed pie chart, line chart settings, etc.\",\r\n \"require\": \"m\",\r\n \"repeat\": \"y\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"SORT\",\r\n \"t\": \"14\",\r\n \"d\": \"Sorts the rows of a given array or range by the values in one or more columns.\",\r\n \"a\": \"Sorts rows of range by specified column.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The data to be sorted.\",\r\n \"example\": \"A2:A17\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"sort_column\",\r\n \"detail\": \"The index of the column in `range` or a range outside of `range` containing the values by which to sort.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"is_ascending\",\r\n \"detail\": \"`TRUE` or `FALSE` indicating whether to sort `sort_column` in ascending order. `FALSE` sorts in descending order.\",\r\n \"example\": \"-1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"sort_column2\",\r\n \"detail\": \"Additional columns.\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"FILTER\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns a filtered version of the source range, returning only rows or columns which meet the specified conditions.\",\r\n \"a\": \"Filters a range based off provided conditions.\",\r\n \"m\": [2, 3],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The data to be filtered.\",\r\n \"example\": \"A5:D20\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"condition1\",\r\n \"detail\": \"A column or row containing true or false values corresponding to the first column or row of `range`, or an array formula evaluating to true or false.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"range\"\r\n }, {\r\n \"name\": \"condition2\",\r\n \"detail\": \"Additional rows or columns containing boolean values `TRUE` or `FALSE` indicating whether the corresponding row or column in `range` should pass through `FILTER`. Can also contain array formula expressions which evaluate to such rows or columns. All conditions must be of the same type (row or column). Mixing row conditions and column conditions is not permitted.\",\r\n \"example\": \"\\\"\\\"\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"UNIQUE\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns unique rows in the provided source range, discarding duplicates. Rows are returned in the order in which they first appear in the source range.\",\r\n \"a\": \"Unique rows in the provided source range.\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\": \"range\",\r\n \"detail\": \"The data to filter by unique entries.\",\r\n \"example\": \"A2:B26\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"by_col\",\r\n \"detail\": \"[Option] - Logical value, indicating how to compare; by row = FALSE() or omitted; by column = TRUE().\",\r\n \"example\": \"TRUE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }, {\r\n \"name\": \"occurs_once\",\r\n \"detail\": \"[Option] - Logical value, only one occurrence in the unique value is returned = TRUE(); including all unique values = FALSE() or omitted.\",\r\n \"example\": \"FALSE()\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n }, {\r\n \"n\": \"RANDARRAY\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns a grid of random numbers between 0 inclusive and 1 exclusive. The grid size will match the provided rows and columns arguments. If neither rows nor columns are provided, then the grid will be size 1 x 1.\",\r\n \"a\": \"Returns a grid of random numbers.\",\r\n \"m\": [0, 2],\r\n \"p\": [{\r\n \"name\": \"rows\",\r\n \"detail\": \"The number of rows to populate with a random number.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"columns\",\r\n \"detail\": \"The number of columns to populate with a random number.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n }, {\r\n \"n\": \"SEQUENCE\",\r\n \"t\": \"14\",\r\n \"d\": \"Returns a grid of sequential numbers starting at a specified start value and increasing by a specified step size. By default, the sequence starts at and increases by 1.\",\r\n \"a\": \"Returns a grid of sequential numbers.\",\r\n \"m\": [1, 4],\r\n \"p\": [{\r\n \"name\": \"rows\",\r\n \"detail\": \"The number of rows in the function's resulting grid.\",\r\n \"example\": \"1\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"columns\",\r\n \"detail\": \"The number of columns in the function's resulting grid. If omitted, the result grid will have 1 column.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"start\",\r\n \"detail\": \"The number, at which to start the sequence. If omitted, the sequence will start at 1.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }, {\r\n \"name\": \"step\",\r\n \"detail\": \"The amount each value in the sequence will differ by. If omitted, each value will differ by 1.\",\r\n \"example\": \"1\",\r\n \"require\": \"o\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangenumber\"\r\n }]\r\n },\r\n {\r\n \"n\": \"EVALUATE\",\r\n \"t\": \"3\",\r\n \"d\": \"Evaluate a formula or expression expressed in words and return the result\",\r\n \"a\": \"Evaluate according to literal formula or expression.\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\": \"expression\",\r\n \"example\": '\"A1+5*2^2\"',\r\n \"detail\": \"Formula or expression\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n ],\r\n toolbar: {\r\n undo: 'Deshacer',\r\n redo: 'Rehacer',\r\n paintFormat: 'Clonar formato',\r\n currencyFormat: 'Formato de moneda',\r\n percentageFormat: 'Formato de porcentaje',\r\n numberDecrease: 'Menos decimales',\r\n numberIncrease: 'Más decimales',\r\n moreFormats:'Más formatos',\r\n font: 'Fuente',\r\n fontSize: 'Tamaño Fuente',\r\n bold: 'Negrita (Ctrl+B)',\r\n italic : 'Itálica (Ctrl+I)',\r\n strikethrough: 'Tachar (Alt+Shift+5)',\r\n underline: 'Guion bajo',\r\n textColor: 'Color texto',\r\n chooseColor: 'elegir color',\r\n resetColor: 'Reinicializar',\r\n customColor: 'PERSONALIZADO',\r\n alternatingColors: 'Colores alternos',\r\n confirmColor: 'Vale',\r\n cancelColor: 'Cancelar',\r\n collapse: 'Recoger',\r\n fillColor: 'Color de relleno',\r\n border: 'Borde',\r\n borderStyle: 'Estilo Borde',\r\n mergeCell: 'Juntar celdas',\r\n chooseMergeType: 'Elegir tipo de unión',\r\n horizontalAlign: 'Alineación Horizontal',\r\n verticalAlign: 'Alineación Vertical',\r\n alignment: 'Alineación',\r\n textWrap: 'Ajuste de texto',\r\n textWrapMode: 'Modo de ajuste de texto',\r\n textRotate: 'Rotar texto',\r\n textRotateMode: 'Modo de rotar texto',\r\n freezeTopRow: 'Fijar fila superior',\r\n sortAndFilter: 'Ordenar y filtrar',\r\n findAndReplace: 'Buscar y reemplazar',\r\n sum: 'SUMA',\r\n autoSum: 'SUMA automática',\r\n moreFunction: 'Más funciones',\r\n conditionalFormat: 'Formato condicional',\r\n postil: 'Comentario',\r\n pivotTable: 'Tabla Dinámica',\r\n chart: 'Gráfica',\r\n screenshot: 'Captura de pantalla',\r\n splitColumn: 'Separar texto',\r\n insertImage: 'Insertar imagen',\r\n dataVerification: 'Verificación de datos',\r\n protection:\"Proteger la hoja\",\r\n\r\n clearText:\"Limpiar color\",\r\n noColorSelectedText:\"Ningún color seleccionado\",\r\n\r\n toolMore:\"Más\",\r\n toolLess:\"Menos\",\r\n toolClose:\"Cerrar\",\r\n toolMoreTip:\"Más funcionalidades\",\r\n moreOptions:\"Más opciones\",\r\n\r\n cellFormat:\"Configuración formato de celda\",\r\n print:\"Imprimir\",\r\n },\r\n alternatingColors:{\r\n applyRange: 'Aplicar a rango',\r\n selectRange: 'Seleccionar un rango de datos',\r\n header: 'Cabecera',\r\n footer: 'Pie',\r\n\r\n errorInfo:\"No se puede realizar esta operación en varias áreas de selección, selecciona una sola área y vuelve a intentarlo\",\r\n textTitle:\"Estilo Formato\",\r\n custom:\"PERSONALIZADO\",\r\n close:\"cerrar\",\r\n selectionTextColor:\"Haz clic para seleccionar el color del texto\",\r\n selectionCellColor:\"Haz clic para seleccionar el color de la celda\",\r\n removeColor:\"Eliminar colores alternos\",\r\n colorShow:\"color\",\r\n currentColor:\"Actual\",\r\n\r\n tipSelectRange:\"Selecciona la gama de colores alternos\",\r\n errorNoRange:\"No hay ningún rango seleccionado\",\r\n errorExistColors:\"Los colores alternos ya existen y no se pueden editar\",\r\n },\r\n button: {\r\n confirm: 'Vale',\r\n cancel: 'Cancelar',\r\n close:\"Cerrar\",\r\n update:\"Actualizar\",\r\n delete:\"Eliminar\",\r\n insert:\"Insertar\",\r\n },\r\n paint:{\r\n start: 'Inicio clonar formato',\r\n end: 'ESC',\r\n\r\n tipSelectRange:\"Selecciona el rango que quieres copiar\",\r\n tipNotMulti:\"No se puede realizar esta operación en un rango de selección múltiple\",\r\n },\r\n format:{\r\n moreCurrency: 'Más formatos de moneda',\r\n moreDateTime: 'Más formatos de fecha y hora',\r\n moreNumber: 'Más formatos de número',\r\n\r\n titleCurrency: 'Formatos de moneda',\r\n decimalPlaces: 'Decimales',\r\n titleDateTime: 'Formatos de fecha y hora',\r\n titleNumber: 'Formatos de números'\r\n },\r\n info:{\r\n detailUpdate: 'Nuevo abierto',\r\n detailSave: 'Cache local restaurado',\r\n row: '',\r\n column: '',\r\n loading:\"Cargando\",\r\n\r\n copy:\"Copiar\",\r\n return:\"Salir\",\r\n rename:\"Renombrar\",\r\n tips:\"Renombrar Libro\",\r\n noName:\"Hoja sin título\",\r\n wait:\"esperando actualización\",\r\n\r\n add:\"Añadir\",\r\n addLast:\"más filas al final\",\r\n backTop:\"Volver arriba\",\r\n pageInfo:'Total ${total},página ${totalPage},actual ${currentPage}',\r\n nextPage:\"Siguiente\",\r\n\r\n tipInputNumber:\"Introduce el número\",\r\n tipInputNumberLimit:\"El rango de aumento está limitado a 1-100\",\r\n\r\n tipRowHeightLimit:\"La altura de la fila debe estar entre 0 ~ 545\",\r\n tipColumnWidthLimit:\"El ancho de la columna debe estar entre 0 ~ 2038\",\r\n pageInfoFull:'Total ${total},página ${totalPage},Se muestran todos los datos',\r\n },\r\n currencyDetail:{\r\n RMB:'RMB',\r\n USdollar:'Dólar US',\r\n EUR:'EUR',\r\n GBP:'GBP',\r\n HK:'HK',\r\n JPY:'JPY',\r\n AlbanianLek:'Albanian Lek',\r\n AlgerianDinar:'Algerian Dinar',\r\n Afghani:'Afghani',\r\n ArgentinePeso:'Argentine Peso',\r\n UnitedArabEmiratesDirham:'United Arab Emirates Dirham',\r\n ArubanFlorin:'Aruban Florin',\r\n OmaniRial:'Omani Rial',\r\n Azerbaijanimanat:'Azerbaijani manat',\r\n EgyptianPound:'Egyptian Pound',\r\n EthiopianBirr:'Ethiopian Birr',\r\n AngolaKwanza:'Angola Kwanza',\r\n AustralianDollar:'Australian Dollar',\r\n Patacas:'Patacas',\r\n BarbadosDollar:'Barbados Dollar',\r\n PapuaNewGuineaKina:'Papua New Guinea Kina',\r\n BahamianDollar:'Bahamian Dollar',\r\n PakistanRupee:'Pakistan Rupee',\r\n ParaguayanGuarani:'Paraguayan Guarani',\r\n BahrainiDinar:'Bahraini Dinar',\r\n PanamanianBalboa:'Panamanian Balboa',\r\n Brazilianreal:'Brazilian real',\r\n Belarusianruble:'Belarusian ruble',\r\n BermudianDollar:'Bermudian Dollar',\r\n BulgarianLev:'Bulgarian Lev',\r\n IcelandKrona:'Iceland Krona',\r\n BosniaHerzegovinaConvertibleMark:'Bosnia-Herzegovina Convertible Mark',\r\n PolishZloty:'Polish Zloty',\r\n Boliviano:'Boliviano',\r\n BelizeDollar:'Belize Dollar',\r\n BotswanaPula:'Botswana Pula',\r\n NotDannuzhamu:'Not Dannuzhamu',\r\n BurundiFranc:'Burundi Franc',\r\n NorthKoreanWon:'North Korean Won',\r\n DanishKrone:'Danish Krone',\r\n EastCaribbeanDollar:'East Caribbean Dollar',\r\n DominicaPeso:'Dominica Peso',\r\n RussianRuble:'Russian Ruble',\r\n EritreanNakfa:'Eritrean Nakfa',\r\n CFAfranc:'CFA franc',\r\n PhilippinePeso:'Philippine Peso',\r\n FijiDollar:'Fiji Dollar',\r\n CapeVerdeEscudo:'Cape Verde Escudo',\r\n FalklandIslandsPound:'Falkland Islands Pound',\r\n GambianDalasi:'Gambian Dalasi',\r\n Congolesefranc:'Congolese franc',\r\n ColombianPeso:'Colombian Peso',\r\n CostaRicanColon:'Costa Rican Colon',\r\n CubanPeso:'Cuban Peso',\r\n Cubanconvertiblepeso:'Cuban convertible peso',\r\n GuyanaDollar:'Guyana Dollar',\r\n KazakhstanTenge:'Kazakhstan Tenge',\r\n Haitiangourde:'Haitian gourde',\r\n won:'won',\r\n NetherlandsAntillesGuilder:'Netherlands Antilles Guilder',\r\n Honduraslempiras:'Honduras lempiras',\r\n DjiboutiFranc:'Djibouti Franc',\r\n KyrgyzstanSom:'Kyrgyzstan Som',\r\n GuineaFranc:'Guinea Franc',\r\n CanadianDollar:'Canadian Dollar',\r\n GhanaianCedi:'Ghanaian Cedi',\r\n Cambodianriel:'Cambodian riel',\r\n CzechKoruna:'Czech Koruna',\r\n ZimbabweDollar:'Zimbabwe Dollar',\r\n QatariRiyal:'Qatari Riyal',\r\n CaymanIslandsDollar:'Cayman Islands Dollar',\r\n Comorianfranc:'Comorian franc',\r\n KuwaitiDinar:'Kuwaiti Dinar',\r\n CroatianKuna:'Croatian Kuna',\r\n KenyanShilling:'Kenyan Shilling',\r\n LesothoLoti:'Lesotho Loti',\r\n LaoKip:'Lao Kip',\r\n LebanesePound:'Lebanese Pound',\r\n Lithuanianlitas:'Lithuanian litas',\r\n LibyanDinar:'Libyan Dinar',\r\n LiberianDollar:'Liberian Dollar',\r\n RwandaFranc:'Rwanda Franc',\r\n RomanianLeu:'Romanian Leu',\r\n MalagasyAriary:'Malagasy Ariary',\r\n MaldivianRufiyaa:'Maldivian Rufiyaa',\r\n MalawiKwacha:'Malawi Kwacha',\r\n MalaysianRinggit:'Malaysian Ringgit',\r\n MacedoniawearingDinar:'Macedonia wearing Dinar',\r\n MauritiusRupee:'Mauritius Rupee',\r\n MauritanianOuguiya:'Mauritanian Ouguiya',\r\n MongolianTugrik:'Mongolian Tugrik',\r\n BangladeshiTaka:'Bangladeshi Taka',\r\n PeruvianNuevoSol:'Peruvian Nuevo Sol',\r\n MyanmarKyat:'Myanmar Kyat',\r\n MoldovanLeu:'Moldovan Leu',\r\n MoroccanDirham:'Moroccan Dirham',\r\n MozambiqueMetical:'Mozambique Metical',\r\n MexicanPeso:'Mexican Peso',\r\n NamibianDollar:'Namibian Dollar',\r\n SouthAfricanRand:'South African Rand',\r\n SouthSudanesePound:'South Sudanese Pound',\r\n NicaraguaCordoba:'Nicaragua Cordoba',\r\n NepaleseRupee:'Nepalese Rupee',\r\n NigerianNaira:'Nigerian Naira',\r\n NorwegianKrone:'Norwegian Krone',\r\n GeorgianLari:'Georgian Lari',\r\n RMBOffshore:'RMB (Offshore)',\r\n SwedishKrona:'Swedish Krona',\r\n SwissFranc:'Swiss Franc',\r\n SerbianDinar:'Serbian Dinar',\r\n SierraLeone:'Sierra Leone',\r\n SeychellesRupee:'Seychelles Rupee',\r\n SaudiRiyal:'Saudi Riyal',\r\n SaoTomeDobra:'Sao Tome Dobra',\r\n SaintHelenapound:'Saint Helena pound',\r\n SriLankaRupee:'Sri Lanka Rupee',\r\n SwazilandLilangeni:'Swaziland Lilangeni',\r\n SudanesePound:'Sudanese Pound',\r\n Surinamesedollar:'Surinamese dollar',\r\n SolomonIslandsDollar:'Solomon Islands Dollar',\r\n SomaliShilling:'Somali Shilling',\r\n TajikistanSomoni:'Tajikistan Somoni',\r\n PacificFranc:'Pacific Franc',\r\n ThaiBaht:'Thai Baht',\r\n TanzanianShilling:'Tanzanian Shilling',\r\n TonganPaanga:\"Tongan Pa'anga\",\r\n TrinidadandTobagoDollar:'Trinidad and Tobago Dollar',\r\n TunisianDinar:'Tunisian Dinar',\r\n TurkishLira:'Turkish Lira',\r\n VanuatuVatu:'Vanuatu Vatu',\r\n GuatemalanQuetzal:'Guatemalan Quetzal',\r\n CommissionBolivar:'Commission Bolivar',\r\n BruneiDollar:'Brunei Dollar',\r\n UgandanShilling:'Ugandan Shilling',\r\n UkrainianHryvnia:'Ukrainian Hryvnia',\r\n UruguayanPeso:'Uruguayan Peso',\r\n Uzbekistansom:'Uzbekistan som',\r\n WesternSamoaTala:'Western Samoa Tala',\r\n SingaporeDollar:'Singapore Dollar',\r\n NT:'NT',\r\n NewZealandDollar:'New Zealand Dollar',\r\n HungarianForint:'Hungarian Forint',\r\n SyrianPound:'Syrian Pound',\r\n JamaicanDollar:'Jamaican Dollar',\r\n ArmenianDram:'Armenian Dram',\r\n YemeniRial:'Yemeni Rial',\r\n IraqiDinar:'Iraqi Dinar',\r\n IranianRial:'Iranian Rial',\r\n NewIsraeliShekel:'New Israeli Shekel',\r\n IndianRupee:'Indian Rupee',\r\n IndonesianRupiah:'Indonesian Rupiah',\r\n JordanianDinar:'Jordanian Dinar',\r\n VND:'VND',\r\n ZambianKwacha:'Zambian Kwacha',\r\n GibraltarPound:'Gibraltar Pound',\r\n ChileanPeso:'Chilean Peso',\r\n CFAFrancBEAC:'CFA Franc BEAC'\r\n },\r\n defaultFmt:[\r\n { \"text\": 'Automático', \"value\": \"General\", \"example\": \"\" },\r\n { \"text\": 'Texto', \"value\": \"@\", \"example\": \"\" },\r\n { \"text\": \"\", \"value\": \"partir\", \"example\": \"\" },\r\n { \"text\": 'Número', \"value\": \"##0.00\", \"example\": \"1000.12\" },\r\n { \"text\": 'Porcentaje', \"value\": \"#0.00%\", \"example\": \"12.21%\" },\r\n { \"text\": 'Científico', \"value\": \"0.00E+00\", \"example\": \"1.01E+5\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": 'Contabilidad', \"value\": \"¥(0.00)\", \"example\": \"¥(1200.09)\" },\r\n\r\n\r\n { \"text\": 'Moneda', \"value\": \"¥0.00\", \"example\": \"¥1200.09\" },\r\n\r\n\r\n { \"text\": \"\", \"value\": \"partir\", \"example\": \"\" },\r\n { \"text\": 'Fecha', \"value\": \"yyyy-MM-dd\", \"example\": \"2017-11-29\" },\r\n { \"text\": 'Hora', \"value\": \"hh:mm AM/PM\", \"example\": \"3:00 PM\" },\r\n { \"text\": 'Hora 24H', \"value\": \"hh:mm\", \"example\": \"15:00\" },\r\n { \"text\": 'Fecha Hora', \"value\": \"yyyy-MM-dd hh:mm AM/PM\", \"example\": \"2017-11-29 3:00 PM\" },\r\n { \"text\": 'Fecha Hora 24 H', \"value\": \"yyyy-MM-dd hh:mm\", \"example\": \"2017-11-29 15:00\" },\r\n { \"text\": \"\", \"value\": \"partir\", \"example\": \"\" },\r\n { \"text\": 'Formatos personalizados', \"value\": \"fmtOtherSelf\", \"example\": \"más\" }\r\n ],\r\n dateFmtList:[\r\n {\r\n \"name\": \"1930-08-05\",\r\n \"value\": \"yyyy-MM-dd\"\r\n },\r\n {\r\n \"name\": \"1930/8/5\",\r\n \"value\": \"yyyy/MM/dd\"\r\n },\r\n {\r\n \"name\": \"08-05\",\r\n \"value\": \"MM-dd\"\r\n },\r\n {\r\n \"name\": \"8-5\",\r\n \"value\": \"M-d\"\r\n },\r\n {\r\n \"name\": \"13:30:30\",\r\n \"value\": \"h:mm:ss\"\r\n },\r\n {\r\n \"name\": \"13:30\",\r\n \"value\": \"h:mm\"\r\n },\r\n {\r\n \"name\": \"PM 01:30\",\r\n \"value\": 'AM/PM hh:mm'\r\n },\r\n {\r\n \"name\": \"PM 1:30\",\r\n \"value\": 'AM/PM h:mm'\r\n },\r\n {\r\n \"name\": \"PM 1:30:30\",\r\n \"value\": 'AM/PM h:mm:ss'\r\n },\r\n {\r\n \"name\": \"08-05 PM 01:30\",\r\n \"value\": \"MM-dd AM/PM hh:mm\"\r\n }\r\n ],\r\n fontFamily:{\r\n MicrosoftYaHei:\"YaHei\",\r\n },\r\n fontarray: [\"Times New Roman\",\"Arial\",\"Tahoma\",\"Verdana\"],\r\n fontjson: {\"times new roman\":0,\"arial\":1,\"tahoma\":2,\"verdana\":3},\r\n border:{\r\n borderTop:'borderTop',\r\n borderBottom:'borderBottom',\r\n borderLeft:'borderLeft',\r\n borderRight:'borderRight',\r\n borderNone:'borderNone',\r\n borderAll:'borderAll',\r\n borderOutside:'borderOutside',\r\n borderInside:'borderInside',\r\n borderHorizontal:'borderHorizontal',\r\n borderVertical:'borderVertical',\r\n borderColor:'borderColor',\r\n borderSize:'borderSize',\r\n },\r\n merge:{\r\n mergeAll:\"Unir todo\",\r\n mergeV:\"Verticalmente\",\r\n mergeH:\"Horizontalmente\",\r\n mergeCancel:\"Separar\",\r\n overlappingError:\"No se pueden fusionar áreas superpuestas\",\r\n partiallyError:\"No se puede realizar esta operación en celdas parcialmente unidas\",\r\n },\r\n align:{\r\n left:\"izquierda\",\r\n center:\"centro\",\r\n right:\"derecha\",\r\n\r\n top:\"Arriba\",\r\n middle:\"Centro\",\r\n bottom:\"Abajo\",\r\n },\r\n textWrap:{\r\n \"overflow\":\"Desbordar\",\r\n \"wrap\":\"Ajustar\",\r\n \"clip\":\"Cortar\",\r\n },\r\n rotation:{\r\n \"none\":\"Ninguno\",\r\n \"angleup\":\"Ladear Arriba\",\r\n \"angledown\":\"Ladear Abajo\",\r\n \"vertical\":\"Apilar Verticalmente\",\r\n \"rotationUp\":\"Rotar Arriba\",\r\n \"rotationDown\":\"Rotar Abajo\"\r\n },\r\n freezen:{\r\n default:\"Fijar\",\r\n freezenRow:\"Primera Fila\",\r\n freezenColumn:\"Primera Columna\",\r\n freezenRC:\"Ambas\",\r\n freezenRowRange:\"Fijar rango filas\",\r\n freezenColumnRange:\"Fijar rango columnas\",\r\n freezenRCRange:\"Fijar ambos rangos\",\r\n freezenCancel:\"Cancelar\",\r\n\r\n noSeletionError:\"No hay rango para seleccionar\",\r\n },\r\n sort:{\r\n \"asc\":\"Ascendente \",\r\n \"desc\":\"Descendente \",\r\n \"custom\":\"Ordenación personalizada\",\r\n\r\n \"hasTitle\":\"Los datos tienen una fila de encabezado\",\r\n \"sortBy\":\"Ordenar por\",\r\n \"addOthers\":\"Añadir otra columna de ordenación\",\r\n \"close\":\"cerrar\",\r\n \"confirm\":\"ordenar\",\r\n\r\n \"columnOperation\":\"Columna\",\r\n \"secondaryTitle\":\"y después por\",\r\n\r\n \"sortTitle\":\"Ordenar rango\",\r\n\r\n \"sortRangeTitle\":\"Ordenar rango de\",\r\n \"sortRangeTitleTo\":\"a\",\r\n\r\n\r\n \"noRangeError\":\"No se puede realizar esta operación en múltiples áreas de selección, selecciona un solo rango e intenta nuevamente\",\r\n \"mergeError\":\"Hay celdas combinadas en la selección, ¡esta operación no se puede realizar!\",\r\n\r\n },\r\n filter:{\r\n filter:\"crear filtro\", \r\n\r\n sortByAsc:\"Ordenar A-Z\",\r\n sortByDesc:\"Ordenar Z-A\",\r\n filterByColor:\"Filtrar por color\",\r\n filterByCondition:\"Filtrar por condición\",\r\n filterByValues:\"Filtrar por valores\",\r\n\r\n filiterInputNone:\"Ninguno\",\r\n\r\n filiterInputTip:\"Introduce valor de filtro\",\r\n filiterRangeStartTip:\"Valor para fórmula\",\r\n filiterRangeEndTip:\"Valor para fórmula\",\r\n\r\n filterValueByAllBtn:\"Seleccionar todos\",\r\n filterValueByClearBtn:\"Limpiar\",\r\n filterValueByInverseBtn:\"Invertir\",\r\n filterValueByTip:\"filtrar por valores\",\r\n filterConform:\"Confirmar\",\r\n filterCancel:\"Cancelar\",\r\n clearFilter:\"Quitar filtro\",\r\n\r\n conditionNone:\"Ninguno\",\r\n conditionCellIsNull: \"Está vacío\",\r\n conditionCellNotNull: \"No está vacío\",\r\n conditionCellTextContain: \"El texto contiene\",\r\n conditionCellTextNotContain: \"El texto no contiene\",\r\n conditionCellTextStart: \"El texto empieza con\",\r\n conditionCellTextEnd: \"El texto termina con\",\r\n conditionCellTextEqual: \"El texto es exactamente\",\r\n conditionCellDateEqual: \"La fecha es\",\r\n conditionCellDateBefore: \"La fecha es anterior\",\r\n conditionCellDateAfter: \"La fecha es posterior\",\r\n conditionCellGreater: \"Mayor que\",\r\n conditionCellGreaterEqual: \"Mayor o igual que\",\r\n conditionCellLess: \"Menor que\",\r\n conditionCellLessEqual: \"Menor o igual que\",\r\n conditionCellEqual: \"Es igual a\",\r\n conditionCellNotEqual: \"No es igual a\",\r\n conditionCellBetween: \"Está entre\",\r\n conditionCellNotBetween: \"No está entre\",\r\n\r\n filiterMoreDataTip:\"¡Gran cantidad de datos! por favor espera\",\r\n filiterMonthText:\"Mes\",\r\n filiterYearText:\"Año\",\r\n filiterByColorTip:\"Filtrar por color de celda\",\r\n filiterByTextColorTip:\"Filtrar por color de fuente\",\r\n filterContainerOneColorTip:\"Esta columna contiene solo un color\",\r\n filterDateFormatTip:\"Format fecha\",\r\n\r\n valueBlank:\"(Nulo)\",\r\n mergeError:\"Hay celdas combinadas en la selección del filtro, ¡esta operación no se puede realizar!\",\r\n },\r\n rightclick: {\r\n copy: 'Copiar',\r\n copyAs: 'Copiar como',\r\n paste: 'Pegar',\r\n insert: 'Insertar',\r\n delete: 'Eliminar',\r\n deleteCell: 'Eliminar celda',\r\n deleteSelected: 'Eliminar seleccionado ',\r\n hide: 'Esconder',\r\n hideSelected: 'Esconder seleccionado ',\r\n showHide: 'Mostrar ocultos ',\r\n to: 'Hacia',\r\n left: 'Izquierda',\r\n right: 'Derecha',\r\n top: 'Arriba',\r\n bottom: 'Abajo',\r\n moveLeft: 'Mover izquierda',\r\n moveUp: 'Mover arriba',\r\n add: 'Añadir',\r\n row: 'Fila',\r\n column: 'Columna',\r\n width: 'Ancho',\r\n height: 'Alto',\r\n number: 'Número',\r\n confirm: 'Confirmar',\r\n orderAZ: 'Ordenar A-Z',\r\n orderZA: 'Ordenar Z-A',\r\n clearContent: 'Limpiar contenido',\r\n matrix: 'Operación de Matriz',\r\n sortSelection: 'Ordenar',\r\n filterSelection: 'Filtrar',\r\n chartGeneration: 'Crear gráfico',\r\n firstLineTitle: 'título primera línea',\r\n untitled: 'sin título',\r\n array1: 'Matriz unidimensional',\r\n array2: 'Matriz bidimensional',\r\n array3: 'Matrices multidimensionales',\r\n diagonal: 'Diagonal',\r\n antiDiagonal: 'Anti-diagonal',\r\n diagonalOffset: 'Desplazamiento Diagonal',\r\n offset: 'Desplazamiento',\r\n boolean: 'Booleana',\r\n flip: 'Voltear',\r\n upAndDown: 'Arriba y abajo',\r\n leftAndRight: 'Izquierda y derecha',\r\n clockwise: 'Sentido horario',\r\n counterclockwise: 'Sentido anti-horario',\r\n transpose: 'Transponer',\r\n matrixCalculation: 'Cálculo de matrices',\r\n plus: 'Suma',\r\n minus: 'Resta',\r\n multiply: 'Multiplicación',\r\n divided: 'División',\r\n power: 'Exponenciación',\r\n root: 'Raíz Cuadrada',\r\n log: 'Logaritmo',\r\n delete0: 'Eliminar valores nulos en ambos extremos',\r\n removeDuplicate: 'Eliminar valores duplicados',\r\n byRow: 'Por fila',\r\n byCol: 'Por columna',\r\n generateNewMatrix: 'Generar nueva matriz',\r\n \r\n },\r\n comment:{\r\n \"insert\":\"Insertar\",\r\n \"edit\":\"Editar\",\r\n \"delete\":\"Elimiar\",\r\n \"showOne\":\"Mostrar/Ocular\",\r\n \"showAll\":\"Mostrar/Ocular Todo\"\r\n },\r\n screenshot:{\r\n screenshotTipNoSelection:\"Selecciona el alcance de la captura de pantalla\",\r\n screenshotTipTitle:\"¡Advertencia!\",\r\n screenshotTipHasMerge:\"Esta operación no se puede realizar en celdas combinadas\",\r\n screenshotTipHasMulti:\"Esta operación no se puede realizar en varios rangos de selección\",\r\n screenshotTipSuccess:\"Exitoso\",\r\n screenshotImageName:\"Captura de pantalla\",\r\n\r\n downLoadClose:\"Cerrar\",\r\n downLoadCopy:\"Copiar al portapapeles\",\r\n downLoadBtn:\"Descargar\",\r\n browserNotTip:\"no es compatible con el navegador IE.\",\r\n rightclickTip:\"Haz clic con el botón derecho en la imagen y selecciona \\\"copiar\\\"\",\r\n successTip:\"Con éxito (si falla el pegado, haz clic con el botón derecho en la imagen para \\\"copiar imagen\\\")\",\r\n },\r\n splitText:{\r\n splitDelimiters:\"Delimitadores\",\r\n splitOther:\"Otros\",\r\n splitContinueSymbol:\"Los separadores consecutivos se tratan como uno solo\",\r\n splitDataPreview:\"Previsualizar\",\r\n splitTextTitle:\"Partir texto\",\r\n splitConfirmToExe:\"Ya hay datos aquí, ¿quieres reemplazarlos?\",\r\n\r\n tipNoMulti: \"No se puede realizar esta operación en varias áreas de selección, selecciona una única área y vuelve a intentarlo\",\r\n tipNoMultiColumn: \"Solo se puede convertir una columna de datos a la vez. El área seleccionado puede tener varias filas, pero no varias columnas. Vuelve a intentarlo después de seleccionar un solo rango de columnas\",\r\n },\r\n imageText:{\r\n imageSetting: 'Configuración de imagen',\r\n close: 'Cerrar',\r\n conventional: 'Convencional',\r\n moveCell1: 'Mover y cambiar el tamaño de las celdas',\r\n moveCell2: 'Mover y no cambiar el tamaño de la celda',\r\n moveCell3: 'No mover ni cambiar el tamaño de la celda',\r\n fixedPos: 'Posición fija',\r\n border: 'Borde',\r\n width: 'Ancho',\r\n radius: 'Radio',\r\n style: 'Estilo',\r\n solid: 'Sólido',\r\n dashed: 'Discontinua',\r\n dotted: 'Punteado',\r\n double: 'Doble',\r\n color: 'Color',\r\n },\r\n punctuation:{\r\n \"tab\":\"Tabulación\",\r\n \"semicolon\":\"punto y coma\",\r\n \"comma\":\"coma\",\r\n \"space\":\"espacio\",\r\n \r\n },\r\n findAndReplace:{\r\n find:\"Encontrar\",\r\n replace:\"Reemplazar\",\r\n goto:\"Ir a\",\r\n location:\"Ubicación\",\r\n formula:\"Fórmula\",\r\n date:\"Fecha\",\r\n number:\"Número\",\r\n string:\"Texto\",\r\n error:\"Error\",\r\n condition:\"Condición\",\r\n rowSpan:\"Intervalo de filas\",\r\n columnSpan:\"Intervalo de columnas\",\r\n locationExample:\"Ubicación\",\r\n lessTwoRowTip:\"Selecciona al menos dos filas\",\r\n lessTwoColumnTip:\"Selecciona al menos dos columnas\",\r\n\r\n findTextbox:\"Encontrar Contenido\",\r\n replaceTextbox:\"Reemplazar Contenido\",\r\n\r\n regexTextbox:\"Expresión Regular\",\r\n wholeTextbox:\"Palabra entera\",\r\n distinguishTextbox:\"Distingue mayúsculas y minúsculas\",\r\n\r\n allReplaceBtn:\"Reemplazar Todo\",\r\n replaceBtn:\"Reemplazar\",\r\n allFindBtn:\"Encontrar Todo\",\r\n findBtn:\"Encontrar siguiente\",\r\n\r\n noFindTip:\"No se encontró el contenido\",\r\n modeTip:\"Esta operación no está disponible en este modo\",\r\n\r\n searchTargetSheet:\"Hoja\",\r\n searchTargetCell:\"Celda\",\r\n searchTargetValue:\"Valor\",\r\n\r\n searchInputTip:\"Introduce el contenido de la búsqueda\",\r\n\r\n noReplceTip:\"No hay nada que reemplazar\",\r\n noMatchTip:\"No se encontraron coincidencias\",\r\n\r\n successTip:\"${xlength} elementos encontrados\",\r\n\r\n locationConstant:\"Constante\",\r\n locationFormula:\"Fórmula\",\r\n locationDate:\"Fecha\",\r\n locationDigital:\"Número\",\r\n locationString:\"Texto\",\r\n locationBool:\"Lógicos\",\r\n locationError:\"Error\",\r\n locationNull:\"Nulo\",\r\n locationCondition:\"Formato condicional\",\r\n locationRowSpan:\"Intervalo fila\",\r\n locationColumnSpan:\"Intervalo columna\",\r\n\r\n locationTiplessTwoRow:\"Selecciona al menos dos filas\",\r\n locationTiplessTwoColumn:\"Selecciona al menos dos columnas\",\r\n locationTipNotFindCell:\"Celda no encontrada\"\r\n },\r\n sheetconfig: {\r\n delete: 'Eliminar',\r\n copy: 'Copiar',\r\n rename: 'Renombrar',\r\n changeColor: 'Cambiar color',\r\n hide: 'Ocultar',\r\n unhide: 'Mostrar',\r\n moveLeft: 'Mover izquierda',\r\n moveRight: 'Mover derecja',\r\n resetColor: 'Reiniciar color',\r\n cancelText: 'Cancelar',\r\n chooseText: 'Confirmar color',\r\n\r\n tipNameRepeat:\"¡El nombre de la página de la pestaña no se puede repetir! Revísalo\",\r\n noMoreSheet:\"El libro de trabajo contiene al menos una hoja de trabajo visual. Para eliminar la hoja de trabajo seleccionada, inserta una nueva hoja de trabajo o muestra una hoja de trabajo oculta\",\r\n confirmDelete:\"¿Estás seguro de eliminar\",\r\n redoDelete:\"Se puede deshacer con Ctrl+Z\",\r\n noHide:\"No se puede ocultar, al menos conserva una etiqueta de hoja\",\r\n chartEditNoOpt:\"¡Esta operación no está permitida en el modo de edición de gráficos!\",\r\n sheetNameSpecCharError:\"El nombre no puede contener:[ ] : \\ ? * / ' \\\"\",\r\n sheetNamecannotIsEmptyError:\"El nombre de la hoja no puede estar vacío\"\r\n },\r\n conditionformat: {\r\n conditionformat_greaterThan: 'Conditionformat-GreaterThan',\r\n conditionformat_greaterThan_title: 'Dar formato a celdas mayores que',\r\n conditionformat_lessThan: 'Conditionformat-LessThan',\r\n conditionformat_lessThan_title: 'Dar formato a celdas más pequeñas que',\r\n conditionformat_betweenness: 'Conditionformat-Betweenness',\r\n conditionformat_betweenness_title: 'Dar formato a celdas con valores entre',\r\n conditionformat_equal: 'Conditionformat-Equal',\r\n conditionformat_equal_title: 'Dar formato a celdas iguales a',\r\n conditionformat_textContains: 'Conditionformat-TextContains',\r\n conditionformat_textContains_title: 'Dar formato a las celdas que contienen el siguiente texto',\r\n conditionformat_occurrenceDate: 'Conditionformat-OccurrenceDate',\r\n conditionformat_occurrenceDate_title: 'Dar formato a celdas que contienen las siguientes fechas',\r\n conditionformat_duplicateValue: 'Conditionformat-DuplicateValue',\r\n conditionformat_duplicateValue_title: 'Dar formato a celdas que contienen los siguientes tipos de valores',\r\n conditionformat_top10: 'Conditionformat-Top10',\r\n conditionformat_top10_percent: 'Conditionformat-Top10%',\r\n conditionformat_top10_title: 'Formatea las celdas con el valor más alto',\r\n conditionformat_last10: 'Conditionformat-Last10',\r\n conditionformat_last10_percent: 'Conditionformat-Last10%',\r\n conditionformat_last10_title: 'Formatea las celdas con el valor más pequeño',\r\n conditionformat_AboveAverage: 'Conditionformat-AboveAverage',\r\n conditionformat_AboveAverage_title: 'Dar formato a celdas por encima del promedio',\r\n conditionformat_SubAverage: 'Conditionformat-SubAverage',\r\n conditionformat_SubAverage_title: 'Dar formato a celdas por debajo del promedio',\r\n rule: 'Regla',\r\n newRule: 'Nueva regla',\r\n editRule: 'Editar regla',\r\n deleteRule: 'Eliminar regla',\r\n deleteCellRule: 'Eliminar regla de celda',\r\n deleteSheetRule: 'Eliminar regla de hoja',\r\n manageRules: 'Reglas administración',\r\n showRules: 'Muestra sus reglas de formato',\r\n highlightCellRules: 'Resaltar reglas de celda',\r\n itemSelectionRules: 'Reglas de selección de elementos',\r\n conditionformatManageRules: 'Administrador de reglas de formato condicional',\r\n format: 'Formatear',\r\n setFormat: 'Establecer formato',\r\n setAs: 'Establecer como',\r\n setAsByArea: 'Para el área seleccionada, establecer',\r\n applyRange: 'Aplicar rango',\r\n selectRange: 'Seleccionar rango de aplicación',\r\n selectRange_percent: 'Porcentaje del rango seleccionado',\r\n selectRange_average: 'Valor promedio del rango seleccionado',\r\n selectRange_value: 'Valor en el rango seleccionado',\r\n pleaseSelectRange: 'Selecciona el rango de aplicación',\r\n selectDataRange: 'Seleccionar rango de datos',\r\n selectCell: 'seleccionar celda',\r\n pleaseSelectCell: 'Selecciona una celda',\r\n pleaseSelectADate: 'Selecciona una fecha',\r\n pleaseEnterInteger: 'Introduzca un número entero entre 1 y 1000',\r\n onlySingleCell: 'Solo se puede hacer referencia a una sola celda',\r\n conditionValueCanOnly: 'El valor de la condición solo puede ser un número o una sola celda',\r\n ruleTypeItem1: 'Aplicar formato a todas las celdas según sus valores respectivos',\r\n ruleTypeItem2: 'Solo formatear celdas que contengan',\r\n ruleTypeItem2_title: 'Solo para celdas que cumplan las siguientes condiciones',\r\n ruleTypeItem3: 'Aplicar formato solo a los números superiores o inferiores',\r\n ruleTypeItem3_title: 'Es el valor en la siguiente clasificación',\r\n ruleTypeItem4: 'Aplicar formato solo a los valores superiores o inferiores al promedio',\r\n ruleTypeItem4_title: 'Es un valor que cumple las siguientes condiciones',\r\n ruleTypeItem5: 'Aplicar formato solo a valores únicos o repetidos',\r\n ruleTypeItem6: 'Use fórmulas para determinar qué celdas formatear',\r\n formula: 'fórmula',\r\n textColor: 'Color Texto',\r\n cellColor: 'Color Celda',\r\n confirm: 'Confirma',\r\n confirmColor: 'Confirma color',\r\n cancel: 'Cancela',\r\n close: 'Cierra',\r\n clearColorSelect: 'Limpiar selección de color',\r\n sheet: 'Hoja',\r\n currentSheet: 'Hoja actual',\r\n dataBar: 'Barra de datos',\r\n dataBarColor: 'Color barra de datos',\r\n gradientDataBar_1: 'Barra de datos de degradado azul-blanco',\r\n gradientDataBar_2: 'Barra de datos de degradado verde-blanco',\r\n gradientDataBar_3: 'Barra de datos de degradado rojo-blanco',\r\n gradientDataBar_4: 'Rayas de degradado de color naranja-blanco',\r\n gradientDataBar_5: 'Rayas de degradado azul claro-blancas',\r\n gradientDataBar_6: 'Barra de datos de degradado púrpura-blanco',\r\n solidColorDataBar_1: 'Barra de datos azul',\r\n solidColorDataBar_2: 'Barra de datos verde',\r\n solidColorDataBar_3: 'Barra de datos roja',\r\n solidColorDataBar_4: 'Barra de datos naranja',\r\n solidColorDataBar_5: 'Barra de datos azul claro',\r\n solidColorDataBar_6: 'Barra de datos púrpura',\r\n colorGradation: 'Degradado de color',\r\n colorGradation_1: 'Gradación de color verde-amarillo-rojo',\r\n colorGradation_2: 'Gradación de color rojo-amarillo-verde',\r\n colorGradation_3: 'Gradación de color verde-blanco-rojo',\r\n colorGradation_4: 'Gradación de color rojo-blanco-verde',\r\n colorGradation_5: 'Gradación de color azul-blanco-rojo',\r\n colorGradation_6: 'Gradación de color rojo-blanco-azul',\r\n colorGradation_7: 'Gradación de color blanco-rojo',\r\n colorGradation_8: 'Gradación de color rojo-blanco',\r\n colorGradation_9: 'Gradación de color verde-blanco',\r\n colorGradation_10: 'Gradación de color blanco-verde',\r\n colorGradation_11: 'Gradación de color verde-amarillo',\r\n colorGradation_12: 'Gradación de color amarillo-verde',\r\n icons: 'iconos',\r\n pleaseSelectIcon: 'Haz clic para seleccionar un grupo de iconos:',\r\n cellValue: 'Valor de celda',\r\n specificText: 'Texto específico',\r\n occurrence: 'Fecha',\r\n greaterThan: 'Mayor que',\r\n lessThan: 'Menor que',\r\n between: 'Entre',\r\n equal: 'Igual',\r\n in: 'En',\r\n between2: '',\r\n contain: 'Contiene',\r\n textContains: 'Texto contiene',\r\n duplicateValue: 'Valor duplicado',\r\n uniqueValue: 'Valor Unico',\r\n top: 'Mejor',\r\n top10: '10 mejores',\r\n top10_percent: '10% mejores',\r\n last: 'Ultimo',\r\n last10: 'Ultimos 10',\r\n last10_percent: 'Ultimos 10%',\r\n oneself: '',\r\n above: 'Encima',\r\n aboveAverage: 'Encima media',\r\n below: 'Debajo',\r\n belowAverage: 'Debajo media',\r\n all: 'Todos',\r\n yesterday: 'Año a fecha',\r\n today: 'Hoy',\r\n tomorrow: 'Mañana',\r\n lastWeek: 'Ultima semana',\r\n thisWeek: 'Esta semana',\r\n lastMonth: 'Ultimo mes',\r\n thisMonth: 'Este mes',\r\n lastYear: 'Ultimo año',\r\n thisYear: 'Este año',\r\n last7days: 'Ultimos 7 días',\r\n last30days: 'Ultimos 30 días',\r\n next7days: 'Siguientes 7 días',\r\n next30days: 'Siguientes 30 días',\r\n next60days: 'Siguientes 60 días',\r\n chooseRuleType: 'Elige el tipo de regla',\r\n editRuleDescription: 'Editar descripción de regla',\r\n newFormatRule: 'Nueva regla de formato',\r\n editFormatRule: 'Editar regla de formato',\r\n formatStyle: 'Estilo',\r\n fillType: 'Rellenar',\r\n color: 'Color',\r\n twocolor: 'Dos colores',\r\n tricolor: 'Tricolor',\r\n multicolor: 'Multi color',\r\n grayColor: 'Color gris',\r\n gradient: 'Gradiente',\r\n solid: 'Sólido',\r\n maxValue: 'Valor máximo',\r\n medianValue: 'Valor mediano',\r\n minValue: 'Valor mínimo',\r\n direction: 'Dirección',\r\n threeWayArrow: 'Flecha de tres direcciones',\r\n fourWayArrow: 'Flecha de cuatro direcciones',\r\n fiveWayArrow: 'Flecha de cinco direcciones',\r\n threeTriangles: 'Tres triángulos',\r\n shape: 'Forma',\r\n threeColorTrafficLight: 'Semáforo de tres colores',\r\n fourColorTrafficLight: 'Semáforo de cuatro colores',\r\n threeSigns: 'Tres signos',\r\n greenRedBlackGradient: 'Gradiente verde-rojo-negro',\r\n rimless: 'Sin aros',\r\n bordered: 'Bordeado',\r\n mark: 'Marcar',\r\n threeSymbols: 'Tres símbolos',\r\n tricolorFlag: 'Bandera tricolor',\r\n circled: 'Rodeado',\r\n noCircle: 'Sin círculo',\r\n grade: 'Grado',\r\n grade4: '4 Grado',\r\n grade5: '5 Grado',\r\n threeStars: '3 Estrellas',\r\n fiveQuadrantDiagram: 'Diagrama de cinco cuadrantes',\r\n fiveBoxes: '5 Cajas',\r\n },\r\n dataVerification: {\r\n cellRange: 'Rango celdas',\r\n selectCellRange: 'Haz clic para seleccionar un rango de celdas',\r\n selectCellRange2: 'Selecciona un rango de celdas',\r\n verificationCondition: 'Condición de verificación',\r\n dropdown: 'lista desplegable',\r\n checkbox: 'Casilla de verificación',\r\n number: 'Número',\r\n number_integer: 'Número entero',\r\n number_decimal: 'Número decimal',\r\n text_content: 'Contenido texto',\r\n text_length: 'Longitud texto',\r\n date: 'Fecha',\r\n validity: 'Eficacia',\r\n placeholder1: 'Introduce las opciones, separadas por comas, como 1,2,3,4,5',\r\n placeholder2: 'Introduce contenido',\r\n placeholder3: 'Valor numérico, como 10',\r\n placeholder4: 'Introduce el texto especificado',\r\n placeholder5: 'Introduce el mensaje que se muestra cuando se selecciona la celda',\r\n selected: 'Seleccionado',\r\n notSelected: 'No seleccionado',\r\n between: 'Entre',\r\n notBetween: 'No entre',\r\n equal: 'Iqual',\r\n notEqualTo: 'No iqual a',\r\n moreThanThe: 'Más que el',\r\n lessThan: 'Menos que',\r\n greaterOrEqualTo: 'Mayor o igual a',\r\n lessThanOrEqualTo: 'Menor o igual a',\r\n include: 'Incluir',\r\n exclude: 'Excluir',\r\n earlierThan: 'Antes de',\r\n noEarlierThan: 'No antes de',\r\n laterThan: 'Después de',\r\n noLaterThan: 'No después de',\r\n identificationNumber: 'Número de identificación',\r\n phoneNumber: 'Número de teléfono',\r\n remote: 'Opción de adquisición remota automática',\r\n prohibitInput: 'Prohibir la entrada cuando los datos de entrada no son válidos',\r\n hintShow: 'Mostrar mensaje cuando se selecciona la celda',\r\n deleteVerification: 'Eliminar verificación',\r\n tooltipInfo1: 'La opción de la lista desplegable no puede estar vacía',\r\n tooltipInfo2: 'El contenido de la casilla de verificación no puede estar vacío',\r\n tooltipInfo3: 'El valor ingresado no es un tipo numérico',\r\n tooltipInfo4: 'El segundo valor no puede ser menor que el primero',\r\n tooltipInfo5: 'El contenido del texto no puede estar vacío',\r\n tooltipInfo6: 'El valor ingresado no es una fecha',\r\n tooltipInfo7: 'La segunda fecha no puede ser menor que la primera',\r\n },\r\n formula:{\r\n sum:\"Suma\",\r\n average:\"Media\",\r\n count:\"Contar\",\r\n max:\"Máx\",\r\n min:\"Mín\",\r\n ifGenerate:\"Generador de fórmula SI\",\r\n find:\"Aprender más\",\r\n\r\n tipNotBelongToIf: \"¡Esta función de celda no pertenece a la fórmula SI!\",\r\n tipSelectCell: \"Selecciona la celda para insertar la función\",\r\n\r\n ifGenCompareValueTitle:\"Valor de comparación\",\r\n ifGenSelectCellTitle:\"Haz click para seleccionar una celda\",\r\n ifGenRangeTitle:\"Rango\",\r\n ifGenRangeTo:\"a\",\r\n ifGenRangeEvaluate:\"Evaluar rango\",\r\n ifGenSelectRangeTitle:\"Haz click para seleccionar rango\",\r\n ifGenCutWay:\"Forma particionado\",\r\n ifGenCutSame:\"Mismo valor de particionado\",\r\n ifGenCutNpiece:\"Particionar por N\",\r\n ifGenCutCustom:\"Personalizado\",\r\n ifGenCutConfirm:\"Confirma\",\r\n\r\n ifGenTipSelectCell:\"Selecciona celdas\",\r\n ifGenTipSelectCellPlace:\"Por favor selecciona celdas\",\r\n\r\n ifGenTipSelectRange:\"Selecciona rango\",\r\n ifGenTipSelectRangePlace:\"Por favor selecciona rango\",\r\n\r\n ifGenTipNotNullValue:\"El valor de comparación no puede ser vacío!\",\r\n ifGenTipLableTitile:\"Etiqueta\",\r\n ifGenTipRangeNotforNull:\"El rango no puede quedar vacío!\",\r\n ifGenTipCutValueNotforNull:\"El valor de partición no puede ser vacío!\",\r\n ifGenTipNotGenCondition:\"No hay condiciones disponibles para la generación!\",\r\n },\r\n formulaMore:{\r\n valueTitle:\"Valor\",\r\n tipSelectDataRange:\"Selecciona rango de datos\",\r\n tipDataRangeTile:\"Rango de datos\",\r\n findFunctionTitle:\"Función de búsqueda\",\r\n tipInputFunctionName:\"Nombre o breve descripción de la función\",\r\n\r\n \"Array\":\"Vector\",\r\n \"Database\":\"Base de datos\",\r\n \"Date\":\"Fecha\",\r\n \"Engineering\":\"Ingeniería\",\r\n \"Filter\":\"Filtro\",\r\n \"Financial\":\"Financiero\",\r\n \"luckysheet\":\"Luckysheet\",\r\n \"other\":\"Otro\",\r\n \"Logical\":\"Lógica\",\r\n \"Lookup\":\"Búsqueda\",\r\n \"Math\":\"Matemático\",\r\n \"Operator\":\"Operadores\",\r\n \"Parser\":\"Compilador\",\r\n \"Statistical\":\"Estadístico\",\r\n \"Text\":\"Texto\",\r\n \"dataMining\":\"Minería de datos\",\r\n\r\n \"selectFunctionTitle\":\"Selecciona una función\",\r\n \"calculationResult\":\"Resultado\",\r\n\r\n tipSuccessText:\"Exito\",\r\n tipParamErrorText:\"Parámetro erróneo\",\r\n\r\n \"helpClose\":\"Cerrar\",\r\n \"helpCollapse\":\"Recoger\",\r\n \"helpExample\":\"Ejemplo\",\r\n \"helpAbstract\":\"Resumen\",\r\n\r\n \"execfunctionError\":'Error en la fórmula',\r\n \"execfunctionSelfError\":'La fórmula no puede hacer referencia a su propia celda',\r\n \"execfunctionSelfErrorResult\":'La fórmula no puede hacer referencia a su propia celda, lo que dará lugar a resultados de cálculo inexactos',\r\n\r\n \"allowRepeatText\":\"Repetir\",\r\n \"allowOptionText\":\"Opción\",\r\n\r\n \"selectCategory\":\"O selecciona una categoría\",\r\n },\r\n drag:{\r\n noMerge: \"No se puede realizar esta operación en celdas combinadas\",\r\n afectarPivot: \"¡Este cambio no se puede realizar en la celda seleccionada porque afectará a la tabla dinámica!\",\r\n noMulti: \"No se puede realizar esta operación en varias áreas de selección, selecciona una sola área\",\r\n noPaste: \"No se puede pegar este contenido aquí, selecciona una celda en el área de pegado e intenta pegar nuevamente\",\r\n noPartMerge: \"No se puede realizar esta operación en celdas parcialmente fusionadas\",\r\n\r\n inputCorrect:\"Introduce el valor correcto\",\r\n notLessOne:\"El número de filas y columnas no puede ser inferior a 1\",\r\n offsetColumnLessZero:\"¡La columna de desplazamiento no puede ser negativa!\",\r\n\r\n pasteMustKeybordAlert:\"在表格中进行复制粘贴: Ctrl + C 进行复制, Ctrl + V 进行粘贴, Ctrl + X 进行剪切\",\r\n pasteMustKeybordAlertHTMLTitle:\"在表格中进行复制粘贴\",\r\n pasteMustKeybordAlertHTML:\"Ctrl + C  进行复制
Ctrl + V  进行粘贴
Ctrl + X  进行剪切\",\r\n },\r\n pivotTable:{\r\n title:\"Tabla Dinámica\",\r\n closePannel:\"Cerrar\",\r\n editRange:\"Rango\",\r\n tipPivotFieldSelected:\"Selecciona los campos\",\r\n tipClearSelectedField:\"Limpiar todos los campos\",\r\n btnClearSelectedField:\"Limpiar\",\r\n btnFilter:\"Filtrar\",\r\n titleRow:\"Fila\",\r\n titleColumn:\"Columna\",\r\n titleValue:\"Valor\",\r\n tipShowColumn: \"Los campos de estadísticas se muestran como columnas\",\r\n tipShowRow: \"Los campos de estadísticas se muestran como filas\",\r\n\r\n titleSelectionDataRange:\"Selecciona rango\",\r\n titleDataRange:\"Rango de datos\",\r\n\r\n valueSum:\"SUMA\",\r\n\r\n valueStatisticsSUM:\"Suma\",\r\n valueStatisticsCOUNT:\"Contar\",\r\n valueStatisticsCOUNTA:\"Contar A\",\r\n valueStatisticsCOUNTUNIQUE:\"Contar Distintos\",\r\n valueStatisticsAVERAGE:\"Media\",\r\n valueStatisticsMAX:\"Máx\",\r\n valueStatisticsMIN:\"Mín\",\r\n valueStatisticsMEDIAN:\"Mediana\",\r\n valueStatisticsPRODUCT:\"Producto\",\r\n valueStatisticsSTDEV:\"Desviación Estándar\",\r\n\r\n valueStatisticsSTDEVP:\"Stdevp\",\r\n valueStatisticslet:\"Varianza\",\r\n valueStatisticsVARP:\"VarP\",\r\n\r\n errorNotAllowEdit: \"¡Esta operación está prohibida en el modo sin edición!\",\r\n errorNotAllowMulti: \"No se puede realizar esta operación en varias áreas de selección, selecciona un solo rango y vuelve a intentarlo\",\r\n errorSelectRange: \"Seleccione el rango de la nueva tabla dinámica\",\r\n errorIsDamage: \"¡Los datos de origen de esta tabla dinámica están dañados!\",\r\n errorNotAllowPivotData: \"¡No se puede seleccionar la tabla dinámica como datos de origen!\",\r\n errorSelectionRange: \"¡La selección falló, rango de entrada incorrecto!\",\r\n errorIncreaseRange: \"¡Por favor, expande el rango seleccionado!\",\r\n\r\n titleAddColumn:\"Añadir columna a la tabla dinámica\",\r\n titleMoveColumn:\"Muever la columna a la celda en blanco de abajo\",\r\n titleClearColumnFilter:\"Quitar el filtro de esta columna\",\r\n titleFilterColumn:\"Filtro\",\r\n\r\n titleSort:\"Ordenar\",\r\n titleNoSort:\"No Ordenar\",\r\n titleSortAsc:\"ASC\",\r\n titleSortDesc:\"DESC\",\r\n titleSortBy:\"Ordenar por\",\r\n titleShowSum:\"Mostrar total\",\r\n titleStasticTrue:\"Sí\",\r\n titleStasticFalse:\"No\",\r\n },\r\n dropCell:{\r\n copyCell:\"Copiar\",\r\n sequence:\"Secuencia\",\r\n onlyFormat:\"Solo formato\",\r\n noFormat:\"Sin formato\",\r\n day:\"Día\",\r\n workDay:\"Día Laborable\",\r\n month:\"Mes\",\r\n year:\"Año\",\r\n chineseNumber:\"Números Chinos\",\r\n },\r\n imageCtrl:{\r\n borderTile:\"Color de borde de imagen\",\r\n borderCur:\"Color\",\r\n },\r\n protection:{\r\n protectiontTitle:\"Protección\",\r\n enterPassword:\"Introduce una contraseña (opcional)\",\r\n enterHintTitle:\"Preguntar cuando la edición está prohibida (opcional)\",\r\n enterHint:\"La celda o el gráfico que estás intentando cambiar se encuentra en una hoja de trabajo protegida. Si quieres cambiarlo, desprotege la hoja de trabajo. Es posible que tengas que ingresar una contraseña\",\r\n swichProtectionTip:\"Protege la hoja y el contenido de las celdas bloqueadas\",\r\n authorityTitle:\"Permitir a los usuarios de esta hoja:\",\r\n selectLockedCells:\"Selecciona celdas bloqueadas\",\r\n selectunLockedCells:\"Selecciona celdas desbloqueadas\",\r\n formatCells:\"Formatear celdas\",\r\n formatColumns:\"Formatear columnas\",\r\n formatRows:\"Formatear filas\",\r\n insertColumns:\"Insertar columnas\",\r\n insertRows:\"Insertar filas\",\r\n insertHyperlinks:\"Insertar enlaces\",\r\n deleteColumns:\"Eliminar columnas\",\r\n deleteRows:\"Eliminar filas\",\r\n sort:\"Ordenar\",\r\n filter:\"Filtrar\",\r\n usePivotTablereports:\"Usar informes de tabla dinámica\",\r\n editObjects:\"Editar objetos\",\r\n editScenarios:\"Editar escenarios\",\r\n\r\n allowRangeTitle:\"Permitir a los usuarios del rango:\",\r\n allowRangeAdd:\"Nuevo...\",\r\n\r\n allowRangeAddTitle:\"Título\",\r\n allowRangeAddSqrf:\"Referencia\",\r\n selectCellRange: 'Haz clic para seleccionar un rango de celdas',\r\n selectCellRangeHolder:\"Rango de celdas\",\r\n allowRangeAddTitlePassword:\"Contraseña\",\r\n allowRangeAddTitleHint:\"Pregunta\",\r\n allowRangeAddTitleHintTitle:\"Preguntar cuando hay una contraseña (opcional)\",\r\n allowRangeAddtitleDefault:\"Nombre del rango de entrada\",\r\n\r\n rangeItemDblclick:\"Haz doble clic para editar\",\r\n rangeItemHasPassword:\"Tiene contraseña\",\r\n\r\n rangeItemErrorTitleNull:\"El título es nulo\",\r\n rangeItemErrorRangeNull:\"La referencia es nula\",\r\n rangeItemErrorRange:\"La reference tiene un error\",\r\n\r\n validationTitle:\"Validación de contraseña\",\r\n validationTips:\"Hay que ingresar una contraseña para desbloquear la protección de la hoja de trabajo\",\r\n validationInputHint:\"Introduce una contraseña\",\r\n\r\n checkPasswordNullalert:\"Contraseña requerida!\",\r\n checkPasswordWrongalert:\"¡Contraseña incorrecta. Por favor, prueba de nuevo!\",\r\n\r\n checkPasswordSucceedalert:\"Desbloqueo conseguido!\",\r\n defaultRangeHintText:\"La celda está protegida con contraseña.\",\r\n defaultSheetHintText:\"La celda o el gráfico están en una hoja de trabajo protegida. Para realizar cambios, desprotege la hoja de trabajo. Es posible que tengas que ingresar una contraseña\",\r\n },\r\n cellFormat:{\r\n cellFormatTitle:\"Formatear celdas\",\r\n protection:\"Protección\",\r\n locked:\"Bloqueado\",\r\n hidden:\"Escondido\",\r\n protectionTips:\"Para bloquear celdas u ocultar fórmulas, protege la hoja de trabajo. En la barra de herramientas, haz clic en el botón Proteger hoja\",\r\n tipsPart:\"Comprobado parcial\",\r\n tipsAll:\"Todo seleccionado\",\r\n\r\n selectionIsNullAlert:\"Se requiere una selección!\",\r\n sheetDataIsNullAlert:\"error, no hay datos!\",\r\n\r\n },\r\n print:{\r\n normalBtn:\"Normal\",\r\n layoutBtn:\"Disposición de página\",\r\n pageBtn:\"Previsualización de saltos de página\",\r\n\r\n menuItemPrint:\"Imprimir (Ctrl+P)\",\r\n menuItemAreas:\"Imprimir áreas\",\r\n menuItemRows:\"Imprimir títulos de filas\",\r\n menuItemColumns:\"Imprimir títulos de columnas\",\r\n },\r\n edit:{\r\n typing:\"mecanografía\",\r\n },\r\n websocket:{\r\n success: 'Éxito de la conexión de WebSocket',\r\n refresh: 'Se produjo un error en la conexión de WebSocket, ¡actualice la página!',\r\n wait: 'Se produjo un error en la conexión de WebSocket, ¡tenga paciencia!',\r\n close: 'Conexión WebSocket cerrada',\r\n contact: 'Ocurrió un error de comunicación con el servidor, actualice la página y vuelva a intentarlo; de lo contrario, comuníquese con el administrador.',\r\n support: 'El navegador actual no es compatible con WebSocket',\r\n }\r\n };","export default {\r\n functionlist: [{\r\n 'n': 'SUMIF',\r\n 't': 0,\r\n 'd': '對範圍中符合指定條件的值求和。',\r\n 'a': '對範圍中符合指定條件的值求和。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : '範圍',\r\n 'detail' : '要根據條件進行檢測的範圍。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : '條件',\r\n 'detail' : '要應用於範圍的模式或測試條件。\\n\\n如果範圍包含的是要檢測的文字,則條件必須為字串。條件可以包含萬用字元,包括用於匹配單個字元的?或用於匹配零個或連續多個字元的*。要匹配問號星號本身,請在該字元前面加上波浪號(~)首碼(即~?和~*)。字串條件必須用引號括起來。函數會檢查範圍中的每個儲存格與條件是否相等或匹配(如果使用了萬用字元)。\\n\\n如果範圍包含的是要檢測的數位,則條件可以是字串也可以是數位。如果給定的條件是一個數位,則檢查範圍中的每個儲存格是否等於條件。另外,條件也可能是包含數位的字串(也將對其進行相等檢測),或者帶有以下首碼的數位:=(檢查是否相等)、>(檢查範圍儲存格的值是否大於條件值)或<(檢查範圍儲存格的值是否小於條件值)',\r\n 'example': '\">20\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '求和範圍',\r\n 'detail' : '要求和的範圍(如果與範圍不同)。',\r\n 'example': 'B1:B10',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'TAN',\r\n 't': 0,\r\n 'd': '返回已知角度的正切值。',\r\n 'a': '返回已知角度的正切值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '角度',\r\n 'detail' : '要求其正切值的角度,以弧度表示。',\r\n 'example': '45*PI()/180',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TANH',\r\n 't': 0,\r\n 'd': '返回給定實數的雙曲正切值。',\r\n 'a': '返回給定實數的雙曲正切值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其雙曲正切值的實數。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CEILING',\r\n 't': 0,\r\n 'd': '將數值向上取整為最接近的指定因數的倍數。',\r\n 'a': '將數值向上取整為最接近的指定因數的倍數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要向上舍入的數值。',\r\n 'example': '23.25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '因數',\r\n 'detail' : '要將值舍入到此數的整數倍。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ATAN',\r\n 't': 0,\r\n 'd': '返回數值的反正切值,以弧度表示。',\r\n 'a': '返回數值的反正切值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其反正切值的數值。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ASINH',\r\n 't': 0,\r\n 'd': '返回數值的反雙曲正弦值。',\r\n 'a': '返回數值的反雙曲正弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其反雙曲正弦值的數值。',\r\n 'example': '0.9',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ABS',\r\n 't': 0,\r\n 'd': '返回數值的絕對值。',\r\n 'a': '返回數值的絕對值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要返回其絕對值的數。',\r\n 'example': '-2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ACOS',\r\n 't': 0,\r\n 'd': '返回數值的反余弦值,以弧度表示。',\r\n 'a': '返回數值的反余弦值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其反余弦值的數值。必須介於-1和1之間,包括兩端值。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ACOSH',\r\n 't': 0,\r\n 'd': '返回數值的反雙曲余弦值。',\r\n 'a': '返回數值的反雙曲余弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其反雙曲余弦值的數值。必須大於等於1。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MULTINOMIAL',\r\n 't': 0,\r\n 'd': '返回參數和的階乘除以各參數階乘的乘積後得到的值。',\r\n 'a': '返回參數和的階乘除以各參數階乘的乘積後得到的值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '用於計算的第一項數值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '用於計算的其他數值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ATANH',\r\n 't': 0,\r\n 'd': '返回數值的反雙曲正切值。',\r\n 'a': '返回數值的反雙曲正切值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其反雙曲正切值的數值。必須介於-1和1之間(不包括-1和1)。',\r\n 'example': '0.9',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ATAN2',\r\n 't': 0,\r\n 'd': '以弧度為組織返回x軸與從原點(0,0)到指定座標點(`x`,`y`)之間連線的夾角。',\r\n 'a': '以弧度為組織返回x軸與從原點(0,0)到指定座標點(`x`,`y`)之間連線的夾角。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '要計算其與x軸夾角大小的線段的終點x座標。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'y',\r\n 'detail' : '要計算其與x軸夾角大小的線段的終點y座標。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUNTBLANK',\r\n 't': 1,\r\n 'd': '返回給定範圍內的空儲存格數。',\r\n 'a': '返回給定範圍內的空儲存格數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '範圍',\r\n 'detail' : '要統計空白儲存格數量的範圍。',\r\n 'example': 'A2:C100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'COSH',\r\n 't': 0,\r\n 'd': '返回給定實數的雙曲余弦值。',\r\n 'a': '返回給定實數的雙曲余弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其雙曲余弦值的實數值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'INT',\r\n 't': 0,\r\n 'd': '數值向下取整為小於或等於該數的最接近的整數。',\r\n 'a': '數值向下取整為小於或等於該數的最接近的整數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要向下取整為最接近的整數的數值。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ISEVEN',\r\n 't': 0,\r\n 'd': '檢查所提供的數值是否為偶數。',\r\n 'a': '檢查所提供的數值是否為偶數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要驗證其是否為偶數的數值。\\n\\n如果值為偶數或指向包含偶數的儲存格的引用,ISEVEN將返回TRUE,否則返回FALSE。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ISODD',\r\n 't': 0,\r\n 'd': '檢查所提供的數值是否為奇數。',\r\n 'a': '檢查所提供的數值是否為奇數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要驗證其是否為奇數的數值。\\n\\n如果值為奇數或指向包含奇數的儲存格,ISODD將返回TRUE,否則返回FALSE。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LCM',\r\n 't': 0,\r\n 'd': '返回一個或多個整數的最小公倍數。',\r\n 'a': '返回一個或多個整數的最小公倍數。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '要在求最小公倍數數的計算中檢查其因數的第一項數值或範圍。',\r\n 'example': 'A2:A5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 在求最小公倍數時要考慮其因數的其他數值或範圍。',\r\n 'example': '3',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LN',\r\n 't': 0,\r\n 'd': '返回數值以e(歐拉數)為底的對數。',\r\n 'a': '返回數值以e(歐拉數)為底的對數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要以e為底數計算其對數的值。\\n\\n值必須為正數。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOG',\r\n 't': 0,\r\n 'd': '根據指定底數返回數位的對數。',\r\n 'a': '根據指定底數返回數位的對數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '想要計算其對數的正實數。',\r\n 'example': '128',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '底數',\r\n 'detail' : '[可選] - 對數的底數。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOG10',\r\n 't': 0,\r\n 'd': '返回數值以10為底的對數。',\r\n 'a': '返回數值以10為底的對數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其以10為底的對數的數值。\\n\\n值必須為正值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MOD',\r\n 't': 0,\r\n 'd': '返回兩數相除的餘數,結果的符號與除數相同。',\r\n 'a': '返回兩數相除的餘數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '被除數',\r\n 'detail' : '要將其相除以得到餘數的數值。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '除數',\r\n 'detail' : '用於除其他數的數值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MROUND',\r\n 't': 0,\r\n 'd': '將數值取整為另一整數最接近的整數倍。',\r\n 'a': '將數值取整為另一整數最接近的整數倍。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要取整為另一整數最接近的整數倍的數值。',\r\n 'example': '21',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '因數',\r\n 'detail' : '值將取此因數的整數倍。',\r\n 'example': '14',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ODD',\r\n 't': 0,\r\n 'd': '將數值向上取整為最接近的奇整數。',\r\n 'a': '將數值向上取整為最接近的奇整數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要向上取整的數值,取整值為大於此值的最接近的奇數。\\n\\n如果值為負數,則將其取整為絕對值大於該值的相鄰負奇數',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMSQ',\r\n 't': 0,\r\n 'd': '返回一組數值和/或儲存格的平方總和。',\r\n 'a': '返回一組數值和/或儲存格的平方總和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '要將其平方相加的第一個數值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 要將其平方與值1的平方相加的其他數值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COMBIN',\r\n 't': 0,\r\n 'd': '給定集合中的對象總數和要選擇的對象數量,返回共有多少種不同選擇管道。',\r\n 'a': '給定集合中的對象總數和要選擇的對象數量',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'n',\r\n 'detail' : '要從中進行選擇的對象集合的大小。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'k',\r\n 'detail' : '要選擇的對象數量。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUM',\r\n 't': 0,\r\n 'd': '返回一組數值和/或儲存格的總和。',\r\n 'a': '返回一組數值和/或儲存格的總和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '要相加的第一個數值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 要相加的其他數值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'SUBTOTAL',\r\n 't': 0,\r\n 'd': '使用指定的匯總函數,返回一系列縱向儲存格的分類匯總。',\r\n 'a': '使用指定的匯總函數',\r\n 'm': [2, 256],\r\n 'p': [{\r\n 'name' : '函數程式碼',\r\n 'detail' : '用於計算分類匯總的函數。\\n\\n1代表AVERAGE\\n\\n2代表COUNT\\n\\n3代表COUNTA\\n\\n4代表MAX\\n\\n5代表MIN\\n\\n6代表PRODUCT\\n\\n7代表STDEV\\n\\n8代表STDEVP\\n\\n9代表SUM\\n\\n10代表VAR\\n\\n11代表VARP\\n\\n通過在這些2位程式碼前附加10(對於1位程式碼)或1(對於2位程式碼),可以將隱藏值忽略。例如,102代表忽略隱藏儲存格的COUNT,而110則代表忽略隱藏值的VAR。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '範圍1',\r\n 'detail' : '要計算分類匯總的第一個範圍。',\r\n 'example': 'A2:A5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : '範圍2',\r\n 'detail' : '[可選] - 要計算分類匯總的其他範圍。',\r\n 'example': 'B2:B8',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'ASIN',\r\n 't': 0,\r\n 'd': '返回數值的反正弦值,以弧度表示。',\r\n 'a': '返回數值的反正弦值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其反正弦值的數值。必須介於-1和1之間,包括兩端值。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUNTIF',\r\n 't': 1,\r\n 'd': '返回範圍內滿足某個條件的儲存格的數量。',\r\n 'a': '返回範圍內滿足某個條件的儲存格的數量。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '範圍',\r\n 'detail' : '要根據條件進行檢測的範圍。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : '條件',\r\n 'detail' : '要應用於範圍的模式或測試條件。\\n\\n如果範圍包含的是要檢測的文字,則條件必須為字串。條件可以包含萬用字元,包括用於匹配單個字元的?或用於匹配零個或連續多個字元的*。要匹配問號星號本身,請在該字元前面加上波浪號(~)首碼(即~?和~*)。字串條件必須用引號括起來。函數會檢查範圍中的每個儲存格與條件是否相等或匹配(如果使用了萬用字元)。\\n\\n如果範圍包含的是要檢測的數位,則條件可以是字串也可以是數位。如果給定的條件是一個數位,則檢查範圍中的每個儲存格是否等於條件。另外,條件也可能是包含數位的字串(也將對其進行相等檢測),或者帶有以下首碼的數位:=、>、>=、<或<=,這些條件將分別用於檢查範圍中的儲存格是否等於、大於、大於等於、小於、小於等於條件值。',\r\n 'example': '\">20\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RADIANS',\r\n 't': 0,\r\n 'd': '將以度表示的角度值轉換為弧度。',\r\n 'a': '將以度表示的角度值轉換為弧度。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '角度',\r\n 'detail' : '要從度轉換為弧度的角度。',\r\n 'example': '180',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RAND',\r\n 't': 0,\r\n 'd': '返回一個介於0和1之間(包括0但不包括1)的亂數。',\r\n 'a': '返回一個介於0和1之間(包括0但不包括1)的亂數。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'COUNTUNIQUE',\r\n 't': 0,\r\n 'd': '計算一列指定值和範圍中不重複數值的個數。',\r\n 'a': '計算一列指定值和範圍中不重複數值的個數。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '要檢查其是否唯一的第一個值或範圍。',\r\n 'example': 'A1:C100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 要檢查是否唯一的其他值或範圍。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DEGREES',\r\n 't': 0,\r\n 'd': '將以弧度表示的角度值轉換為度。',\r\n 'a': '將以弧度表示的角度值轉換為度。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '角度',\r\n 'detail' : '要從弧度轉換為度的角度。',\r\n 'example': 'PI()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ERFC',\r\n 't': 9,\r\n 'd': '返回數值的互補高斯誤差函數。',\r\n 'a': '返回數值的互補高斯誤差函數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'z',\r\n 'detail' : '要為其計算互補高斯誤差函數的數值。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EVEN',\r\n 't': 0,\r\n 'd': '將數值向上取整為最接近的偶整數。',\r\n 'a': '將數值向上取整為最接近的偶整數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要向上取整的數值,取整值為大於此值的最接近的偶數。\\n\\n如果值為負數,則將其取整為絕對值大於該值的相鄰負偶數。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EXP',\r\n 't': 0,\r\n 'd': '返回歐拉數e(~2.718)的指定次幂。',\r\n 'a': '返回歐拉數e(~2.718)的指定次幂。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '指數',\r\n 'detail' : '指定e的自乘幂次值。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FACT',\r\n 't': 0,\r\n 'd': '返回數值的階乘。',\r\n 'a': '返回數值的階乘。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算並返回其階乘的數位或對數位(所在儲存格)的引用。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FACTDOUBLE',\r\n 't': 0,\r\n 'd': '返回數值的\"雙階乘\"。',\r\n 'a': '返回數值的\"雙階乘\"。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算並返回其雙階乘的數位或對數位(所在儲存格)的引用。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PI',\r\n 't': 0,\r\n 'd': '返回帶有14位小數的PI值。',\r\n 'a': '返回帶有14位小數的PI值。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'FLOOR',\r\n 't': 0,\r\n 'd': '將數值向下取整為指定因數的最接近的整數倍。',\r\n 'a': '將數值向下取整為指定因數的最接近的整數倍。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要向下舍入為因數的最接近整數倍的數值。',\r\n 'example': '23.25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '因數',\r\n 'detail' : '要將值舍入到此數的整數倍。\\n\\n因數不得為0。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GCD',\r\n 't': 0,\r\n 'd': '返回一個或多個整數的最大公約數。',\r\n 'a': '返回一個或多個整數的最大公約數。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '要在查找最大公約數的計算中檢查其因數的第一項數值或範圍。',\r\n 'example': 'A2:A5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 在求最大公約數時要考慮其因數的其他數值或範圍。',\r\n 'example': '96',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANDBETWEEN',\r\n 't': 0,\r\n 'd': '返回介於兩個整數之間(包括這兩個整數)的亂數。',\r\n 'a': '返回介於兩個整數之間(包括這兩個整數)的亂數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '下界',\r\n 'detail' : '隨機值範圍的下界。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '上界',\r\n 'detail' : '隨機值範圍的上界。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ROUND',\r\n 't': 0,\r\n 'd': '將數位四捨五入到指定的位數。',\r\n 'a': '將數位四捨五入到指定的位數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要四捨五入的數位。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '位數',\r\n 'detail' : '要進行四捨五入運算的位數。\\n\\n位數可以取負值,在這種情況下會將值的小數點左側部分舍入到指定的位數。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ROUNDDOWN',\r\n 't': 0,\r\n 'd': '朝著零的方向將數位進行向下舍入。',\r\n 'a': '朝著零的方向將數位進行向下舍入。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '需要向下舍入的任意實數。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '位數',\r\n 'detail' : '要通過舍入達到的小數位數。\\n\\n位數可以取負值,在這種情況下會將值的小數點左側部分舍入到指定的位數。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ROUNDUP',\r\n 't': 0,\r\n 'd': '朝著遠離0(零)的方向將數位進行向上舍入。',\r\n 'a': '朝著遠離0(零)的方向將數位進行向上舍入。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要將其舍入為位數位數位的值,始終向上舍入。',\r\n 'example': '99.44',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '位數',\r\n 'detail' : '要通過舍入達到的小數位數。\\n\\n位數可以取負值,在這種情況下會將值的小數點左側部分舍入到指定的位數。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SERIESSUM',\r\n 't': 0,\r\n 'd': '給定參數x、n、m和a,返回幂級數的和a1xn + a2x(n+m)+…+ aix(n+(i-1)m),其中i為範圍a中的項數。',\r\n 'a': '給定參數x、n、m和a',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '幂級數的輸入值。隨相應的近似類型而變,有可能為角度、指數或其他一些值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'n',\r\n 'detail' : '在幂級數中x的初始自乘幂次。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'm',\r\n 'detail' : 'x的幂次中的附加增量。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'a',\r\n 'detail' : '包含幂級數係數的數組或範圍。',\r\n 'example': '{FACT(0)',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SIGN',\r\n 't': 0,\r\n 'd': '給定輸入數值,如果為負返回-1;如果為正返回1;如果為零則返回0。',\r\n 'a': '給定輸入數值',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要返回其符號的數值。',\r\n 'example': '-42',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SIN',\r\n 't': 0,\r\n 'd': '給定角度(以弧度表示),返回其正弦值。',\r\n 'a': '給定角度(以弧度表示)',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '角度',\r\n 'detail' : '要返回其正弦值的角度,以弧度表示。',\r\n 'example': 'PI()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SINH',\r\n 't': 0,\r\n 'd': '返回給定實數的雙曲正弦值。',\r\n 'a': '返回給定實數的雙曲正弦值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其雙曲正弦值的實數值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SQRT',\r\n 't': 0,\r\n 'd': '返回一個正數的正平方根。',\r\n 'a': '返回一個正數的正平方根。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要計算其正平方根的數值。\\n\\n值必須為正數;如果為負,SQRT將返回#NUM!錯誤。',\r\n 'example': '9',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SQRTPI',\r\n 't': 0,\r\n 'd': '返回PI與給定正數乘積的正平方根。',\r\n 'a': '返回PI與給定正數乘積的正平方根。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要將其與PI相乘並返回該乘積的平方根的數值\\n\\n值必須為正數;如果為負數,SQRTPI將返回#NUM!錯誤。',\r\n 'example': '9',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GAMMALN',\r\n 't': 1,\r\n 'd': '返回指定伽瑪函數的以e(歐拉數)為底的對數。',\r\n 'a': '返回指定伽瑪函數的以e(歐拉數)為底的對數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '伽瑪函數的輸入值。返回的將是伽瑪(值)的自然對數。\\n\\n值必須為正數。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COS',\r\n 't': 0,\r\n 'd': '返回給定角度的余弦值(角度以弧度表示)。',\r\n 'a': '返回給定角度的余弦值(角度以弧度表示)。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '角度',\r\n 'detail' : '要取其余弦值的角度,以弧度表示。',\r\n 'example': 'PI()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TRUNC',\r\n 't': 0,\r\n 'd': '除指定有效位之外的部分,取數據的指定有效位。',\r\n 'a': '除指定有效位之外的部分',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : '值',\r\n 'detail' : '要截取的數據。',\r\n 'example': '3.141592654',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '位數',\r\n 'detail' : '[可選 - 預設值為0] - 小數點右側要保留的有效位數。\\n\\n如果位數大於值中的有效位數,則將\"值\"原樣返回。\\n\\n位數可以取負值,在這種情況下會將小數點左側指定位數的值更改為零。小數點右側的所有位數都會被捨棄。如果值的所有位都被更改為零,則TRUNC會返回0。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'QUOTIENT',\r\n 't': 0,\r\n 'd': '返回以一個數除以另一個數所得的結果,不包含餘數。',\r\n 'a': '返回以一個數除以另一個數所得的結果',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '被除數',\r\n 'detail' : '要被除的數值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '除數',\r\n 'detail' : '用於除其他數的數值。\\n\\n除數不得為0',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'POWER',\r\n 't': 0,\r\n 'd': '返回數值的指定次幂。',\r\n 'a': '返回數值的指定次幂。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '底數',\r\n 'detail' : '要計算其指數次幂的數值。\\n\\n如果底數為負,則指數必須為整數。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '指數',\r\n 'detail' : '指定底數的自乘幂次值。',\r\n 'example': '0.5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMIFS',\r\n 't': 0,\r\n 'd': '根據多項條件返回範圍之和。',\r\n 'a': '根據多項條件返回範圍之和。',\r\n 'm': [3, 257],\r\n 'p': [{\r\n 'name' : '求和範圍',\r\n 'detail' : '要對其求和的範圍。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : '條件範圍1',\r\n 'detail' : '要在哪個範圍內檢查條件1。',\r\n 'example': ' B1:B10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : '條件1',\r\n 'detail' : '要應用於條件範圍1的模式或測試條件。',\r\n 'example': ' \">20\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '條件範圍2,條件2…',\r\n 'detail' : '[ 可選 ] - 要檢查的其他範圍和條件。',\r\n 'example': ' C1:C10',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COUNTIFS',\r\n 't': 1,\r\n 'd': '根據多項條件返回範圍中的儲存格數量。',\r\n 'a': '根據多項條件返回範圍中的儲存格數量。',\r\n 'm': [2, 256],\r\n 'p': [{\r\n 'name' : '條件範圍1',\r\n 'detail' : '要在哪個範圍內檢查條件1。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : '條件1',\r\n 'detail' : '要應用於條件範圍1的模式或測試條件。',\r\n 'example': ' \">20\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '條件範圍2,條件2…',\r\n 'detail' : '[ 可選 ] - 要檢查的其他範圍和條件,可重複。',\r\n 'example': ' B1:B10',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PRODUCT',\r\n 't': 0,\r\n 'd': '返回將一組數相乘所得的結果。',\r\n 'a': '返回將一組數相乘所得的結果。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '乘數1',\r\n 'detail' : '用於計算乘積的第一個數值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '乘數2 ... 乘數30',\r\n 'detail' : '[可選] - 要相乘的其他數值',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HARMEAN',\r\n 't': 1,\r\n 'd': '計算數據集的調和平均值。',\r\n 'a': '計算數據集的調和平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 數據集中包含的其他數值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HYPGEOMDIST',\r\n 't': 1,\r\n 'd': '返回超幾何分佈。如果已知樣本量、總體成功次數和總體大小,則 HYPGEOM.DIST 返回樣本取得已知成功次數的概率。',\r\n 'a': '返回超幾何分佈。',\r\n 'm': [5, 5],\r\n 'p': [{\r\n 'name' : 'Sample_s',\r\n 'detail' : '樣本中成功的次數。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'Number_sample',\r\n 'detail' : '樣本量。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'Population_s',\r\n 'detail' : '總體中成功的次數。',\r\n 'example': '20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'Number_pop',\r\n 'detail' : '總體大小。',\r\n 'example': '40',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '决定函數形式的邏輯值。\\n\\n如果cumulative為TRUE(),則HYPGEOM.DIST返回累積分佈函數;\\n\\n如果為FALSE(),則返回概率密度函數。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'INTERCEPT',\r\n 't': 1,\r\n 'd': '計算數據集的線性回歸方程直線與 Y 軸的相交點(x=0)的y值。',\r\n 'a': '計算數據集的線性回歸方程直線與 Y 軸的相交點(x=0)的y值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'KURT',\r\n 't': 1,\r\n 'd': '計算數據集的峭度,該名額訓示數據集(分佈)的形態,尤其是該形態的陡峭程度。',\r\n 'a': '計算數據集的峭度',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '數據集中的第一個值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 數據集中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LARGE',\r\n 't': 1,\r\n 'd': '返回數據集中第 n 個最大元素,n 由用戶指定。',\r\n 'a': '返回數據集中第 n 個最大元素',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據',\r\n 'detail' : '包含相關數據集的數組或範圍。',\r\n 'example': 'A2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'n',\r\n 'detail' : '要返回的元素的排行位置(從大到小順序)。\\n\\n例如,將n設為4將使LARGE返回數據中排名第4的最大元素。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STDEVA',\r\n 't': 1,\r\n 'd': '基於樣本計算標準差,將文字取值為0。',\r\n 'a': '基於樣本計算標準差',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2,…',\r\n 'detail' : '[可選] - 樣本中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STDEVP',\r\n 't': 1,\r\n 'd': '基於樣本總體計算標準差。',\r\n 'a': '基於樣本總體計算標準差。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '數據集中的第一個值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 數據集中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GEOMEAN',\r\n 't': 1,\r\n 'd': '計算數據集的幾何平均值。',\r\n 'a': '計算數據集的幾何平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 數據集中包含的其他數值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANK_EQ',\r\n 't': 1,\r\n 'd': '返回指定值在數據集中的排名。如果相同的值在數據集中存在多項,則返回其中的最高排名。',\r\n 'a': '返回指定值在數據集中的排名。如果相同的值在數據集中存在多項,則返回其中的最高排名。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要確定其排名的值。',\r\n 'example': 'A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'ref',\r\n 'detail' : '包含相關數據集的數組或範圍。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'order',\r\n 'detail' : '[可選-默認為按降序(FALSE())] - 要按昇冪還是按降序考慮\"data\"中的值。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANK_AVG',\r\n 't': 1,\r\n 'd': '返回指定值在數據集中的排名。如果相同的值在數據集中存在多項,則返回這些項排名的平均值。',\r\n 'a': '返回指定值在數據集中的排名。如果相同的值在數據集中存在多項,則返回這些項排名的平均值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要確定其排名的值。',\r\n 'example': 'A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'ref',\r\n 'detail' : '包含相關數據集的數組或範圍。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'order',\r\n 'detail' : '[可選-默認為按降序(FALSE())] - 要按昇冪還是按降序考慮\"data\"中的值。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PERCENTRANK_EXC',\r\n 't': 1,\r\n 'd': '以百分數形式返回指定值在給定數據集中的百分比排名(介於0和1之間,不包括兩端值)。',\r\n 'a': '以百分數形式返回指定值在給定數據集中的百分比排名(介於0和1之間,不包括兩端值)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'data',\r\n 'detail' : '包含相關數據集的數組或範圍。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'x',\r\n 'detail' : '要確定其百分比排位的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'significance',\r\n 'detail' : '[可選-預設值為3] - 要在計算中使用的有效位數。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PERCENTRANK_INC',\r\n 't': 1,\r\n 'd': '以百分比形式返回指定值在給定數據集中的百分比排名(介於0和1之間,包括兩端值)。',\r\n 'a': '以百分比形式返回指定值在給定數據集中的百分比排名(介於0和1之間,包括兩端值)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'data',\r\n 'detail' : '包含相關數據集的數組或範圍。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'x',\r\n 'detail' : '要確定其百分比排位的值。',\r\n 'example': ' A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'significance',\r\n 'detail' : '[可選-預設值為3] - 要在計算中使用的有效位數。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FORECAST',\r\n 't': 1,\r\n 'd': '基於數據集的線性回歸,計算指定 x 的預期 y 值。',\r\n 'a': '基於數據集的線性回歸',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : 'x軸上用於預測的值。',\r\n 'example': 'A1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FISHERINV',\r\n 't': 1,\r\n 'd': '返回指定數值的 Fisher 逆變換。',\r\n 'a': '返回指定數值的 Fisher 逆變換。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'y',\r\n 'detail' : '要計算其Fisher逆變換的數值。',\r\n 'example': '0.962',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FISHER',\r\n 't': 1,\r\n 'd': '返回指定數值的 Fisher 變換。',\r\n 'a': '返回指定數值的 Fisher 變換。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '要計算其Fisher變換的數值。',\r\n 'example': '0.962',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MODE_SNGL',\r\n 't': 1,\r\n 'd': '返回數據集中出現次數最多的值。',\r\n 'a': '返回數據集中出現次數最多的值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算模式時要檢查的第一個值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 在計算模式時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'WEIBULL_DIST',\r\n 't': 1,\r\n 'd': '給定形狀和尺度,返回韋伯分佈函數(或韋伯累積分佈函數)的值。',\r\n 'a': '給定形狀和尺度',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : 'WEIBULL 分佈函數的輸入值。',\r\n 'example': '2.4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'alpha',\r\n 'detail' : 'Weibull 分佈函數的形狀參數。\\n\\n alpha值必須大於0。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'beta',\r\n 'detail' : 'Weibull 分佈函數的尺度參數。\\n\\n beta值必須大於0。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : 'TRUE()表示使用累積分佈函數,FALSE()則表示使用概率密度函數。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COUNT',\r\n 't': 1,\r\n 'd': '返回數據集中數值的個數。',\r\n 'a': '返回數據集中數值的個數。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計數時要檢查的第一個值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 在計數時要檢查的其他值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COUNTA',\r\n 't': 1,\r\n 'd': '返回數據集中值的數量。',\r\n 'a': '返回數據集中值的數量。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計數時要檢查的第一個值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 在計數時要檢查的其他值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVEDEV',\r\n 't': 1,\r\n 'd': '計算數據與數據集平均值之間的偏差大小的平均值。',\r\n 'a': '計算數據與數據集平均值之間的偏差大小的平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 樣本中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'AVERAGE',\r\n 't': 1,\r\n 'd': '返回數據集的算術平均值,對文字忽略不計。',\r\n 'a': '返回數據集的算術平均值',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算平均值時用到的第一個數值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 在計算平均值時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVERAGEA',\r\n 't': 1,\r\n 'd': '返回數據集的算術平均值。',\r\n 'a': '返回數據集的算術平均值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算平均值時用到的第一個數值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 在計算平均值時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'BINOM_DIST',\r\n 't': 1,\r\n 'd': '返回一元二項式分佈的概率。',\r\n 'a': '返回一元二項式分佈的概率。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'number_s',\r\n 'detail' : '試驗的成功次數。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'trials',\r\n 'detail' : '獨立檢驗的次數。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'probability_s',\r\n 'detail' : '任一給定檢驗的成功概率。',\r\n 'example': '0.005',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '是否使用二項式累積分佈。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'BINOM_INV',\r\n 't': 1,\r\n 'd': '計算累積二項式分佈大於或等於指定條件的最小值。',\r\n 'a': '計算累積二項式分佈大於或等於指定條件的最小值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'trials',\r\n 'detail' : '貝努利試驗次數。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'probability_s',\r\n 'detail' : '任一次給定檢驗的成功概率。',\r\n 'example': '0.005',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'alpha',\r\n 'detail' : '期望的臨界概率。',\r\n 'example': '0.8',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CONFIDENCE_NORM',\r\n 't': 1,\r\n 'd': '計算常态分配的置信區間的一半寬度。',\r\n 'a': '計算常态分配的置信區間的一半寬度。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'alpha',\r\n 'detail' : '用來計算置信水准的顯著性水准。\\n\\n置信水准等於100*(1 - alpha)%,亦即,如果 alpha 為0.05,則置信水准為 95%。',\r\n 'example': '0.05',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'standard_dev',\r\n 'detail' : '數據區域的總體標準差。',\r\n 'example': '1.6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'size',\r\n 'detail' : '樣本總量的大小。',\r\n 'example': '250',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CORREL',\r\n 't': 1,\r\n 'd': '計算給定數據集的皮爾遜積矩相關係數 r。',\r\n 'a': '計算給定數據集的皮爾遜積矩相關係數 r。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COVARIANCE_P',\r\n 't': 1,\r\n 'd': '計算數據集的總體協方差。',\r\n 'a': '計算數據集的總體協方差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COVARIANCE_S',\r\n 't': 1,\r\n 'd': '計算數據集的樣本協方差。',\r\n 'a': '計算數據集的樣本協方差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEVSQ',\r\n 't': 1,\r\n 'd': '基於樣本計算其偏差的平方和。',\r\n 'a': '基於樣本計算其偏差的平方和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 樣本中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EXPON_DIST',\r\n 't': 1,\r\n 'd': '返回帶有指定 Lambda 和指定值的指數分佈函數的值。',\r\n 'a': '返回帶有指定 Lambda 和指定值的指數分佈函數的值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '指數分佈函數的輸入值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'lambda',\r\n 'detail' : '用於指定指數分佈函數的 lambda 值。',\r\n 'example': '0.5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '是否使用指數累積分佈。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVERAGEIF',\r\n 't': 1,\r\n 'd': '根據條件返回範圍的平均值。',\r\n 'a': '根據條件返回範圍的平均值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'criteria_range',\r\n 'detail' : '要對其檢查 criterion 的範圍。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criterion',\r\n 'detail' : '要應用於criteria_range的模式或測試條件。\\n\\n等於:\"文字\" 或 1 或 \"=文字\" 或 \"=1\"\\n\\n大於:\">1\"\\n\\n大於等於:\">=1\"\\n\\n小於:\"<1\"\\n\\n小於等於:\"<=1\"\\n\\n不等於:\"<>1\"或\"<>文字\"',\r\n 'example': '\">20\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'average_range',\r\n 'detail' : '[可選] - 要計算平均值的範圍。如果未提供此參數,則改用criteria_range來計算平均值。',\r\n 'example': 'B1:B10',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'AVERAGEIFS',\r\n 't': 1,\r\n 'd': '根據多項條件返回範圍的平均值。',\r\n 'a': '根據多項條件返回範圍的平均值。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name' : 'average_range',\r\n 'detail' : '要計算平均值的範圍。',\r\n 'example': 'A1:A10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria_range1',\r\n 'detail' : '要對其檢查 criterion1 的範圍。',\r\n 'example': ' B1:B10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criterion1',\r\n 'detail' : '要應用於criteria_range1的模式或測試條件。',\r\n 'example': ' \">20\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria_range2, criterion2, ...',\r\n 'detail' : '[可選] - 要檢查的其他範圍和條件。',\r\n 'example': ' C1:C10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PERMUT',\r\n 't': 1,\r\n 'd': '返回可從數位對象中選擇的給定數目對象的排列數。',\r\n 'a': '返回可從數位對象中選擇的給定數目對象的排列數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '表示對象個數的整數。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'number_chosen',\r\n 'detail' : '表示每個排列中對象個數的整數。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TRIMMEAN',\r\n 't': 1,\r\n 'd': '在排除數據集高低兩端的部分數據之後計算所得的平均值。',\r\n 'a': '在排除數據集高低兩端的部分數據之後計算所得的平均值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據',\r\n 'detail' : '包含相關數據集的數組或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : '排除比例',\r\n 'detail' : '要從數據集的極值部分排除的數據占數據集的比例。\\n\\n排除比例必須大於等於0且小於1。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PERCENTILE_EXC',\r\n 't': 1,\r\n 'd': '返回數組的 K 百分點值,K 介於0到1之間,不含0與1。',\r\n 'a': '返回數組的 K 百分點值,K 介於0到1之間,不含0與1。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '定義相對位置的數組或數據區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'k',\r\n 'detail' : '0 到 1 之間的百分點值,不包含 0 和 1。',\r\n 'example': '0.25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PERCENTILE_INC',\r\n 't': 1,\r\n 'd': '返回數組的 K 百分點值,K 介於 0 到 1 之間,包含 0 與 1。',\r\n 'a': '返回數組的 K 百分點值,K 介於 0 到 1 之間,包含 0 與 1。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '定義相對位置的數組或數據區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'k',\r\n 'detail' : '0 到 1 之間的百分點值,包含 0 和 1。',\r\n 'example': '0.25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PEARSON',\r\n 't': 1,\r\n 'd': '回皮爾生(Pearson)乘積矩相關係數 r。',\r\n 'a': '回皮爾生(Pearson)乘積矩相關係數 r。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NORM_S_INV',\r\n 't': 1,\r\n 'd': '返回標準正態累積分佈函數的反函數值。該分佈的平均值為0,標準差為1。',\r\n 'a': '返回標準正態累積分佈函數的反函數值。該分佈的平均值為0,標準差為1。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'probability',\r\n 'detail' : '對應於常态分配的概率。',\r\n 'example': '0.75',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NORM_S_DIST',\r\n 't': 1,\r\n 'd': '返回標準常态分配函數(該分佈的平均值為0,標準差為1)。',\r\n 'a': '返回標準常态分配函數(該分佈的平均值為0,標準差為1)。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'z',\r\n 'detail' : '需要計算其分佈的數值。',\r\n 'example': '2.4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '决定函數形式的邏輯值。\\n\\n如果為TRUE(),則返回累積分佈函數;\\n\\n如果為FALSE(),則返回概率密度函數。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NORM_INV',\r\n 't': 1,\r\n 'd': '返回指定平均值和標準差的正態累積分佈函數的反函數值。',\r\n 'a': '返回指定平均值和標準差的正態累積分佈函數的反函數值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'probability',\r\n 'detail' : '對應於常态分配的概率。',\r\n 'example': '0.75',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'mean',\r\n 'detail' : '分佈的算術平均值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'standard_dev',\r\n 'detail' : '分佈的標準差。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NORM_DIST',\r\n 't': 1,\r\n 'd': '返回指定平均值和標準差的常态分配函數。',\r\n 'a': '返回指定平均值和標準差的常态分配函數。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '需要計算其分佈的數值。',\r\n 'example': '2.4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'mean',\r\n 'detail' : '分佈的算術平均值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'standard_dev',\r\n 'detail' : '分佈的標準差。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '决定函數形式的邏輯值。\\n\\n如果為TRUE(),則返回累積分佈函數;\\n\\n如果為FALSE(),則返回概率密度函數。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NEGBINOM_DIST',\r\n 't': 1,\r\n 'd': '返回負二項式分佈。',\r\n 'a': '返回負二項式分佈。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'number_f',\r\n 'detail' : '要類比的失敗次數。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'number_s',\r\n 'detail' : '要類比的成功次數。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'probability_s',\r\n 'detail' : '任一次給定檢驗的成功概率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '决定函數形式的邏輯值。\\n\\n如果為TRUE(),則返回累積分佈函數;\\n\\n如果為FALSE(),則返回概率密度函數。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'MINA',\r\n 't': 1,\r\n 'd': '返回數據集中的最小數值。',\r\n 'a': '返回數據集中的最小數值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算最小值時所用的第一個值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 在計算最小值時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MIN',\r\n 't': 1,\r\n 'd': '返回數值數據集中的最小值。',\r\n 'a': '返回數值數據集中的最小值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算最小值時所用的第一個值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 在計算最小值時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MEDIAN',\r\n 't': 1,\r\n 'd': '返回數值數據集中的中值。',\r\n 'a': '返回數值數據集中的中值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算中值時所用的第一個數值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 在計算中值時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MAXA',\r\n 't': 1,\r\n 'd': '返回數據集中的最大數值。',\r\n 'a': '返回數據集中的最大數值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算最大值時所用的第一個值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 在計算最大值時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MAX',\r\n 't': 1,\r\n 'd': '返回數值數據集中的最大值。',\r\n 'a': '返回數值數據集中的最大值。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '計算最大值時所用的第一個值或範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2',\r\n 'detail' : '[可選] - 在計算最大值時要考慮的其他數值或範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOGNORM_INV',\r\n 't': 1,\r\n 'd': '返回 x 的對數累積分佈函數的反函數值。',\r\n 'a': '返回 x 的對數累積分佈函數的反函數值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'probability',\r\n 'detail' : '與對數分佈相關的概率,介於0與1之間(不含0與1)。',\r\n 'example': '0.4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'mean',\r\n 'detail' : 'ln(x) 的平均值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'standard_dev',\r\n 'detail' : 'ln(x) 的標準差,正數。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LOGNORM_DIST',\r\n 't': 1,\r\n 'd': '返回 x 的對數分佈函數。',\r\n 'a': '返回 x 的對數分佈函數。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '用來計算函數的值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'mean',\r\n 'detail' : 'ln(x) 的平均值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'standard_dev',\r\n 'detail' : 'ln(x) 的標準差,正數。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '决定函數形式的邏輯值。\\n\\n如果為TRUE(),則返回累積分佈函數;\\n\\n如果為FALSE(),則返回概率密度函數。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'Z_TEST',\r\n 't': 1,\r\n 'd': '返回 z 檢驗的單尾 P 值。',\r\n 'a': '返回 z 檢驗的單尾 P 值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '用來檢驗 x 的數組或數據區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'x',\r\n 'detail' : '要測試的值。',\r\n 'example': 'B2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'sigma',\r\n 'detail' : '[可選] - 總體(已知)標準差。如果省略,則使用樣本標準差。',\r\n 'example': '3',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PROB',\r\n 't': 1,\r\n 'd': '返回區域中的數值落在指定區間內的概率。',\r\n 'a': '返回區域中的數值落在指定區間內的概率。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'x_range',\r\n 'detail' : '具有各自相應概率值的 x 數值區域。',\r\n 'example': 'A3:A6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'prob_range',\r\n 'detail' : '與 x_range 中的值相關聯的一組概率值。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'lower_limit',\r\n 'detail' : '要計算其概率的數值下界。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'upper_limit',\r\n 'detail' : '[可選 - 預設值為下界] - 要計算其概率的可選數值上界。\\n\\n如果省略上界,PROB則計算隨機選取相應值的次數恰好等於下界的概率。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'QUARTILE_EXC',\r\n 't': 1,\r\n 'd': '基於 0 到 1 之間(不包括 0 和 1)的百分點值返回數據集的四分位數。',\r\n 'a': '基於 0 到 1 之間(不包括 0 和 1)的百分點值返回數據集的四分位數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '要求得四分位數值的數組或數字型儲存格區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'quart',\r\n 'detail' : '要返回第幾個四分位值。\\n\\n1返回數據中最靠近第一個四分位值的值(25%標記)。\\n\\n2返回數據中最接近中值的值(50%標記)。\\n\\n3返回數據中最接近第三個四分位值的值(75%標記)。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'QUARTILE_INC',\r\n 't': 1,\r\n 'd': '根據 0 到 1 之間的百分點值(包含 0 和 1)返回數據集的四分位數。',\r\n 'a': '根據 0 到 1 之間的百分點值(包含 0 和 1)返回數據集的四分位數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '要求得四分位數值的數組或數字型儲存格區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'quart',\r\n 'detail' : '要返回第幾個四分位值。\\n\\n0返回數據中的最小值(0%標記)。\\n\\n1返回數據中最靠近第一個四分位值的值(25%標記)。\\n\\n2返回數據中最接近中值的值(50%標記)。\\n\\n3返回數據中最接近第三個四分位值的值(75%標記)。\\n\\n4返回數據中的最大值(100%標記)。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'POISSON_DIST',\r\n 't': 1,\r\n 'd': '返回泊松分布。',\r\n 'a': '返回泊松分布。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '事件數。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'mean',\r\n 'detail' : '期望值。非負數',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '一 邏輯值,確定所返回的概率分佈的形式。\\n\\n如果為TRUE(),則返回發生的隨機事件數在零(含零)和x(含x)之間的累積泊松概率;\\n\\n如果為FALSE(),則返回發生的事件數正好是x的泊松概率密度函數。',\r\n 'example': 'FALSE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RSQ',\r\n 't': 1,\r\n 'd': '返回皮爾生(Pearson)乘積矩相關係數r的平方。',\r\n 'a': '返回皮爾生(Pearson)乘積矩相關係數r的平方。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_DIST',\r\n 't': 1,\r\n 'd': '返回學生的左尾 t 分佈。',\r\n 'a': '返回學生的左尾 t 分佈。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : 'T-分佈函數的輸入。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'degrees_freedom',\r\n 'detail' : '自由度數值。',\r\n 'example': '30',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'tails',\r\n 'detail' : '决定函數形式的邏輯值。\\n\\n如果cumulative為TRUE(),則HYPGEOM.DIST返回累積分佈函數;\\n\\n如果為FALSE(),則返回概率密度函數。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'T_DIST_2T',\r\n 't': 1,\r\n 'd': '返回學生的雙尾 t 分佈。',\r\n 'a': '返回學生的雙尾 t 分佈。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : 'T-分佈函數的輸入。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'degrees_freedom',\r\n 'detail' : '自由度數值。',\r\n 'example': '30',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_DIST_RT',\r\n 't': 1,\r\n 'd': '返回學生的右尾 t 分佈。',\r\n 'a': '返回學生的右尾 t 分佈。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : 'T-分佈函數的輸入。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'degrees_freedom',\r\n 'detail' : '自由度數值。',\r\n 'example': '30',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_INV',\r\n 't': 1,\r\n 'd': '返回學生的 t 分佈的左尾反函數。',\r\n 'a': '返回學生的 t 分佈的左尾反函數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'probability',\r\n 'detail' : '與學生的 t 分佈相關的概率。\\n\\n必須大於 0 且小於 1。',\r\n 'example': '0.35',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'deg_freedom',\r\n 'detail' : '自由度數值。\\n\\n如果所提供的參數不是整數,將截取其整數部分。\\n\\n必須大於等於1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_INV_2T',\r\n 't': 1,\r\n 'd': '返回學生 t 分佈的雙尾反函數。',\r\n 'a': '返回學生 t 分佈的雙尾反函數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'probability',\r\n 'detail' : '與學生的t分佈相關的概率。\\n\\n必須大於 0 且小於 1。',\r\n 'example': '0.35',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'deg_freedom',\r\n 'detail' : '自由度數值。\\n\\n如果所提供的參數不是整數,將截取其整數部分。\\n\\n必須大於等於1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'T_TEST',\r\n 't': 1,\r\n 'd': '返回與t-檢驗相關的概率。用於判斷兩個樣本是否可能是出自平均值相同的兩個樣本總體。',\r\n 'a': '返回與t-檢驗相關的概率。用於判斷兩個樣本是否可能是出自平均值相同的兩個樣本總體。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'array1',\r\n 'detail' : '將用於t檢驗的第一個數據樣本或第一組儲存格。',\r\n 'example': 'A1:A4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'array2',\r\n 'detail' : '將用於t檢驗的第二個數據樣本或第二組儲存格。',\r\n 'example': 'B1:B4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'tails',\r\n 'detail' : '指定分佈的尾數。\\n\\n如果為 1:使用單尾分佈。\\n\\n如果為 2:使用雙尾分佈。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '指定t檢驗的類型。\\n\\n如果為 1:執行配對檢驗。\\n\\n如果為 2:執行雙樣本等方差(同方差)檢驗。\\n\\n如果為 3:執行雙樣本不等方差(异方差)檢驗。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'F_DIST',\r\n 't': 1,\r\n 'd': '給定輸入值 x,計算兩個數據集的左尾 F 概率分佈(差异程度)。此分佈也稱為 Fisher-Snedecor 分佈或Snedecor F 分佈。',\r\n 'a': '給定輸入值 x',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '用來計算函數的值。',\r\n 'example': '15.35',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'degrees_freedom1',\r\n 'detail' : '分子自由度。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'degrees_freedom2',\r\n 'detail' : '分母自由度。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cumulative',\r\n 'detail' : '用於確定函數形式的邏輯值。預設值為 FALSE。\\n\\n如果為 TRUE():F.DIST將返回累積分佈函數值。\\n\\n如果為FALSE():F.DIST將返回概率密度函數值。',\r\n 'example': 'TRUE()',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'F_DIST_RT',\r\n 't': 1,\r\n 'd': '給定輸入x,計算兩個數據集的右尾F概率分佈(差异程度)。此分佈也稱為Fisher-Snedecor分佈或Snedecor F分佈。',\r\n 'a': '給定輸入 x',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '用來計算函數的值。',\r\n 'example': '15.35',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'degrees_freedom1',\r\n 'detail' : '分子自由度。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'degrees_freedom2',\r\n 'detail' : '分母自由度。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VAR_P',\r\n 't': 1,\r\n 'd': '基於樣本總體計算方差。',\r\n 'a': '基於樣本總體計算方差。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '數據集中的第一個值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, …',\r\n 'detail' : '[可選] - 數據集中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VAR_S',\r\n 't': 1,\r\n 'd': '基於樣本計算方差。',\r\n 'a': '基於樣本計算方差。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, …',\r\n 'detail' : '[可選] - 樣本中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VARA',\r\n 't': 1,\r\n 'd': '基于样本计算方差,将文本取值为0。',\r\n 'a': '基于样本计算方差',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'value2, ...',\r\n 'detail' : '[可選] - 樣本中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'VARPA',\r\n 't': 1,\r\n 'd': '基於樣本總體計算方差,將文字取值為0。',\r\n 'a': '基於樣本總體計算方差',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '樣本中的第一項值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 數據集中包含的其他數值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STEYX',\r\n 't': 1,\r\n 'd': '返回通過線性回歸法預測每個 x 的 y 值時所產生的標準誤差。',\r\n 'a': '返回通過線性回歸法預測每個 x 的 y 值時所產生的標準誤差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'STANDARDIZE',\r\n 't': 1,\r\n 'd': '給定分佈的平均值和標準差,計算一個隨機變數正態化的相應值。',\r\n 'a': '給定分佈的平均值和標準差,計算一個隨機變數正態化的相應值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'x',\r\n 'detail' : '要正態化的隨機變數值。',\r\n 'example': '96',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'mean',\r\n 'detail' : '分佈的平均值。',\r\n 'example': '80',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'standard_dev',\r\n 'detail' : '分佈的標準差。',\r\n 'example': '6.7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SMALL',\r\n 't': 1,\r\n 'd': '返回數據集中的第k個最小值。',\r\n 'a': '返回數據集中的第k個最小值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '需要找到第k個最小值的數組或數值數據區域。',\r\n 'example': 'A2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'k',\r\n 'detail' : '要返回的數據在數組或數據區域裏的位置(從小到大)。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SLOPE',\r\n 't': 1,\r\n 'd': '計算通過數據集的線性回歸得到的直線的斜率。',\r\n 'a': '計算通過數據集的線性回歸得到的直線的斜率。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : '數據_y',\r\n 'detail' : '代表因變數數據數組或矩陣的範圍。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '數據_x',\r\n 'detail' : '代表引數數據數組或矩陣的範圍。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SKEW',\r\n 't': 1,\r\n 'd': '返回分佈的偏斜度。偏斜度表明分佈相對於平均值的不對稱程度。正偏斜度表明分佈的不對稱尾部趨向於更多正值。負偏斜度表明分佈的不對稱尾部趨向於更多負值。',\r\n 'a': '返回分佈的偏斜度。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '數據集中的第一個值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 數據集中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'SKEW_P',\r\n 't': 1,\r\n 'd': '返回基於樣本總體的分佈不對稱度:表明分佈相對於平均值的不對稱程度。',\r\n 'a': '返回基於樣本總體的分佈不對稱度:表明分佈相對於平均值的不對稱程度。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : '值1',\r\n 'detail' : '數據集中的第一個值或範圍。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '值2, ...',\r\n 'detail' : '[可選] - 數據集中包含的其他值或範圍。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'VLOOKUP',\r\n 't': 2,\r\n 'd': '縱向查找。在範圍的第一列中自上而下蒐索某個鍵值,並返回所找到的行中指定儲存格的值。',\r\n 'a': '縱向查找。在範圍的第一列中自上而下蒐索某個鍵值',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : '蒐索鍵值',\r\n 'detail' : '要蒐索的值,如 42、\"Cats\" 或 I24。',\r\n 'example': '10003',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '範圍',\r\n 'detail' : '要進行蒐索的範圍。VLOOKUP 將在該範圍的第一列中蒐索蒐索鍵值中指定的鍵值。',\r\n 'example': 'A2:B26',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '索引',\r\n 'detail' : '要返回的值的列索引,範圍中的第一列編號為1。\\n\\n如果索引不是介於1和範圍中的列數之間,將返回#VALUE!。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '已排序',\r\n 'detail' : '[預設值為TRUE()] -訓示要蒐索的列(指定範圍的第一列)是否已排序。大多數情况下,建議設為FALSE()。\\n\\n建議將已排序設為FALSE。如果設為FALSE,將返回完全匹配項。如果存在多個匹配值,將返回找到的第一個值對應的儲存格的內容,如果找不到匹配值,則返回#N/A。\\n\\n如果將已排序設為TRUE或省略,將返回(小於或等於蒐索鍵值的)最接近的匹配項。如果蒐索的列中所有的值均大於蒐索鍵值,則返回#N/A。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HLOOKUP',\r\n 't': 2,\r\n 'd': '橫向查找。在範圍的第一行中蒐索某個鍵值,並返回所找到的列中指定儲存格的值。',\r\n 'a': '橫向查找。在範圍的第一行中蒐索某個鍵值',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : '蒐索鍵值',\r\n 'detail' : '要蒐索的值。例如,42、\"Cats\"或I24。',\r\n 'example': '10003',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '範圍',\r\n 'detail' : '要進行蒐索的範圍。將在該範圍的第一行中蒐索在蒐索鍵值中指定的鍵值。',\r\n 'example': 'A2:Z6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '索引',\r\n 'detail' : '要返回的值的行索引,範圍中的第一行編號為1。\\n\\n如果索引不是介於1和範圍中的行數之間,將返回#VALUE!。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '已排序',\r\n 'detail' : '[可選 - 預設值為TRUE()] - 訓示要蒐索的行(指定範圍的第一行)是否已排序。\\n\\n如果將已排序設為TRUE或省略,將返回最接近的匹配值(小於或等於蒐索鍵值)。如果在蒐索的行中所有的值均大於蒐索鍵值,則返回#N/A。\\n\\n如果將已排序設為TRUE或將其省略,而範圍的首行並非處於已排序狀態,則返回值可能會是錯誤的。\\n\\n如果將已排序設為FALSE,則僅返回完全匹配。如果存在多個匹配值,將返回與找到的第一個值對應的儲存格的內容,如果找不到匹配值則返回#N/A。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LOOKUP',\r\n 't': 2,\r\n 'd': '在行或列中查找相應鍵,並將相應儲存格的值返回到與蒐索行或列所在位置相同的結果範圍中。',\r\n 'a': '在行或列中查找相應鍵',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : '蒐索鍵值',\r\n 'detail' : '要在行或列中蒐索的值。例如,42、\"Cats\" 或 I24。',\r\n 'example': '10003',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '搜索範圍 | 搜索結果數組',\r\n 'detail' : '使用LOOKUP的一種方法是給定單行或單列形式的搜索範圍進行蒐索查找,這種管道要用到另一個參數結果範圍。另一種管道是將這兩個參數合併為一個搜索結果數組,其中第一行或第一列用於蒐索,並將返回值放在該數組的最後一行或最後一列中。',\r\n 'example': 'A1:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '結果範圍',\r\n 'detail' : '[ 可選 ] - 用於存放返回結果的範圍。返回值對應於在搜索範圍中找到蒐索鍵值的位置。此範圍必須僅為單行或單列,而如果您使用的是搜索結果數組管道,則不應提供此參數。',\r\n 'example': 'B1:B100',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ADDRESS',\r\n 't': 2,\r\n 'd': '返回字串形式的儲存格引用。',\r\n 'a': '返回字串形式的儲存格引用。',\r\n 'm': [2, 5],\r\n 'p': [{\r\n 'name' : 'row_num',\r\n 'detail' : '一個數值,指定要在儲存格引用中使用的行號。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'column_num',\r\n 'detail' : '一個數值,指定要在儲存格引用中使用的列號(而非名稱)。A列的編號為1。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'abs_num',\r\n 'detail' : '[可選 - 預設值為1] - 一個數值,指定要返回的參考類型。\\n\\n1表示行列均採用絕對值(例如$A$1);\\n\\n2表示採用絕對行號,相對列標(例如A$1);\\n\\n3表示採用相對行號,絕對列標(例如$A1);\\n\\n4表示行列均採用相對值(例如A1)。',\r\n 'example': '4',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'A1',\r\n 'detail' : '[可選 - 預設值為TRUE()] - 一個布林值,訓示採用A1標記形式(TRUE)還是R1C1標記形式(FALSE)。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'sheet_text',\r\n 'detail' : '[可選 - 默認預設] - 用於指定地址所指向的工作表名稱。',\r\n 'example': '\"Sheet2\"',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'INDIRECT',\r\n 't': 2,\r\n 'd': '返回以字串指定的儲存格引用。',\r\n 'a': '返回以字串指定的儲存格引用。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'ref_text',\r\n 'detail' : '以帶引號的字串形式提供的儲存格引用。',\r\n 'example': '\"Sheet2!\"&B10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'A1',\r\n 'detail' : '[可選 - 預設值為TRUE()] - 一個布林值,訓示採用A1標記形式(TRUE)還是R1C1標記形式(FALSE)。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ROW',\r\n 't': 2,\r\n 'd': '返回指定儲存格的行號',\r\n 'a': '返回指定儲存格的行號',\r\n 'm': [0, 1],\r\n 'p': [{\r\n 'name' : 'reference',\r\n 'detail' : '[可選 - 默認為此公式所在的儲存格] - 要返回其行號的儲存格。\\n\\n如果儲存格引用指向的範圍其寬度大於一個儲存格,而此公式不是用作數組公式的,這時會僅返回儲存格引用中首行的編號值。',\r\n 'example': 'A9',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ROWS',\r\n 't': 2,\r\n 'd': '返回指定數組或範圍中的行數。',\r\n 'a': '返回指定數組或範圍中的行數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '要返回其行數的範圍。',\r\n 'example': 'A9:A62',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COLUMN',\r\n 't': 2,\r\n 'd': '按照 `A=1` 的規則返回指定儲存格的列號。',\r\n 'a': '按照 `A=1` 的規則返回指定儲存格的列號。',\r\n 'm': [0, 1],\r\n 'p': [{\r\n 'name' : 'reference',\r\n 'detail' : '[可選 - 默認為包含此公式的儲存格] - 要返回其列號的儲存格。A列對應的編號為1。\\n\\n如果儲存格引用是寬度超過一個儲存格的範圍,而此公式不是作為數組公式來使用的,囙此將返回儲存格引用中的第一列的位置。',\r\n 'example': 'A9',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'COLUMNS',\r\n 't': 2,\r\n 'd': '返回指定數組或範圍中的列數。',\r\n 'a': '返回指定數組或範圍中的列數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '要返回其列數的範圍。',\r\n 'example': 'A9:W62',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'OFFSET',\r\n 't': 2,\r\n 'd': '給定某範圍的起始儲存格引用以及該範圍涵蓋的行列數量,返回該範圍的引用。',\r\n 'a': '給定某範圍的起始儲存格引用以及該範圍涵蓋的行列數量,返回該範圍的引用。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name' : 'reference',\r\n 'detail' : '用於計算行列偏移量的起點。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'rows',\r\n 'detail' : '要偏移的行數。\\n\\n行偏移量必須是整數,但也可以是負數。如果提供的參數帶有小數,小數部分將被截去。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cols',\r\n 'detail' : '要偏移的列數。\\n\\n列偏移量必須是整數,但也可以是負數。如果提供的參數帶有小數,小數部分將被截去。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'height',\r\n 'detail' : '[可選] - 要從偏移目標開始返回的範圍的高度。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'width',\r\n 'detail' : '[可選] - 要從偏移目標開始返回的範圍的寬度。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MATCH',\r\n 't': 2,\r\n 'd': '在儲存格中蒐索指定項,然後返回該項在儲存格區域中的相對位置。',\r\n 'a': '在儲存格中蒐索指定項,然後返回該項在儲存格區域中的相對位置。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'lookup_value',\r\n 'detail' : '要在 lookup_array 中匹配的值。',\r\n 'example': '\"Sunday\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'lookup_array',\r\n 'detail' : '要蒐索的儲存格區域。\\n\\n如果所用的範圍的高度和寬度均大於1,MATCH將返回#N/A!。',\r\n 'example': 'A2:A9',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'match_type',\r\n 'detail' : '[可選 - 預設值為1] - 要採用的蒐索管道。\\n\\n1為默認類型,此時MATCH會假設範圍已按昇冪排序,並返回小於等於蒐索鍵值的最大值。\\n\\n0表示完全匹配,在範圍未排序的情况下需要使用此管道。\\n\\n-1讓MATCH假設範圍是按降序排序的,並返回大於等於蒐索鍵值的最小值。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'INDEX',\r\n 't': 2,\r\n 'd': '返回表格或中的元素值,此元素由行號和列號的索引值給定。',\r\n 'a': '返回表格或中的元素值,此元素由行號和列號的索引值給定。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '儲存格區域或數組常數。',\r\n 'example': 'A1:C20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'row_num',\r\n 'detail' : '選擇數組中的某行,函數從該行返回數值。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'column_num',\r\n 'detail' : '選擇數組中的某列,函數從該列返回數值。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GETPIVOTDATA',\r\n 't': 2,\r\n 'd': '從與指定行和列標題對應的數據透視錶中選取匯總值。',\r\n 'a': '從與指定行和列標題對應的數據透視錶中選取匯總值。',\r\n 'm': [2, 254],\r\n 'p': [{\r\n 'name' : 'data_field',\r\n 'detail' : '您想從數據透視錶中獲取其數據的值名稱。\\n值名稱必須括在引號中或是指向包含相關文字的任何儲存格的引用。\\n如果有多個值欄位,則必須使用數據透視錶中顯示的確切名稱(如\"銷售總額\")。',\r\n 'example': '\"SUM of number of units\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'pivot_table',\r\n 'detail' : '目標數據透視錶中的任何儲存格的引用(推薦位於頂角的儲存格)。',\r\n 'example': \"'Pivot table'!A1\",\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'field1',\r\n 'detail' : '[可選] - 源數據集(不是數據透視錶)中列的名稱。',\r\n 'example': '\"division\"',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'item1',\r\n 'detail' : '[可選] - 數據透視錶中顯示的與您要檢索的欄位名稱1相對應的行或列的名稱。',\r\n 'example': '\"east\"',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CHOOSE',\r\n 't': 2,\r\n 'd': '基於索引返回選項清單中的元素。',\r\n 'a': '基於索引返回選項清單中的元素。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name' : 'index_num',\r\n 'detail' : '指定要返回哪一項。\\n\\n如果索引為零、負值或大於提供的選擇數量,將返回#VALUE!錯誤。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'value1',\r\n 'detail' : '一項可能的返回值。必須提供。可以是儲存格引用或單獨的值。',\r\n 'example': '\"A\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '[可選] - 其他可以選擇的值。選擇',\r\n 'example': '\"B\"',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HYPERLINK',\r\n 't': 2,\r\n 'd': '在儲存格內創建一個超連結。',\r\n 'a': '在儲存格內創建一個超連結。',\r\n 'p': [{\r\n 'name' : '網址',\r\n 'detail' : '以引號括住的連結位置的完整網址,或對包含這種網址的儲存格的引用。\\n\\n僅允許某些連結類型。其中包括:http://、https://、mailto:、aim:、ftp://、gopher://、telnet://和news://,明確禁用使用其他協定。如果指定的是其他協定,將會在儲存格中顯示連結標籤,但該標籤不會以連結形式呈現。\\n\\n如果未指定協定,則假設使用http://,並將其作為網址的首碼。',\r\n 'example': '\"http://www.google.com/\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '連結標籤',\r\n 'detail' : '[可選-默認為網址] - 要在儲存格中作為連結顯示的文字(用引號括起來的),或者指向包含這種標籤的儲存格的引用。\\n\\n如果連結標籤是指向某個空儲存格的引用,如果網址有效,就將其作為連結顯示,否則作為純文字顯示。\\n\\n如果連結標籤為空字串常數(\"\"),所在儲存格顯示的內容將為空白,但通過點擊該儲存格或轉入該儲存格仍然可以訪問連結。',\r\n 'example': '\"Google\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TIME',\r\n 't': 6,\r\n 'd': '將給定的小時、分鐘和秒轉換為時間。',\r\n 'a': '將給定的小時、分鐘和秒轉換為時間。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : '小時',\r\n 'detail' : '0(零)到 32767 之間的數位,代表小時。\\n\\n任何大於 23 的值都會除以24,餘數將作為小時值。',\r\n 'example': '11',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '分鐘',\r\n 'detail' : '0(零)到 32767 之間的數位,代表分鐘。\\n\\n任何大於 59 的值將轉換為小時和分鐘。',\r\n 'example': '40',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : '秒',\r\n 'detail' : '0(零)到 32767 之間的數位,代表秒。\\n\\n任何大於 59 的值將轉換為小時、分鐘和秒。',\r\n 'example': '59',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TIMEVALUE',\r\n 't': 6,\r\n 'd': '按一天24小時返回該時間的分數表示。',\r\n 'a': '按一天24小時返回該時間的分數表示。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'time_text',\r\n 'detail' : '用於表示時間的字串。',\r\n 'example': '\"2:15 PM\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EOMONTH',\r\n 't': 6,\r\n 'd': '返回某個月份最後一天的序號,該月份在另一個日期之前或之後的數個月(月數由參數指定)。',\r\n 'a': '返回某個月份最後一天的序號',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '用於計算結果的參照日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'months',\r\n 'detail' : '用於計算的起始日期之前(負)或之後(正)的月數。返回的是計算所得月份的最後那天。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'EDATE',\r\n 't': 6,\r\n 'd': '返回表示某個日期的序號,該日期在另一個日期的數月之前/之後。',\r\n 'a': '返回表示某個日期的序號',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '用於計算結果的參照日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'months',\r\n 'detail' : '用於計算的起始日期之前(負)或之後(正)的月數。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SECOND',\r\n 't': 6,\r\n 'd': '返回時間值的秒數。秒數是0(零)到59範圍內的整數。',\r\n 'a': '返回時間值的秒數。秒數是0(零)到59範圍內的整數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '時間',\r\n 'detail' : '用於計算秒鐘部分的時間。必須為以下值之一:指向包含日期/時間值的儲存格的引用、返回日期/時間的函數或者數位。',\r\n 'example': 'TIME(11',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'MINUTE',\r\n 't': 6,\r\n 'd': '以數位格式返回特定時間的分鐘部分。',\r\n 'a': '以數位格式返回特定時間的分鐘部分。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '時間',\r\n 'detail' : '用於計算分鐘部分的時間。必須為以下值之一:指向包含日期/時間值的儲存格的引用、返回日期/時間的函數或者數位。',\r\n 'example': 'TIME(11',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HOUR',\r\n 't': 6,\r\n 'd': '以數位格式返回特定時間的小時部分。',\r\n 'a': '以數位格式返回特定時間的小時部分。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : '時間',\r\n 'detail' : '用於計算小時部分的時間。必須為以下值之一:指向包含日期/時間值的儲存格的引用、返回日期/時間的函數或者數位。',\r\n 'example': 'TIME(11',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NOW',\r\n 't': 6,\r\n 'd': '以日期值格式返回當前日期和時間。',\r\n 'a': '以日期值格式返回當前日期和時間。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'NETWORKDAYS',\r\n 't': 6,\r\n 'd': '返回所提供的兩個日期之間的淨工作日天數。',\r\n 'a': '返回所提供的兩個日期之間的淨工作日天數。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '用於計算淨工作日天數的時間段開始日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'end_date',\r\n 'detail' : '用於計算淨工作日天數的時間段結束日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'holidays',\r\n 'detail' : '[可選] - 一個範圍或數組常數,其中包含作為節假日的日期序號。\\n\\n在節假日數組中提供的值必須是日期序號值(例如由N所返回的值)或日期值(例如由DATE、DATEVALUE或TO_DATE返回的值)。由範圍指定的值應該是標準的日期值或日期序數值。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NETWORKDAYS_INTL',\r\n 't': 6,\r\n 'd': '返回給定的兩個日期之間的淨工作日天數(排除指定的週末和節假日)。',\r\n 'a': '返回給定的兩個日期之間的淨工作日天數(排除指定的週末和節假日)。',\r\n 'm': [2, 4],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '用於計算淨工作日天數的時間段開始日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'end_date',\r\n 'detail' : '用於計算淨工作日天數的時間段結束日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'weekend',\r\n 'detail' : '[可選-預設值為1] - 用於表示哪些天為週末的數位或字串。\\n字串管道:可以使用由0和1組成的字串來指定週末,串中的第一個數位字元代表週一,最後一個則代表周日。零表示這一天是工作日,1 表示這一天為週末。例如,\"0000011\"表示將週六和周日作為週末。\\n數位管道:這種管道不使用上述字串形式,而是使用一個數位。1 =週六/周日為週末,2 =周日/週一為週末,依此類推則7 =週五/週六。11 =周日為唯一週末,12 =週一為唯一週末,依此類推則17 =週六為唯一週末。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'holidays',\r\n 'detail' : '[可選] - 這是一個範圍或數組常數,其中包含作為節假日的日期。\\n在節假日數組內提供的值必須為日期序數值(例如N的返回值)或日期值(例如DATE、DATEVALUE或TO_DATE的返回值)。由範圍指定的值應該是標準的日期值或日期序數值。',\r\n 'example': 'DATE(1969',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISOWEEKNUM',\r\n 't': 6,\r\n 'd': '返回給定日期在全年中的 ISO 周數。',\r\n 'a': '返回給定日期在全年中的 ISO 周數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'date',\r\n 'detail' : '用於日期和時間計算的日期-時間程式碼。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'WEEKNUM',\r\n 't': 6,\r\n 'd': '返回特定日期的周數。',\r\n 'a': '返回特定日期的周數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'serial_number',\r\n 'detail' : '要確定其位於第幾周的日期,必須是對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'return_type',\r\n 'detail' : '[可選-預設值為1 ] - 代表一周起始日的數位,系統也使用該數位來確定一年的第一周(1=周日,2=週一)。',\r\n 'example': '7',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'WEEKDAY',\r\n 't': 6,\r\n 'd': '返回一個數位,對應於給定日期所在的星期幾。',\r\n 'a': '返回一個數位,對應於給定日期所在的星期幾。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'serial_number',\r\n 'detail' : '要為其確定星期幾的日期。必須是對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'return_type',\r\n 'detail' : '[可選-預設值為1] -以數位訓示使用哪種編號順序來表示星期幾。默認情况下,按星期日(= 1)開始計算。\\n\\n如果類型為1,則星期值將從星期日開始算起,並且星期日的值為1,囙此星期六的值就是7。\\n\\n如果類型為2,則星期值將從星期一開始算起,並且星期一的值為1,囙此星期日的值就是7。\\n\\n如果類型為3,則星期值將從星期一算起,並且星期一的值為0,囙此星期日的值就是6。',\r\n 'example': '7',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DAY',\r\n 't': 6,\r\n 'd': '以數位格式返回特定日期所在的當月幾號。',\r\n 'a': '以數位格式返回特定日期所在的當月幾號。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'serial_number',\r\n 'detail' : '要從中選取具體幾號的日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DAYS',\r\n 't': 6,\r\n 'd': '返回兩個日期之間的天數。',\r\n 'a': '返回兩個日期之間的天數。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'end_date',\r\n 'detail' : '計算中要使用的結束日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': '2011-3-15',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'start_date',\r\n 'detail' : '計算中要使用的開始日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': '2011-2-1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DAYS360',\r\n 't': 6,\r\n 'd': '按照每年360天,返回兩個日期之間的差(用於計算利息)。',\r\n 'a': '按照每年360天,返回兩個日期之間的差(用於計算利息)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '計算中要使用的開始日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'end_date',\r\n 'detail' : '計算中要使用的結束日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'method',\r\n 'detail' : '[可選 - 默認為FALSE()] - 訓示要使用哪種天數計算方法。\\n\\nFALSE -採用美國(NASD)方法時,如果起始日期為某月的最後一天,為便於計算,會將起始日期的當月幾號更改為30。此外,如果結束日期是所在月份的最後一天,而且起始日期在其所在月的30號之前,則將結束日期更改為結束日期之後那個月的第一天,否則將結束日期更改為該月的30號。\\n\\nTRUE -採用歐洲方法時,會將所有日期在31號的起始日期或結束日期更改為當月的30號。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DATE',\r\n 't': 6,\r\n 'd': '將提供的年、月、日轉換為日期。',\r\n 'a': '將提供的年、月、日轉換為日期。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'year',\r\n 'detail' : '日期的年份部分,包含一到四位數位。\\n\\n介於0(零)到 1899 之間,會將該值與 1900 相加來計算年份;\\n\\n介於 1900 到 9999 之間,將使用該數值作為年份;\\n\\n小於0或大於等於 10000,返回錯誤值#NUM!。',\r\n 'example': '1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'month',\r\n 'detail' : '日期的月份部分,一個正整數或負整數。\\n\\n如果 month 大於 12,則 month 會將該月份數與指定年中的第一個月相加。\\n\\n如果 month 小於 1,month 則從指定年份的一月份開始遞減該月份數,然後再加上 1 個月。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'day',\r\n 'detail' : '日期的日部分,一個正整數或負整數。\\n\\n如果 day 大於月中指定的天數,則 day 會將天數與該月中的第一天相加。\\n\\n如果 day 小於1,則 day 從指定月份的第一天開始遞減該天數,然後再加上 1 天。',\r\n 'example': '20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DATEVALUE',\r\n 't': 6,\r\n 'd': '將提供的日期字串轉換為日期的序號。',\r\n 'a': '將提供的日期字串轉換為日期的序號。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'date_text',\r\n 'detail' : '表示日期的字串。',\r\n 'example': '\"1969-7-20\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DATEDIF',\r\n 't': 6,\r\n 'd': '計算兩個日期之間的天數、月數或年數。',\r\n 'a': '計算兩個日期之間的天數、月數或年數。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : '起始日期',\r\n 'detail' : '計算中要使用的開始日期。必須是對包含DATE值的儲存格的引用、返回DATE類型的函數或數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '結束日期',\r\n 'detail' : '計算中要使用的結束日期。必須是對包含DATE值的儲存格的引用、返回DATE類型的函數或數位。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '組織',\r\n 'detail' : '時間組織的縮寫文字。例如\"M\"代表月。有效值包括:\"Y\"、\"M\"、\"D\"、\"MD\"、\"YM\"和\"YD\"。\\n\\n\"Y\":返回起始日期和結束日期之間的整年數。\\n\\n\"M\":返回起始日期和結束日期之間的整月數。\\n\\n\"D\":返回起始日期和結束日期之間的天數。\\n\\n\"MD\":返回起始日期和結束日期之間的天數(不計整月數)。\\n\\n\"YM\":返回起始日期和結束日期之間的整月數(不計整年數)。\\n\\n\"YD\":返回起始日期和結束日期之間的天數(假設起始日期和結束日期的間隔不超過一年)。',\r\n 'example': '16)',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'WORKDAY',\r\n 't': 6,\r\n 'd': '指定工作日天數,計算結束日期。',\r\n 'a': '指定工作日天數,計算結束日期。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '計算的開始日期。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'days',\r\n 'detail' : 'start_date之前或之後不含週末及節假日的天數。\\n\\n為正值將生成未來日期;\\n\\n為負值生成過去日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'holidays',\r\n 'detail' : '[可選] - 一個範圍或數組常數,其中包含作為節假日的日期序號。\\n\\n在節假日數組中提供的值必須是日期序號值(例如由N所返回的值)或日期值(例如由DATE、DATEVALUE或TO_DATE返回的值)。由範圍指定的值應該是標準的日期值或日期序數值。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'WORKDAY_INTL',\r\n 't': 6,\r\n 'd': '返回指定的若干個工作日之前或之後的日期的序號(使用自定義週末參數)。 ',\r\n 'a': '返回指定的若干個工作日之前或之後的日期的序號(使用自定義週末參數)。 ',\r\n 'm': [2, 4],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '開始日期(將被截尾取整)。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'days',\r\n 'detail' : 'start_date之前或之後的工作日的天數。\\n\\n正值表示未來日期;\\n\\n負值表示過去日期;\\n\\n零值表示開始日期。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'weekend',\r\n 'detail' : '[可選 - 預設值為1] - 用於表示哪些天為週末的數位或字串。\\n字串管道:可以使用由0和1組成的字串來指定週末,串中的第一個數位字元代表週一,最後一個則代表周日。零表示這一天是工作日,1表示這一天為週末。例如,\"0000011\"表示將週六和周日作為週末。\\n數位管道:這種管道不使用上述字串形式,而是使用一個數位。1 =週六/周日為週末,2 =周日/週一為週末,依此類推則7 =週五/週六。11 =周日為唯一週末,12 =週一為唯一週末,依此類推則17 =週六為唯一週末。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'holidays',\r\n 'detail' : '[可選] - 這是一個範圍或數組常數,其中包含作為節假日的日期。\\n在節假日數組內提供的值必須為日期序數值(例如N的返回值)或日期值(例如DATE、DATEVALUE或TO_DATE的返回值)。由範圍指定的值應該是標準的日期值或日期序數值。',\r\n 'example': 'DATE(1969',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'YEAR',\r\n 't': 6,\r\n 'd': '返回對應於某個日期的年份。Year作為 1900 - 9999 之間的整數返回。',\r\n 'a': '返回對應於某個日期的年份。Year作為 1900 - 9999 之間的整數返回。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'serial_number',\r\n 'detail' : '用於計算年份的日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'YEARFRAC',\r\n 't': 6,\r\n 'd': '返回 start_date 和 end_date 之間的天數占全年天數的百分比。',\r\n 'a': '返回 start_date 和 end_date 之間的天數占全年天數的百分比。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'start_date',\r\n 'detail' : '計算中要使用的開始日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'end_date',\r\n 'detail' : '計算中要使用的結束日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': '7',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 要使用的日計數基準類型。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '16)',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TODAY',\r\n 't': 6,\r\n 'd': '以日期值格式返回當前日期。',\r\n 'a': '以日期值格式返回當前日期。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'MONTH',\r\n 't': 6,\r\n 'd': '返回日期(以序列數表示)中的月份。月份是介於1(一月)到12(十二月)之間的整數。',\r\n 'a': '返回日期(以序列數表示)中的月份。月份是介於1(一月)到12(十二月)之間的整數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'serial_number',\r\n 'detail' : '要從中選取月份的日期。必須是以下一種:對包含日期的儲存格的引用、返回日期類型的函數或者數位。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EFFECT',\r\n 't': 8,\r\n 'd': '根據名義利率及每年的複利計息期數來計算實際年利率。',\r\n 'a': '根據名義利率及每年的複利計息期數來計算實際年利率。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'nominal_rate',\r\n 'detail' : '每年的名義利率。',\r\n 'example': '0.99',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'npery',\r\n 'detail' : '每年的複利計算期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DOLLAR',\r\n 't': 12,\r\n 'd': '將數位格式設定為與語言區域相對應的貨幣格式。',\r\n 'a': '將數位格式設定為與語言區域相對應的貨幣格式。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要設定格式的值。',\r\n 'example': '1.2351',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'decimals',\r\n 'detail' : '[可選 - 預設值為2] - 要顯示的小數位數。\\n\\n如果這是負數,則將數位四捨五入到小數點左側。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DOLLARDE',\r\n 't': 8,\r\n 'd': '將以整數部分和分數部分轉換為以小數部分表示的金額數位',\r\n 'a': '將以整數部分和分數部分轉換為以小數部分表示的金額數位',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'fractional_dollar',\r\n 'detail' : '以整數部份和分數部分表示的數位,用小數點隔開。',\r\n 'example': '100.10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fraction',\r\n 'detail' : '用作分數中的分母的整數。',\r\n 'example': '32',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DOLLARFR',\r\n 't': 8,\r\n 'd': '將小數轉換為分數表示的金額數位。',\r\n 'a': '將小數轉換為分數表示的金額數位。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'decimal_dollar',\r\n 'detail' : '小數。',\r\n 'example': '100.125',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fraction',\r\n 'detail' : '用作分數中的分母的整數。',\r\n 'example': '32',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DB',\r\n 't': 8,\r\n 'd': '使用固定餘額遞減法,返回指定期間內某項固定資產的折舊值。',\r\n 'a': '使用固定餘額遞減法,返回指定期間內某項固定資產的折舊值。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'cost',\r\n 'detail' : '資產原值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'salvage',\r\n 'detail' : '折舊末尾時的值(有時也稱為資產殘值)。',\r\n 'example': '50',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'life',\r\n 'detail' : '資產的折舊期數(有時也稱作資產的使用壽命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'period',\r\n 'detail' : '在使用期限內要計算折舊的折舊期。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'month',\r\n 'detail' : '[可選 - 預設值為12] - 折舊第一年中的月數。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DDB',\r\n 't': 8,\r\n 'd': '用雙倍餘額遞減法,返回指定期間內某項固定資產的折舊值。',\r\n 'a': '用雙倍餘額遞減法,返回指定期間內某項固定資產的折舊值。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'cost',\r\n 'detail' : '资产原值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'salvage',\r\n 'detail' : '折舊末尾時的值(有時也稱為資產殘值)。',\r\n 'example': '50',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'life',\r\n 'detail' : '資產的折舊期數(有時也稱作資產的使用壽命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'period',\r\n 'detail' : '在使用期限內要計算折舊的折舊期。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'factor',\r\n 'detail' : '[可選 - 預設值為2] - 折舊的遞減係數。',\r\n 'example': '2.25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RATE',\r\n 't': 8,\r\n 'd': '返回年金每期的利率。',\r\n 'a': '返回年金每期的利率。',\r\n 'm': [3, 6],\r\n 'p': [{\r\n 'name' : 'nper',\r\n 'detail' : '年金的付款總期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pmt',\r\n 'detail' : '每期的付款金額,在年金週期內不能更改。',\r\n 'example': '-100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '現值即一系列未來付款當前值的總和。',\r\n 'example': '400',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fv',\r\n 'detail' : '[可選 - 預設值為0] - 未來值,或在最後一次付款後希望得到的現金餘額。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '[可選 - 預設值為0] - 指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'guess',\r\n 'detail' : '[可選 - 預設值為0.1] - 預期利率。',\r\n 'example': '0.1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CUMPRINC',\r\n 't': 8,\r\n 'd': '基於等額分期付款和固定利率,計算投資在多個付款期內的累計本金償還額。',\r\n 'a': '基於等額分期付款和固定利率,計算投資在多個付款期內的累計本金償還額。',\r\n 'm': [6, 6],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '利率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'nper',\r\n 'detail' : '總付款期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '年金的現值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'start_period',\r\n 'detail' : '開始累計計算的付款期序號。\\n\\n首期必須大於等於1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'end_period',\r\n 'detail' : '結束累計計算的付款期序號。\\n\\n末期必須大於首期。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPNUM',\r\n 't': 8,\r\n 'd': '返回在結算日和到期日之間的付息次數,向上舍入到最近的整數',\r\n 'a': '返回在結算日和到期日之間的付息次數,向上舍入到最近的整數',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': '02',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SYD',\r\n 't': 8,\r\n 'd': '返回在指定期間內資產按年限總和折舊法計算的折舊。',\r\n 'a': '返回在指定期間內資產按年限總和折舊法計算的折舊。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'cost',\r\n 'detail' : '資產原值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'salvage',\r\n 'detail' : '折舊末尾時的值(有時也稱為資產殘值)。',\r\n 'example': '50',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'life',\r\n 'detail' : '資產的折舊期數(有時也稱作資產的使用壽命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'period',\r\n 'detail' : '在使用期限內要計算折舊的折舊期。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TBILLEQ',\r\n 't': 8,\r\n 'd': '基於貼現率計算美國政府短期債券的等效年化收益率。',\r\n 'a': '基於貼現率計算美國政府短期債券的等效年化收益率。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '債券的結算日期,此日期為債券發行後交付給買家的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '債券的到期或結束日期,届時可將其以面值或票面價值贖回。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'discount',\r\n 'detail' : '債券購買時的貼現率。',\r\n 'example': '2)',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TBILLYIELD',\r\n 't': 8,\r\n 'd': '基於價格計算美國政府短期債券的收益率。',\r\n 'a': '基於價格計算美國政府短期債券的收益率。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '債券的結算日期,此日期為債券發行後交付給買家的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '債券的到期或結束日期,届時可將其以面值或票面價值贖回。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'pr',\r\n 'detail' : '債券的購買價格。',\r\n 'example': '95',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TBILLPRICE',\r\n 't': 8,\r\n 'd': '基於貼現率計算美國政府短期債券的價格。',\r\n 'a': '基於貼現率計算美國政府短期債券的價格。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '債券的結算日期,此日期為債券發行後交付給買家的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '債券的到期或結束日期,届時可將其以面值或票面價值贖回。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'discount',\r\n 'detail' : '債券購買時的貼現率。',\r\n 'example': '0.09',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PV',\r\n 't': 8,\r\n 'd': '基於等額分期付款和固定利率,計算年金投資的現值。',\r\n 'a': '基於等額分期付款和固定利率,計算年金投資的現值。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '各期利率。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'nper',\r\n 'detail' : '年金的付款總期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pmt',\r\n 'detail' : '每期的付款金額,在年金週期內不能更改。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fv',\r\n 'detail' : '[可選] - 未來值,或在最後一次付款後希望得到的現金餘額。',\r\n 'example': 'D2',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '[可選 - 預設值為0] - 指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ACCRINT',\r\n 't': 8,\r\n 'd': '返回定期付息證券的應計利息。',\r\n 'a': '返回定期付息證券的應計利息。',\r\n 'm': [6, 8],\r\n 'p': [{\r\n 'name' : 'issue',\r\n 'detail' : '有價證券的發行日。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'first_interest',\r\n 'detail' : '有價證券的首次計息日。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'rate',\r\n 'detail' : '有價證券的年息票利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'par',\r\n 'detail' : '證券的票面值。',\r\n 'example': '10000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"\"歐洲30/360\"方法\"-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'calc_method',\r\n 'detail' : '[可選 - 默認為TRUE()] - 一個邏輯值,指定當結算日期晚於首次計息日期時用於計算總應計利息的方法。\\n\\n如果值為TRUE,則返回從發行日到結算日的總應計利息。\\n\\n如果值為FALSE,則返回從首次計息日到結算日的應計利息。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ACCRINTM',\r\n 't': 8,\r\n 'd': '返回在到期日支付利息的有價證券的應計利息。',\r\n 'a': '返回在到期日支付利息的有價證券的應計利息。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'issue',\r\n 'detail' : '有價證券的發行日。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的到期日。',\r\n 'example': 'DATE(1969',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'rate',\r\n 'detail' : '有價證券的年息票利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'par',\r\n 'detail' : '證券的票面值。',\r\n 'example': '1000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPDAYBS',\r\n 't': 8,\r\n 'd': '返回從付息期開始到結算日的天數。',\r\n 'a': '返回從付息期開始到結算日的天數。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPDAYS',\r\n 't': 8,\r\n 'd': '返回結算日所在的付息期的天數。',\r\n 'a': '返回結算日所在的付息期的天數。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] -訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPDAYSNC',\r\n 't': 8,\r\n 'd': '返回從結算日到下一票息支付日之間的天數。',\r\n 'a': '返回從結算日到下一票息支付日之間的天數。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPNCD',\r\n 't': 8,\r\n 'd': '計算結算日之後的下一票息或利息派發日期。',\r\n 'a': '計算結算日之後的下一票息或利息派發日期。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '01)',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': 'DATE(2019',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COUPPCD',\r\n 't': 8,\r\n 'd': '計算結算日之前的最後一個票息或利息支付日。',\r\n 'a': '計算結算日之前的最後一個票息或利息支付日。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4 。',\r\n 'example': '01)',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': 'DATE(2019',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FV',\r\n 't': 8,\r\n 'd': '基於等額分期付款和固定利率,計算年金投資的未來價值。',\r\n 'a': '基於等額分期付款和固定利率,計算年金投資的未來價值。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '各期利率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'nper',\r\n 'detail' : '年金的付款總期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pmt',\r\n 'detail' : '各期所應支付的金額,在整個年金期間保持不變。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '[可選 - 預設值為0 ] - 現值,或一系列未來付款的當前值的累積和。',\r\n 'example': '400',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '[可選 - 預設值為0 ] - 指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FVSCHEDULE',\r\n 't': 8,\r\n 'd': '返回應用一系列複利率計算的初始本金的未來值。',\r\n 'a': '返回應用一系列複利率計算的初始本金的未來值。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'principal',\r\n 'detail' : '現值。',\r\n 'example': '10000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'schedule',\r\n 'detail' : '用於計算本金複利的一組利率。\\n\\n利率錶必須是範圍或數組,其中包含要用於計算複利的一組利率。這些利率值應該以十進位小數形式表示,或者使用UNARY_PERCENT以百分比形式表示,即表示為0.09或UNARY_PERCENT(9),而不要表示為9。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'YIELD',\r\n 't': 8,\r\n 'd': '返回定期支付利息的債券的收益率。',\r\n 'a': '返回定期支付利息的債券的收益率。',\r\n 'm': [6, 7],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'rate',\r\n 'detail' : '有價證券的年息票利率。',\r\n 'example': '0.057',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pr',\r\n 'detail' : '有價證券的價格。',\r\n 'example': '95',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'redemption',\r\n 'detail' : '有價證券的清償價值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法 - 此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'YIELDDISC',\r\n 't': 8,\r\n 'd': '基於價格計算折價發行的(不帶息)債券的年收益率。',\r\n 'a': '基於價格計算折價發行的(不帶息)債券的年收益率。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'pr',\r\n 'detail' : '有價證券的價格。',\r\n 'example': '95',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'redemption',\r\n 'detail' : '有價證券的清償價值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法 - 此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NOMINAL',\r\n 't': 8,\r\n 'd': '基於給定的實際利率和年複利期數,返回名義年利率。',\r\n 'a': '基於給定的實際利率和年複利期數,返回名義年利率。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'effect_rate',\r\n 'detail' : '每年的實際利率。',\r\n 'example': '0.85',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'npery',\r\n 'detail' : '每年的複利期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'XIRR',\r\n 't': 8,\r\n 'd': '返回一組不一定定期發生的現金流的內部收益率。',\r\n 'a': '返回一組不一定定期發生的現金流的內部收益率。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'values',\r\n 'detail' : '其中含有投資相關收益或支出的數組或範圍。\\n\\n現金流數額中必須至少包含一項負的和一項正的現金流金額才能計算回報率。',\r\n 'example': 'B2:B25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'dates',\r\n 'detail' : '與現金流數額參數中的現金流對應的日期數組或範圍。',\r\n 'example': 'C2:C25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'guess',\r\n 'detail' : '[可選 - 預設值為0.1] - 對內部回報率的估算值。',\r\n 'example': '250',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MIRR',\r\n 't': 8,\r\n 'd': '返回一系列定期現金流的修改後內部收益率。',\r\n 'a': '返回一系列定期現金流的修改後內部收益率。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'values',\r\n 'detail' : '其中含有投資相關收益或支出的數組或範圍。\\n\\n現金流數額中必須至少包含一項負的和一項正的現金流金額才能計算回報率。',\r\n 'example': 'A2:A25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'finance_rate',\r\n 'detail' : '現金流中使用的資金支付的利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'reinvest_rate',\r\n 'detail' : '將現金流再投資的收益率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'IRR',\r\n 't': 8,\r\n 'd': '返回由值中的數位表示的一系列現金流的內部收益率。 ',\r\n 'a': '返回由值中的數位表示的一系列現金流的內部收益率。 ',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'values',\r\n 'detail' : '其中含有投資相關收益或支出的數組或範圍。\\n\\n現金流數額中必須至少包含一項負的和一項正的現金流金額才能計算回報率。',\r\n 'example': 'A2:A25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'guess',\r\n 'detail' : '[可選 - 默認為0.1] - 內部收益率的估值。',\r\n 'example': '200',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NPV',\r\n 't': 8,\r\n 'd': '使用貼現率和一系列未來支出(負值)和收益(正值)來計算一項投資的淨現值。',\r\n 'a': '使用貼現率和一系列未來支出(負值)和收益(正值)來計算一項投資的淨現值。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '某一期間的貼現率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'value1',\r\n 'detail' : '第一筆支出(負值)和收益(正值)。',\r\n 'example': '200',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2, ...',\r\n 'detail' : '[可選] - 其他支出(負值)和收益(正值)。',\r\n 'example': '250',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'XNPV',\r\n 't': 8,\r\n 'd': '返回一組現金流的淨現值,這些現金流不一定定期發生。',\r\n 'a': '返回一組現金流的淨現值,這些現金流不一定定期發生。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '應用於現金流的貼現率。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'values',\r\n 'detail' : '與dates中的支付時間相對應的一系列現金流。',\r\n 'example': 'B2:B25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'dates',\r\n 'detail' : '與現金流支付相對應的支付日期錶。',\r\n 'example': 'C2:C25',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'CUMIPMT',\r\n 't': 8,\r\n 'd': '基於等額分期付款和固定利率,計算投資在一系列付款期內的累計利息。',\r\n 'a': '基於等額分期付款和固定利率,計算投資在一系列付款期內的累計利息。',\r\n 'm': [6, 6],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '利息率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'nper',\r\n 'detail' : '總付款期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '現值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'start_period',\r\n 'detail' : '開始累計計算的付款期序號。\\n\\n首期必須大於等於1。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'end_period',\r\n 'detail' : '結束累計計算的付款期序號。\\n\\n末期必須大於首期。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '0',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PMT',\r\n 't': 8,\r\n 'd': '用於根據固定付款額和固定利率計算貸款的付款額。',\r\n 'a': '用於根據固定付款額和固定利率計算貸款的付款額。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '貸款利率。',\r\n 'example': '0.08',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'nper',\r\n 'detail' : '該項貸款的付款總數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '現值,或一系列未來付款額現在所值的總額,也叫本金。',\r\n 'example': ' 100000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fv',\r\n 'detail' : '[可選 - 預設值為0] - 未來值,或在最後一次付款後希望得到的現金餘額。',\r\n 'example': 'D2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '[可選 - 預設值為0] - 指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'IPMT',\r\n 't': 8,\r\n 'd': '基於固定利率及等額分期付款管道,返回給定期數內對投資的利息償還額。',\r\n 'a': '基於固定利率及等額分期付款管道,返回給定期數內對投資的利息償還額。',\r\n 'm': [4, 6],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '各期利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'per',\r\n 'detail' : '用於計算其利息數額的期數,必須在1到nper之間。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'nper',\r\n 'detail' : '年金的付款總期數。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '現值,或一系列未來付款的當前值的累積和。',\r\n 'example': '80000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fv',\r\n 'detail' : '[可選 - 預設值為0] - 未來值,或在最後一次付款後希望得到的現金餘額。',\r\n 'example': 'E2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '[可選 - 預設值為0] - 指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PPMT',\r\n 't': 8,\r\n 'd': '返回根據定期固定付款和固定利率而定的投資在已知期間內的本金償付額。',\r\n 'a': '返回根據定期固定付款和固定利率而定的投資在已知期間內的本金償付額。',\r\n 'm': [4, 6],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '各期利率。',\r\n 'example': '0.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'per',\r\n 'detail' : '指定期數,該值必須在 1 到 nper 範圍內。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'nper',\r\n 'detail' : '年金的付款總期數。',\r\n 'example': '3*12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '現值即一系列未來付款當前值的總和。',\r\n 'example': '100000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fv',\r\n 'detail' : '[可選 - 預設值為0] - 未來值,或在最後一次付款後希望得到的現金餘額。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '[可選 - 預設值為0] - 指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'INTRATE',\r\n 't': 8,\r\n 'd': '返回完全投資型證券的利率。',\r\n 'a': '返回完全投資型證券的利率。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'investment',\r\n 'detail' : '有價證券的投資額。',\r\n 'example': '100000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'redemption',\r\n 'detail' : '有價證券到期時的兌換值。',\r\n 'example': '101200',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法-此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法 - 此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法-此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PRICE',\r\n 't': 8,\r\n 'd': '返回定期付息的面值¥100的有價證券的價格。',\r\n 'a': '返回定期付息的面值¥100的有價證券的價格。',\r\n 'm': [6, 7],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'rate',\r\n 'detail' : '有價證券的年息票利率。',\r\n 'example': '0.057',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'yld',\r\n 'detail' : '有價證券的年收益率。',\r\n 'example': '0.065',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'redemption',\r\n 'detail' : '面值¥100的有價證券的清償價值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法 - 此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PRICEDISC',\r\n 't': 8,\r\n 'd': '返回折價發行的面值¥100的有價證券的價格。',\r\n 'a': '返回折價發行的面值¥100的有價證券的價格。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'discount',\r\n 'detail' : '有价证券的贴现率。',\r\n 'example': '0.0525',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'redemption',\r\n 'detail' : '面值¥100的有價證券的清償價值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法 - 此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'PRICEMAT',\r\n 't': 8,\r\n 'd': '返回到期付息的面值¥100的有價證券的價格。',\r\n 'a': '返回到期付息的面值¥100的有價證券的價格。',\r\n 'm': [5, 6],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'issue',\r\n 'detail' : '有價證券的發行日。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'rate',\r\n 'detail' : '有價證券在發行日的利率。',\r\n 'example': '0.061',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'yld',\r\n 'detail' : '有價證券的年收益率。',\r\n 'example': '0.061',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法 - 此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RECEIVED',\r\n 't': 8,\r\n 'd': '返回一次性付息的有價證券到期收回的金額。',\r\n 'a': '返回一次性付息的有價證券到期收回的金額。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'investment',\r\n 'detail' : '有價證券的投資額。',\r\n 'example': '10000000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'discount',\r\n 'detail' : '有價證券的貼現率。',\r\n 'example': '0.0575',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法 - 此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '12',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DISC',\r\n 't': 8,\r\n 'd': '返回有價證券的貼現率。',\r\n 'a': '返回有價證券的貼現率。',\r\n 'm': [4, 5],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'pr',\r\n 'detail' : '有價證券的價格(按面值為¥100計算)。',\r\n 'example': '97.975',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'redemption',\r\n 'detail' : '面值¥100的有價證券的清償價值。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法 - 此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '12',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'NPER',\r\n 't': 8,\r\n 'd': '基於固定利率及等額分期付款管道,返回某項投資的總期數。',\r\n 'a': '基於固定利率及等額分期付款管道,返回某項投資的總期數。',\r\n 'm': [3, 5],\r\n 'p': [{\r\n 'name' : 'rate',\r\n 'detail' : '各期利率。',\r\n 'example': '0.12',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pmt',\r\n 'detail' : '各期所應支付的金額,在整個年金期間保持不變。',\r\n 'example': '500',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'pv',\r\n 'detail' : '現值,或一系列未來付款的當前值的累積和。',\r\n 'example': '40000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'fv',\r\n 'detail' : '[可選 - 預設值為0] - 未來值,或在最後一次付款後希望得到的現金餘額。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'type',\r\n 'detail' : '[可選 - 預設值為0] - 指定各期的付款時間是在期初還是期末。\\n\\n0表示期末;\\n\\n1表示期初。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SLN',\r\n 't': 8,\r\n 'd': '返回一個期間內的資產的直線折舊。',\r\n 'a': '返回一個期間內的資產的直線折舊。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'cost',\r\n 'detail' : '資產原值。',\r\n 'example': '300000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'salvage',\r\n 'detail' : '折舊末尾時的值(有時也稱為資產殘值)。',\r\n 'example': '75000',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'life',\r\n 'detail' : '資產的折舊期數(有時也稱作資產的使用壽命)。',\r\n 'example': '10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DURATION',\r\n 't': 8,\r\n 'd': '返回假設面值¥100的定期付息有價證券的修正期限。',\r\n 'a': '返回假設面值¥100的定期付息有價證券的修正期限。',\r\n 'm': [5, 6],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'coupon',\r\n 'detail' : '有價證券的年息票利率。',\r\n 'example': '0.08',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'yld',\r\n 'detail' : '有價證券的年收益率。',\r\n 'example': '0.09',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法 - 此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MDURATION',\r\n 't': 8,\r\n 'd': '返回假設面值¥100的有價證券的Macauley修正期限。',\r\n 'a': '返回假設面值¥100的有價證券的Macauley修正期限。',\r\n 'm': [5, 6],\r\n 'p': [{\r\n 'name' : 'settlement',\r\n 'detail' : '有價證券的結算日。有價證券結算日是在發行日之後,有價證券賣給購買者的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'maturity',\r\n 'detail' : '有價證券的到期日。到期日是有價證券有效期截止時的日期。',\r\n 'example': 'DATE(2010',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'coupon',\r\n 'detail' : '有價證券的年息票利率。',\r\n 'example': '0.08',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'yld',\r\n 'detail' : '有價證券的年收益率。',\r\n 'example': '0.09',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'frequency',\r\n 'detail' : '年付息次數。\\n\\n如果按年支付,frequency = 1;\\n\\n按半年期支付,frequency = 2;\\n\\n按季支付,frequency = 4。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'basis',\r\n 'detail' : '[可選 - 默認為0] - 訓示要使用哪種天數計算方法。\\n\\n0表示\"美國(NASD)30/360\"方法 - 此方法按照美國全國證券交易商協會標準,假設每月30天、每年360天,並對所輸入的月末日期進行具體調整。\\n\\n1表示\"實際/實際\"方法-此方法計算基於指定日期之間的實際天數和所涉及的年份中的實際天數進行計算。此方法用於美國長期債券,也是在非財經用途方面使用最多的方法。\\n\\n2表示\"實際/360\"方法 - 此方法基於指定日期之間的實際天數進行計算, 但假定每年為360天。\\n\\n3表示\"實際/365\"方法 - 此方法基於指定日期之間的實際天數進行計算,但假定每年為365天。\\n\\n4表示\"歐洲30 / 360\"方法-類似於0,此方法基於每月30天、每年360天進行計算,但按照歐洲金融慣例對月末日期進行調整。',\r\n 'example': '0',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'BIN2DEC',\r\n 't': 9,\r\n 'd': '將二進位數轉換為十進位數。',\r\n 'a': '將二進位數轉換為十進位數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為十進位數的帶符號的10位二進位數值(以字串形式提供)。\\n\\n帶符號的二進位數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n對於此函數,最大的正數輸入值為0111111111,最小的負數輸入值為1000000000。\\n\\n如果所提供的帶符號的二進位數是有效的二進位數,會自動將其轉換為相應的字串輸入。例如,BIN2DEC(100)和BIN2DEC(\"100\")得出的結果相同,均為4。',\r\n 'example': '101',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'BIN2HEX',\r\n 't': 9,\r\n 'd': '將二進位數轉換為十六進位數。',\r\n 'a': '將二進位數轉換為十六進位數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的十六進位數的帶符號的10位二進位數值(以字串形式提供)。\\n\\n帶符號的二進位數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n對於此函數,最大的正數輸入值為0111111111,最小的負數輸入值為1000000000。\\n\\n如果所提供的帶符號的二進位數是有效的二進位數,會自動將其轉換為相應的字串輸入。例如,BIN2HEX(11111)和BIN2HEX(\"11111\")得出的結果相同,均為1F。',\r\n 'example': '101',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] -結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。例如,BIN2HEX(\"11111\",8)所得的結果值為0000001F。\\n\\n如果帶符號的二進位數的最高位為1,則忽略此值;即當提供的帶符號的二進位數大於等於1000000000時忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'BIN2OCT',\r\n 't': 9,\r\n 'd': '二進位數轉換為八進制數。',\r\n 'a': '二進位數轉換為八進制數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的八進制數的帶符號的10位二進位數值(以字串形式提供)。\\n\\n帶符號的二進位數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n對於此函數,最大的正數輸入值為0111111111,最小的負數輸入值為1000000000。\\n\\n如果所提供的帶符號的二進位數是有效的二進位數,會自動將其轉換為相應的字串輸入。例如,BIN2OCT(11111)和BIN2OCT(\"11111\")得出的結果相同,均為37。',\r\n 'example': '101',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] - 結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。例如,BIN2OCT(\"11111\")得到的結果值為00000037。\\n\\n如果帶符號的二進位數的最高位為1,則忽略此值;即當提供的帶符號的二進位數大於等於1000000000時忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEC2BIN',\r\n 't': 9,\r\n 'd': '將十進位數轉換為二進位數。',\r\n 'a': '將十進位數轉換為二進位數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的二進位數的十進位數值(以字串形式提供)。\\n\\n對於此函數,最大的正數輸入值為511,最小的負數輸入值為-512。\\n\\n如果所提供的十進位數是有效的十進位數,會自動將其轉換為相應的字串輸入。例如,DEC2BIN(199)和DEC2BIN(\"199\")得出的結果相同,均為11000111。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] - 結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。\\n\\n如果十進位數為負數,則忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEC2HEX',\r\n 't': 9,\r\n 'd': '將十進位數轉換為十六進位數。',\r\n 'a': '將十進位數轉換為十六進位數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的十六進位數的十進位數值(以字串形式提供)。\\n\\n此函數可接受的最大正數值為549755813887,最小負數值為-549755814888。\\n\\n如果所提供的十進位數是有效的十進位數,會自動將其轉換為相應的字串輸入。例如,DEC2HEX(100)和DEC2HEX(\"100\")得出的結果相同,均為64。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] - 結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。\\n\\n如果十進位數為負數,則忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DEC2OCT',\r\n 't': 9,\r\n 'd': '將十進位數轉換為八進制數。',\r\n 'a': '將十進位數轉換為八進制數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的八進制數的十進位數值(以字串形式提供)。\\n\\n此函數可接受的最大正數值為536870911,最小負數值為-53687092。\\n\\n如果所提供的十進位數是有效的十進位數,會自動將其轉換為相應的字串輸入。例如,DEC2OCT(199)和DEC2OCT(\"199\")得出的結果相同,均為307。',\r\n 'example': '100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] -結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。\\n\\n如果十進位數為負數,則忽略此值 。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HEX2BIN',\r\n 't': 9,\r\n 'd': '將十六進位數轉換為二進位數。',\r\n 'a': '將十六進位數轉換為二進位數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的二進位數的帶符號的40位十六進位數值(以字串形式提供)。\\n\\n帶符號的十六進位數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n此函數可接受的最大正數值為1FF,最小負數值為FFFFFFFE00。\\n\\n如果所提供的帶符號的十六進位數是有效的十六進位數,函數會自動將其轉換為相應的字串輸入。例如,HEX2BIN(199)和HEX2BIN(\"199\")得出的結果相同,均為110011001。',\r\n 'example': '\"f3\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] - 結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。\\n\\n如果帶符號的十六進位數的最高位為1,則忽略此值;即當提供的帶符號的十六進位數大於等於8000000000時忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'HEX2DEC',\r\n 't': 9,\r\n 'd': '將十六進位數轉換為十進位數。',\r\n 'a': '將十六進位數轉換為十進位數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為十進位數的帶符號的40位十六進位數值(以字串形式提供)。\\n\\n帶符號的十六進位數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n此函數可接受的最大正數值為7fffffffff,最小負數值為8000000000。\\n\\n如果所提供的帶符號的十六進位數是有效的十六進位數,函數會自動將其轉換為相應的字串輸入。例如,HEX2DEC(199)和HEX2DEC(\"199\")得出的結果相同,均為409 。',\r\n 'example': '\"f3\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'HEX2OCT',\r\n 't': 9,\r\n 'd': '將十六進位數轉換為八進制數。',\r\n 'a': '將十六進位數轉換為八進制數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的八進制數的帶符號的40位十六進位數值(以字串形式提供)。\\n\\n帶符號的十六進位數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n此函數可接受的最大正數值為1FFFFFFF,最小負數值為FFE0000000。\\n\\n如果所提供的帶符號的十六進位數是有效的十六進位數,函數會自動將其轉換為相應的字串輸入。例如,HEX2OCT(199)和HEX2OCT(\"199\")得出的結果相同,均為631。',\r\n 'example': '\"f3\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] - 結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。\\n\\n如果帶符號的十六進位數的最高位為1,則忽略此值;即當給定的帶符號的十六進位數大於等於8000000000時忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'OCT2BIN',\r\n 't': 9,\r\n 'd': '將八進制數轉換為二進位數。',\r\n 'a': '將八進制數轉換為二進位數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的二進位數的帶符號的30位八進制數值(以字串形式提供)。\\n\\n帶符號的八進制數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n此函數可接受的最大正數值為777,最小負數值為7777777000。\\n\\n如果所提供的帶符號的八進制數是有效的八進制數,函數會自動將其轉換為相應的字串輸入。例如,OCT2BIN(177)和OCT2BIN(\"177\")得出的結果相同,均為1111111。',\r\n 'example': '37',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] - 結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。\\n\\n如果帶符號的八進制數的最高位為1,則忽略此值;即當給定的帶符號的八進制數大於等於4000000000時忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'OCT2DEC',\r\n 't': 9,\r\n 'd': '將八進制數轉換為十進位數。',\r\n 'a': '將八進制數轉換為十進位數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為十進位數的帶符號的30位八進制數值(以字串形式提供)。\\n\\n帶符號的ba進制數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n此函數可接受的最大正數值為3777777777,最小負數值為4000000000。\\n\\n如果所提供的帶符號的八進制數是有效的八進制數,函數會自動將其轉換為相應的字串輸入。例如,OCT2DEC(177)和OCT2DEC(\"177\")得出的結果相同,均為127。',\r\n 'example': '37',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'OCT2HEX',\r\n 't': 9,\r\n 'd': '將八進制數轉換為十六進位數。',\r\n 'a': '將八進制數轉換為十六進位數。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要轉換為帶符號的十六進位數的帶符號的30位八進制數值(以字串形式提供)。\\n\\n帶符號的ba進制數的最高位是符號位;也就是說,負數是以二的補數形式表示的。\\n\\n此函數可接受的最大正數值為3777777777,最小負數值為4000000000。\\n\\n如果所提供的帶符號的八進制數是有效的八進制數,函數會自動將其轉換為相應的字串輸入。例如,OCT2HEX(177)和OCT2HEX(\"177\")得出的結果相同,均為7F。',\r\n 'example': '37',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'places',\r\n 'detail' : '[ 可選 ] - 結果中要確保的有效位數。\\n\\n如果設定的有效位數大於結果中的有效位數,則在結果的左側填充0,使總有效位數達到有效位數。\\n\\n如果帶符號的八進制數的最高位為1,則忽略此值;即當給定的帶符號的八進制數大於等於4000000000時忽略此值。',\r\n 'example': '8',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'COMPLEX',\r\n 't': 9,\r\n 'd': '將實係數及虛係數轉換為 x+yi 或 x+yj 形式的複數。',\r\n 'a': '將實係數及虛係數轉換為 x+yi 或 x+yj 形式的複數。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'real_num',\r\n 'detail' : '複數的實係數。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'i_num',\r\n 'detail' : '複數的虛係數。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'suffix',\r\n 'detail' : '[可選 - 默認為\"i\"] - 複數中虛係數的尾碼。',\r\n 'example': '\"j\"',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangestring'\r\n }]\r\n }, {\r\n 'n': 'IMREAL',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的複數的實係數。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的複數的實係數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'inumber',\r\n 'detail' : '需要計算其實係數的複數。',\r\n 'example': '\"4+5i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMAGINARY',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的複數的虛係數。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的複數的虛係數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'inumber',\r\n 'detail' : '需要計算其虛係數的複數。',\r\n 'example': '\"4+5i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMCONJUGATE',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的複數的共軛複數。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的複數的共軛複數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'inumber',\r\n 'detail' : '需要計算其共軛數的複數。',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMABS',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的複數的絕對值(模)。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的複數的絕對值(模)。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'inumber',\r\n 'detail' : '要計算其絕對值的複數。',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'DELTA',\r\n 't': 9,\r\n 'd': '檢驗兩個值是否相等。如果 number1=number2,則返回1;否則返回0。',\r\n 'a': '檢驗兩個值是否相等。如果 number1=number2,則返回1;否則返回0。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'number1',\r\n 'detail' : '第一個數位。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'number2',\r\n 'detail' : '[可選 - 默認為0] - 第二個數位。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'IMSUM',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 個複數的和。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 個複數的和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : 'inumber1',\r\n 'detail' : '要相加的第一個複數',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'inumber2, …',\r\n 'detail' : '[可選] -要與值1相加的其他複數',\r\n 'example': '\"5-3i\"',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMSUB',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的兩個複數的差。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的兩個複數的差。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'inumber1',\r\n 'detail' : '從(複)數中减去 inumber2。',\r\n 'example': '\"6+5i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'inumber2',\r\n 'detail' : '從 inumber1 中减(複)數。',\r\n 'example': '\"2+3i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMPRODUCT',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 個複數的乘積。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的 1 至 255 個複數的乘積。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : 'inumber1',\r\n 'detail' : '用於計算乘積的第一個複數',\r\n 'example': '\"3+4i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'inumber2, …',\r\n 'detail' : '[可選] -要相乘的其他複數。',\r\n 'example': '\"5-3i\"',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IMDIV',\r\n 't': 9,\r\n 'd': '返回以 x+yi 或 x+yj 文本格式表示的兩個複數的商。',\r\n 'a': '返回以 x+yi 或 x+yj 文本格式表示的兩個複數的商。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'inumber1',\r\n 'detail' : '複數分子或被除數。',\r\n 'example': '\"11+16i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'inumber2',\r\n 'detail' : '複數分母或除數。',\r\n 'example': '\"3+2i\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NOT',\r\n 't': 10,\r\n 'd': '返回某個邏輯值的相反值-\"NOT(TRUE())\"將返回FALSE;\"NOT(FALSE())\"將返回TRUE。',\r\n 'a': '返回某個邏輯值的相反值-\"NOT(TRUE())\"將返回FALSE;\"NOT(FALSE())\"將返回TRUE。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'logical',\r\n 'detail' : '計算結果為TRUE或FALSE的任何值或運算式。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TRUE',\r\n 't': 10,\r\n 'd': '返回邏輯值 TRUE。',\r\n 'a': '返回邏輯值 TRUE。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'FALSE',\r\n 't': 10,\r\n 'd': '返回邏輯值 FALSE。',\r\n 'a': '返回邏輯值 FALSE。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'AND',\r\n 't': 10,\r\n 'd': '所有參數的計算結果為TRUE時,返回TRUE;只要有一個參數的計算結果為FALSE,即返回FALSE。',\r\n 'a': '所有參數的計算結果為TRUE時,返回TRUE;只要有一個參數的計算結果為FALSE,即返回FALSE。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : 'logical1',\r\n 'detail' : '要測試的第一個條件,其計算結果可以為TRUE或FALSE。',\r\n 'example': 'A2 = \"foo\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'logical2,...',\r\n 'detail' : '[可選] - 要測試的其他條件,其計算結果可以為TRUE或FALSE,最多可包含255個條件。',\r\n 'example': 'A3 = \"bar\"',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IFERROR',\r\n 't': 10,\r\n 'd': '如果第一個參數不是錯誤值,就返回第一個參數;否則,返回第二個參數。',\r\n 'a': '如果第一個參數不是錯誤值',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '檢查是否存在錯誤的參數。',\r\n 'example': 'A1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value_if_error',\r\n 'detail' : '公式的計算結果錯誤時返回的值。計算以下錯誤類型:#N/A、#VALUE!、#REF!、#DIV/0!、#NUM!、#NAME?或#NULL!。',\r\n 'example': '\"Error in cell A1\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'IF',\r\n 't': 10,\r\n 'd': '當邏輯運算式的值為TRUE時返回一個值,而當其為FALSE時返回另一個值。',\r\n 'a': '當邏輯運算式的值為TRUE時返回一個值,而當其為FALSE時返回另一個值。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'logical_test',\r\n 'detail' : '一個運算式或對包含運算式的儲存格的引用,該運算式代表某種邏輯值(即TRUE或FALSE)。',\r\n 'example': 'A2 = \"foo\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value_if_true',\r\n 'detail' : '當邏輯運算式為TRUE時的返回值。',\r\n 'example': '\"A2 is foo\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value_if_false',\r\n 'detail' : '[可選 - 默認為空白] - 當邏輯運算式等於FALSE時的函數返回值。',\r\n 'example': '\"A2 was false\"',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'OR',\r\n 't': 10,\r\n 'd': '只要有一個參數的計算結果為TRUE時,返回TRUE;所有參數的計算結果為FALSE,即返回FALSE。',\r\n 'a': '只要有一個參數的計算結果為TRUE時,返回TRUE;所有參數的計算結果為FALSE,即返回FALSE。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : 'logical1',\r\n 'detail' : '要測試的第一個條件,其計算結果可以為TRUE或FALSE。',\r\n 'example': 'A2 = \"foo\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : '邏輯運算式2',\r\n 'detail' : '[可選] - 其他運算式或對包含運算式的儲存格的引用,這些運算式代表某種邏輯值(即TRUE或FALSE)或者可以強制轉換為邏輯值。',\r\n 'example': ' A3 = \"bar\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'NE',\r\n 't': 11,\r\n 'd': '如果指定的值不相等,則返回\"TRUE\";否則返回\"FALSE\"。相當於\"<>\"運算子。',\r\n 'a': '如果指定的值不相等,則返回\"TRUE\";否則返回\"FALSE\"。相當於\"<>\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '第一個值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '要檢查是否與 value1 不相等的值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EQ',\r\n 't': 11,\r\n 'd': '如果指定的值相等,則返回\"TRUE\";否則返回\"FALSE\"。相當於\"=\"運算子。',\r\n 'a': '如果指定的值相等,則返回\"TRUE\";否則返回\"FALSE\"。相當於\"=\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '第一個值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '要檢查是否與value1相等的值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'GT',\r\n 't': 11,\r\n 'd': '如果第一個參數嚴格大於第二個,則返回TRUE;否則返回FALSE。相當於' > '運算子。',\r\n 'a': '如果第一個參數嚴格大於第二個,則返回TRUE;否則返回FALSE。相當於' > '運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '要測試其是否大於 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '第二個值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'GTE',\r\n 't': 11,\r\n 'd': '如果第一個參數大於或等於第二個,則返回TRUE;否則返回FALSE。相當於\">=\"運算子。',\r\n 'a': '如果第一個參數大於或等於第二個,則返回TRUE;否則返回FALSE。相當於\">=\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '要测试其是否大于等于 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '第二個值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LT',\r\n 't': 11,\r\n 'd': '如果第一個參數嚴格小於第二個,則返回TRUE;否則返回FALSE。相當於\"<\"運算子。',\r\n 'a': '如果第一個參數嚴格小於第二個,則返回TRUE;否則返回FALSE。相當於\"<\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '要测试其是否小于 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '第二個值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LTE',\r\n 't': 11,\r\n 'd': '如果第一個參數小於或等於第二個,則返回TRUE;否則返回FALSE。相當於\"<=\"運算子。',\r\n 'a': '如果第一個參數小於或等於第二個,則返回TRUE;否則返回FALSE。相當於\"<=\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '要测试其是否小于等于 value2 的值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '第二個值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ADD',\r\n 't': 11,\r\n 'd': '返回兩個數值之和。相當於\"+\"運算子。',\r\n 'a': '返回兩個數值之和。相當於\"+\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '第一個加數。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '第二個加數。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MINUS',\r\n 't': 11,\r\n 'd': '返回兩個數值之差。相當於\"-\"運算子。',\r\n 'a': '返回兩個數值之差。相當於\"-\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '被減數,即要對其計减的數值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '減數,即要從value1中减除的數值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MULTIPLY',\r\n 't': 11,\r\n 'd': '返回兩個數的乘積。相當於\"*\"運算子。',\r\n 'a': '返回兩個數的乘積。相當於\"*\"運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '第一個乘數。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '第二個乘數。',\r\n 'example': 'B2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DIVIDE',\r\n 't': 11,\r\n 'd': '返回兩個參數相除所得的結果。相當於`/`運算子。',\r\n 'a': '返回兩個參數相除所得的結果。相當於`/`運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : '要被除的數值。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n },\r\n {\r\n 'name' : 'value2',\r\n 'detail' : '用於除其他數的數值。\\n\\n除數不得為0。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CONCAT',\r\n 't': 11,\r\n 'd': '返回兩個值的串聯。相當於`&`運算子。',\r\n 'a': '返回兩個值的串聯。相當於`&`運算子。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value1',\r\n 'detail' : 'value2 將附於其後的值。',\r\n 'example': '\"de\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'value2',\r\n 'detail' : '要附於 value1 之後的值。',\r\n 'example': '\"mystify\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'UNARY_PERCENT',\r\n 't': 11,\r\n 'd': '返回按百分比解釋的數值。例如,\"UNARY_PERCENT(100)\"等於1。',\r\n 'a': '返回按百分比解釋的數值。例如,\"UNARY_PERCENT(100)\"等於1。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要作為百分比解釋的數值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CONCATENATE',\r\n 't': 12,\r\n 'd': '將兩個或多個文字字串聯接為一個字串。',\r\n 'a': '將兩個或多個文字字串聯接為一個字串。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : 'text1',\r\n 'detail' : '初始字串。',\r\n 'example': '\"Super\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n },\r\n {\r\n 'name' : 'text2…',\r\n 'detail' : '[可選] - 要按順序連接在一起的其他字串。',\r\n 'example': '\"calla\"',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CODE',\r\n 't': 12,\r\n 'd': '返回所提供的字串中首字元的Unicode映射值。',\r\n 'a': '返回所提供的字串中首字元的Unicode映射值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要返回其首字元的Unicode映射值的字串。',\r\n 'example': '\"a\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CHAR',\r\n 't': 12,\r\n 'd': '按照當前Unicode編碼表,將數位轉換為對應的字元。',\r\n 'a': '按照當前Unicode編碼表,將數位轉換為對應的字元。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '介於1到255之間的數位。',\r\n 'example': '97',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ARABIC',\r\n 't': 12,\r\n 'd': '將羅馬數字轉換為阿拉伯數字。',\r\n 'a': '將羅馬數字轉換為阿拉伯數字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要轉換格式的羅馬數字',\r\n 'example': '\"XIV\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ROMAN',\r\n 't': 12,\r\n 'd': '將數位格式設定為羅馬數字形式。',\r\n 'a': '將數位格式設定為羅馬數字形式。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要設定格式的數位,介於1到3999之間(包括這兩個數位)。',\r\n 'example': '499',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'REGEXEXTRACT',\r\n 't': 12,\r\n 'd': '按照規則運算式選取匹配的子串。',\r\n 'a': '按照規則運算式選取匹配的子串。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '輸入文字。',\r\n 'example': '\"Needle in a haystack\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'regular_expression',\r\n 'detail' : '此函數將返回文字中符合此運算式的第一個子串。',\r\n 'example': '\".e{2}dle\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REGEXMATCH',\r\n 't': 12,\r\n 'd': '判斷一段文字是否與規則運算式相匹配。',\r\n 'a': '判斷一段文字是否與規則運算式相匹配。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要用規則運算式測試的文字。',\r\n 'example': '\"Spreadsheets\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'regular_expression',\r\n 'detail' : '用來測試文字的規則運算式。',\r\n 'example': '\"S.r\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REGEXREPLACE',\r\n 't': 12,\r\n 'd': '使用規則運算式將文字字串中的一部分替換為其他文字字串。',\r\n 'a': '使用規則運算式將文字字串中的一部分替換為其他文字字串。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要對其局部進行替換操作的文字。',\r\n 'example': '\"Spreadsheets\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'regular_expression',\r\n 'detail' : '規則運算式。text中所有匹配的實例都將被替換。',\r\n 'example': '\"S.*d\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'replacement',\r\n 'detail' : '要插入到原有文字中的文字。',\r\n 'example': '\"Bed\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'T',\r\n 't': 12,\r\n 'd': '返回文本格式的字串參數。',\r\n 'a': '返回文本格式的字串參數。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要轉換為文字的參數。\\n\\n如果值為文字,T將返回值本身。\\n\\n如果值為指向包含文字的儲存格的引用,T將返回值中的內容。\\n\\n如果值為錯誤值或包含錯誤值的儲存格,T將返回該錯誤值。\\n\\n對於所有其他情况,T將返回空串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FIXED',\r\n 't': 12,\r\n 'd': '以固定的小數位數設定數位的格式。',\r\n 'a': '以固定的小數位數設定數位的格式。',\r\n 'm': [1, 3],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '要進行舍入並轉換為文字的數位。',\r\n 'example': '3.141592653',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'decimals',\r\n 'detail' : '[可選-預設值為2] - 結果中要顯示的小數位數。\\n\\n如果數值的有效位數小於小數位數,將以零填充。如果數值的有效位數大於小數位數,則將其舍入到所需的小數位數而不是將其截斷。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'no_commas',\r\n 'detail' : '[可選-預設值為FALSE()] - 一個邏輯值,如果為TRUE(),則會禁止FIXED在返回的文字中包含逗號。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FIND',\r\n 't': 12,\r\n 'd': '返回字串在文字中首次出現的位置(區分大小寫)。',\r\n 'a': '返回字串在文字中首次出現的位置(區分大小寫)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'find_text',\r\n 'detail' : '要在要蒐索的文字中查找的字串。',\r\n 'example': '\"n\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'within_text',\r\n 'detail' : '要在其中蒐索蒐索字串的首次出現位置的文字。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'start_num',\r\n 'detail' : '[可選-預設值為1] - 要在要蒐索的文字中開始蒐索的字元位置。',\r\n 'example': '14',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'FINDB',\r\n 't': 12,\r\n 'd': '返回某個字串在文字中首次出現的位置(每個雙位元組字元占兩個位置)。',\r\n 'a': '返回某個字串在文字中首次出現的位置(每個雙位元組字元占兩個位置)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'find_text',\r\n 'detail' : '要在要蒐索的文字中查找的字串。',\r\n 'example': '\"新\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'within_text',\r\n 'detail' : '要在其中蒐索蒐索字串的首次出現位置的文字。',\r\n 'example': '\"農曆新年\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'start_num',\r\n 'detail' : '[可選-預設值為1] - 要在要蒐索的文字中開始蒐索的字元位置。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'JOIN',\r\n 't': 12,\r\n 'd': '將一個或多個使用指定定界符的一維數組的元素連接到一起。',\r\n 'a': '將一個或多個使用指定定界符的一維數組的元素連接到一起。',\r\n 'm': [2, 255],\r\n 'p': [{\r\n 'name' : 'separator',\r\n 'detail' : '置於相互連接的值之間的字元或字串。\\n\\n定界符可以為空,例如JOIN(,{1,2,3})。',\r\n 'example': '\"and-a\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'array1',\r\n 'detail' : '要使用定界符連接的一個或多個值。',\r\n 'example': '{1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'array2,…',\r\n 'detail' : '[可選] - 要使用定界符連接的其他值或數組。',\r\n 'example': '2',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LEFT',\r\n 't': 12,\r\n 'd': '從文字字串的第一個字元開始返回指定個數的字元。',\r\n 'a': '從文字字串的第一個字元開始返回指定個數的字元。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '包含要選取的字元的文字字串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'num_chars',\r\n 'detail' : '[可選-預設值為1] - 指定要由LEFT選取的字元的數量。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'RIGHT',\r\n 't': 12,\r\n 'd': '根據所指定的字元數返回文字字串中最後一個或多個字元。',\r\n 'a': '根據所指定的字元數返回文字字串中最後一個或多個字元。',\r\n 'm': [1, 2],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '包含要選取的字元的文字字串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'num_chars',\r\n 'detail' : '[可選-預設值為1] - 指定要由RIGHT選取的字元的數量。',\r\n 'example': '2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MID',\r\n 't': 12,\r\n 'd': '返回文字字串中從指定位置開始的特定數目的字元。',\r\n 'a': '返回文字字串中從指定位置開始的特定數目的字元。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '包含要選取的字元的文字字串。',\r\n 'example': '\"get this\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'start_num',\r\n 'detail' : '要從字串中開始選取的位置。字串中第一個字元的索引為1。',\r\n 'example': '5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'num_chars',\r\n 'detail' : '指定要由MID選取的字元的數量。\\n\\n如果選取的字元數尚不足選取長度個字元時就到達了字串尾部,則MID返回從開始位置到字串尾部的字元。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'LEN',\r\n 't': 12,\r\n 'd': '返回給定字串的長度。',\r\n 'a': '返回給定字串的長度。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要返回其長度的字串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LENB',\r\n 't': 12,\r\n 'd': '返回文字中所包含的字元數。與雙位元組字元集(DBCS)一起使用。',\r\n 'a': '返回文字中所包含的字元數。與雙位元組字元集(DBCS)一起使用。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要返回其位元組數的字串。(一個漢字為兩個位元組數)',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LOWER',\r\n 't': 12,\r\n 'd': '將指定字串中的字母轉換為小寫。',\r\n 'a': '將指定字串中的字母轉換為小寫。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要轉換為小寫的字串。',\r\n 'example': '\"LOREM IPSUM\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'UPPER',\r\n 't': 12,\r\n 'd': '將指定字串中的字母轉換為大寫。',\r\n 'a': '將指定字串中的字母轉換為大寫。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要轉換為大寫的字串。',\r\n 'example': '\"lorem ipsum\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'EXACT',\r\n 't': 12,\r\n 'd': '比較兩個字串是否相同。',\r\n 'a': '比較兩個字串是否相同。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'text1',\r\n 'detail' : '要比較的第一個字串。',\r\n 'example': 'A1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'text2',\r\n 'detail' : '要比較的第二個字串。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REPLACE',\r\n 't': 12,\r\n 'd': '將文字字串的一部分替換為其他文字字串。',\r\n 'a': '將文字字串的一部分替換為其他文字字串。',\r\n 'm': [4, 4],\r\n 'p': [{\r\n 'name' : 'old_text',\r\n 'detail' : '要對其局部進行替換操作的文字。',\r\n 'example': '\"Spreadsheets\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'start_num',\r\n 'detail' : '開始進行替換操作的位置(文字開頭位置為1)。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'num_chars',\r\n 'detail' : '要在文字中替換的字元個數。',\r\n 'example': '6',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'new_text',\r\n 'detail' : '要插入到原有文字中的文字。',\r\n 'example': '\"Bed\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'REPT',\r\n 't': 12,\r\n 'd': '返回指定文字的多次重複。',\r\n 'a': '返回指定文字的多次重複。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要重複的字元或字串。',\r\n 'example': '\"ha\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'number_times',\r\n 'detail' : '要重複的文字要在返回值中出現的次數。\\n\\n最大重複次數為100。即使重複次數大於100,REPT也僅將相應文字重複100次。',\r\n 'example': '4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SEARCH',\r\n 't': 12,\r\n 'd': '返回字串在文字中首次出現的位置(不區分大小寫)。',\r\n 'a': '返回字串在文字中首次出現的位置(不區分大小寫)。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'find_text',\r\n 'detail' : '要在要蒐索的文字中查找的字串。',\r\n 'example': '\"n\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'within_text',\r\n 'detail' : '要在其中蒐索蒐索字串的首次出現位置的文字。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'start_num',\r\n 'detail' : '[可選-預設值為1 ] - 要在要蒐索的文字中開始蒐索的字元位置。',\r\n 'example': '14',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUBSTITUTE',\r\n 't': 12,\r\n 'd': '在文字字串中用new_text替換old_text。',\r\n 'a': '在文字字串中用new_text替換old_text。',\r\n 'm': [3, 4],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '需要替換其中字元的文字,或對含有文字(需要替換其中字元)的儲存格的引用。',\r\n 'example': '\"search for it\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'old_text',\r\n 'detail' : '需要替換的文字。',\r\n 'example': '\"search for\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'new_text',\r\n 'detail' : '用於替換old_text的文字。',\r\n 'example': '\"Google\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'instance_num',\r\n 'detail' : '[可選] - 指定要用new_text替換old_text的事件。如果指定了instance_num,則只有滿足要求的old_text被替換。否則,文字中出現的所有old_text都會更改為new_text。',\r\n 'example': '3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'CLEAN',\r\n 't': 12,\r\n 'd': '移除文字中的不可列印ASCII字元後將其返回。',\r\n 'a': '移除文字中的不可列印ASCII字元後將其返回。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要移除其中不可列印字元的文字。',\r\n 'example': '\"AF\"&CHAR(31)',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TEXT',\r\n 't': 12,\r\n 'd': '按照指定格式將數位轉換為文字。',\r\n 'a': '按照指定格式將數位轉換為文字。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要設定格式的數位、日期或時間。',\r\n 'example': '1.23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'format_text',\r\n 'detail' : '以括弧括起來的模式串,將按該模式設定數位的格式。\\n\\n0表示在數值位數少於格式指定的位數時必定以零填充。例如,TEXT(12.3,“000.00\")將返回012.30。當數值的小數位數超過模式指定的小數位數時,四捨五入為指定的小數位數。例如,TEXT(12.305,“00.00\")將返回12.31。\\n\\n#類似於0,但並不是在小數點的兩側都以零填充。例如,TEXT(12.3,“###.##\")將返回12.3。',\r\n 'example': '\"$0.00\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TRIM',\r\n 't': 12,\r\n 'd': '删除指定字串前後的空格。',\r\n 'a': '删除指定字串前後的空格。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要修剪的字串或指向包含該字串的儲存格的引用。',\r\n 'example': '\"lorem ipsum\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'VALUE',\r\n 't': 12,\r\n 'd': '將可識別的任何日期、時間或數位格式的字串轉換為數位。',\r\n 'a': '將可識別的任何日期、時間或數位格式的字串轉換為數位。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '包含要轉換的值的字串。',\r\n 'example': '\"123\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'PROPER',\r\n 't': 12,\r\n 'd': '將指定字串中每個單詞的首字母轉為大寫。',\r\n 'a': '將指定字串中每個單詞的首字母轉為大寫。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'text',\r\n 'detail' : '要轉換的文字,其中每個單詞的首字母都將轉為大寫,所有其他字母則轉為小寫。',\r\n 'example': '\"united states\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'CONVERT',\r\n 't': 13,\r\n 'd': '將數位從一種度量系統轉換為另一種度量系統。',\r\n 'a': '將數位從一種度量系統轉換為另一種度量系統。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'number',\r\n 'detail' : '是以from_unit為組織的需要進行轉換的數值。',\r\n 'example': '5.1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'from_unit',\r\n 'detail' : '是數值的組織。',\r\n 'example': '\"g\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'to_unit',\r\n 'detail' : '是結果的組織。',\r\n 'example': '\"kg\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'SUMX2MY2',\r\n 't': 14,\r\n 'd': '返回兩數組中對應數值的平方差之和。',\r\n 'a': '返回兩數組中對應數值的平方差之和。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array_x',\r\n 'detail' : '第一個數組或數值區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'array_y',\r\n 'detail' : '第二個數組或數值區域。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMX2PY2',\r\n 't': 14,\r\n 'd': '返回兩數組中對應數值的平方和之和。',\r\n 'a': '返回兩數組中對應數值的平方和之和。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array_x',\r\n 'detail' : '第一個數組或數值區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'array_y',\r\n 'detail' : '第二個數組或數值區域。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMXMY2',\r\n 't': 14,\r\n 'd': '返回兩數組中對應數值之差的平方和。',\r\n 'a': '返回兩數組中對應數值之差的平方和。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array_x',\r\n 'detail' : '第一個數組或數值區域。',\r\n 'example': 'A2:A100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'array_y',\r\n 'detail' : '第二個數組或數值區域。',\r\n 'example': 'B2:B100',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TRANSPOSE',\r\n 't': 14,\r\n 'd': '將數組或儲存格範圍的行列轉置。',\r\n 'a': '將數組或儲存格範圍的行列轉置。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '要將其行列互換的數組或範圍。',\r\n 'example': '{1,2}',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'TREND',\r\n 't': 14,\r\n 'd': '返回線性趨勢值。',\r\n 'a': '返回線性趨勢值。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name' : 'known_y',\r\n 'detail' : '關係運算式y = mx + b 中已知的y值集合。\\n\\n如果known_y為二維陣列或範圍,則known_x的維數必須與之相同,或者省略此參數。\\n\\n如果known_y為一維數組或範圍,known_x則可代表二維陣列或範圍中的多個引數。也就是說,如果known_y為單行,則將known_x中的每行解釋為各自獨立的值,類似情况也適用於known_y為單列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'known_x',\r\n 'detail' : '[可選-默認該數組為{1,2,3,…},其大小與known_y相同] -關係運算式y = mx + b 中已知的可選x值集合。\\n\\n如果known_y為一維數組或範圍,known_x則可代表二維陣列或範圍中的多個引數。也就是說,如果known_y為單行,則將known_x中的每行解釋為各自獨立的值,類似情况也適用於known_y為單列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'new_x',\r\n 'detail' : '[可選 - 默認與known_x相同] - 需要函數TREND返回對應y值的新x值。',\r\n 'example': 'A11:A13',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'const',\r\n 'detail' : '[可選 - 預設值為TRUE()] - 一個邏輯值,用於指定是否將常數b強制設為0。\\n\\nTRUE()表示b將按正常計算;\\n\\nFALSE()表示b將被設為0(零),m 將被調整以使y = mx。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FREQUENCY',\r\n 't': 14,\r\n 'd': '計算數值在某個區域內的出現頻率,然後返回一個垂直數組。',\r\n 'a': '計算數值在某個區域內的出現頻率,然後返回一個垂直數組。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'data_array',\r\n 'detail' : '要對其頻率進行計數的一組數值或對這組數值的引用。',\r\n 'example': 'A2:A40',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'bins_array',\r\n 'detail' : '要將data_array中的值插入到的間隔數組或對間隔的引用。\\n\\n為清晰起見,應將類別排序,但如果未排序,FREQUENCY會在內部對這些指定的值進行排序並返回正確結果。',\r\n 'example': 'B2:B5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'GROWTH',\r\n 't': 14,\r\n 'd': '使用現有數據計算預測的指數等比。',\r\n 'a': '使用現有數據計算預測的指數等比。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name' : 'known_y',\r\n 'detail' : '關係運算式y = b*m^x 中已知的y值集合。\\n\\n如果已知數據_y為二維陣列或範圍,則已知數據_x的維數必須與之相同,或者省略此參數。\\n\\n如果已知數據_y為一維數組或範圍,已知數據_x則可代表二維陣列或範圍中的多個引數。也就是說,如果已知數據_y為單行,則將已知數據_x中的每行解釋為各自獨立的值,類似情况也適用於已知數據_y為單列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'known_x',\r\n 'detail' : '[可選 - 默認該數組為{1,2,3,…},其大小與known_y相同] - 關係運算式y = b*m^x 中已知的可選x值集合。\\n\\n如果已知數據_y為一維數組或範圍,已知數據_x則可代表二維陣列或範圍中的多個引數。也就是說,如果已知數據_y為單行,則將已知數據_x中的每行解釋為各自獨立的值,類似情况也適用於已知數據_y為單列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'new_x',\r\n 'detail' : '[可選 - 默認與known_x相同] - 需要函數GROWTH返回對應y值的新x值。',\r\n 'example': 'A11:A13',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'const',\r\n 'detail' : '[可選 - 預設值為TRUE()] - 一個邏輯值,用於指定是否將常數b強制設為1。\\n\\nTRUE()表示b將按正常計算;\\n\\nFALSE()表示b將被設為1,m將被調整以使y = m^x。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LINEST',\r\n 't': 14,\r\n 'd': '可通過使用最小二乘法計算與現有數據最佳擬合的直線,來計算某直線的統計值,然後返回描述此直線的數組。',\r\n 'a': '可通過使用最小二乘法計算與現有數據最佳擬合的直線,來計算某直線的統計值,然後返回描述此直線的數組。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name' : 'known_y',\r\n 'detail' : '關係運算式y = mx + b 中已知的y值集合。\\n\\n如果known_y為二維陣列或範圍,則known_x的維數必須與之相同,或者省略此參數。\\n\\n如果known_y為一維數組或範圍,known_x則可代表二維陣列或範圍中的多個引數。也就是說,如果known_y為單行,則將known_x中的每行解釋為各自獨立的值,類似情况也適用於known_y為單列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'known_x',\r\n 'detail' : '[可選 - 默認該數組為{1,2,3,…},其大小與known_y相同] - 關係運算式y = mx + b中已知的可選x值集合。\\n\\n如果known_y為一維數組或範圍,known_x則可代表二維陣列或範圍中的多個引數。也就是說,如果known_y為單行,則將known_x中的每行解釋為各自獨立的值,類似情况也適用於known_y為單列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'const',\r\n 'detail' : '[可選 - 預設值為TRUE()] - 一個邏輯值,用於指定是否將常數b強制設為0。\\n\\nTRUE()表示b將按正常計算;\\n\\nFALSE()表示b將被設為0(零),m將被調整以使y = mx。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'stats',\r\n 'detail' : '[可選 - 預設值為FALSE()] - 一個邏輯值,用於指定是否返回附加回歸統計值。\\n\\n如果詳細為TRUE,除了對應於每個引數的一組線性係數和y截距之外,LINEST還返回以下資訊:\\n\\n每項係數和截距的標準誤差、\\n\\n限定係數(介於0和1之間,1表示完全相關)、\\n\\n因變數值的標准誤差、\\n\\nF統計或F觀測值,訓示所觀測到的因變數和引數變數之間的關係是隨機的還是線性的、\\n\\n自由度,用於在參照錶中查找F統計值以估算可信度、\\n\\n回歸平方和,以及\\n\\n殘差平方和。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'LOGEST',\r\n 't': 14,\r\n 'd': '在回歸分析中,計算最符合數據的指數回歸擬合曲線,並返回描述該曲線的數值數組。',\r\n 'a': '在回歸分析中,計算最符合數據的指數回歸擬合曲線,並返回描述該曲線的數值數組。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name' : 'known_y',\r\n 'detail' : '關係運算式y = mx + b 中已知的y值集合。\\n\\n如果known_y為二維陣列或範圍,則known_x的維數必須與之相同,或者省略此參數。\\n\\n如果known_y為一維數組或範圍,known_x則可代表二維陣列或範圍中的多個引數。也就是說,如果known_y為單行,則將known_x中的每行解釋為各自獨立的值,類似情况也適用於known_y為單列的情况。',\r\n 'example': 'B2:B10',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'known_x',\r\n 'detail' : '[可選 - 默認該數組為{1,2,3,…},其大小與known_y相同] - 關係運算式y = mx + b中已知的可選x值集合。\\n\\n如果known_y為一維數組或範圍,known_x則可代表二維陣列或範圍中的多個引數。也就是說,如果known_y為單行,則將known_x中的每行解釋為各自獨立的值,類似情况也適用於known_y為單列的情况。',\r\n 'example': 'A2:A10',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'const',\r\n 'detail' : '[可選 - 預設值為TRUE()] - 一個邏輯值,用於指定是否將常數b強制設為0。\\n\\nTRUE()表示b將按正常計算;\\n\\nFALSE()表示b將被設為0(零),m將被調整以使y = mx。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'stats',\r\n 'detail' : '[可選 - 預設值為FALSE()] - 一個邏輯值,用於指定是否返回附加回歸統計值。\\n\\n如果詳細為TRUE,則除了為每個引數和係數b返回一組指數值之外,LOGEST還將返回以下數據:\\n\\n每項指數和係數的標準誤差、\\n\\n限定係數(介於0和1之間,1表示完全相關)、\\n\\n因變數值的標准誤差、\\n\\nF統計或F觀測值,訓示所觀測到的因變數和引數之間的關係是隨機的還是指數的、\\n\\n自由度-用於在參照錶中查找F統計值以估算可信度、\\n\\n回歸平方和,以及\\n\\n殘差平方和。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'MDETERM',\r\n 't': 14,\r\n 'd': '返回一個數組的矩陣行列式的值。',\r\n 'a': '返回一個數組的矩陣行列式的值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '行數和列數相等的數值數組。',\r\n 'example': 'A1:D4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MINVERSE',\r\n 't': 14,\r\n 'd': '返回數組中存儲的矩陣的逆矩陣。',\r\n 'a': '返回數組中存儲的矩陣的逆矩陣。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '行數和列數相等的數值數組。',\r\n 'example': 'A1:D4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'MMULT',\r\n 't': 14,\r\n 'd': '返回兩個數組的矩陣乘積。結果矩陣的行數與array1的行數相同,矩陣的列數與array2的列數相同。',\r\n 'a': '返回兩個數組的矩陣乘積。結果矩陣的行數與array1的行數相同,矩陣的列數與array2的列數相同。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'array1',\r\n 'detail' : '要進行矩陣乘法運算的第一個矩陣數組。\\n\\narray1列數必須與array2的行數相同',\r\n 'example': 'A1:B3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'array2',\r\n 'detail' : '要進行矩陣乘法運算的第二個矩陣數組。\\n\\narray2的行數必須與array1列數相同',\r\n 'example': 'C1:F2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SUMPRODUCT',\r\n 't': 14,\r\n 'd': '在給定的幾組數組中,將數組間對應的元素相乘,並返回乘積之和。',\r\n 'a': '在給定的幾組數組中,將數組間對應的元素相乘,並返回乘積之和。',\r\n 'm': [1, 255],\r\n 'p': [{\r\n 'name' : 'array1',\r\n 'detail' : '其相應元素需要進行相乘並求和的第一個數組參數。',\r\n 'example': 'A2:C5',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'array2',\r\n 'detail' : '[可選] - 其相應元素需要進行相乘並求和的其它數組參數。',\r\n 'example': 'D2:F5',\r\n 'require': 'o',\r\n 'repeat' : 'y',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'ISFORMULA',\r\n 't': 15,\r\n 'd': '檢查公式是否位於引用的儲存格中。',\r\n 'a': '檢查公式是否位於引用的儲存格中。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'cell',\r\n 'detail' : '要檢查是否存在公式的儲存格。\\n\\n如果 cell 為包含公式的儲存格,則 ISFORMULA 將返回TRUE。如果 cell 為相應儲存格範圍,則當該範圍內的首個儲存格包含公式時,系統會返回TRUE。如果是任何其他值,系統都將返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'CELL',\r\n 't': 15,\r\n 'd': '返回有關儲存格的格式、位置或內容的資訊。',\r\n 'a': '返回有關儲存格的格式、位置或內容的資訊。',\r\n 'm': [2, 2],\r\n 'p': [{\r\n 'name' : 'info_type',\r\n 'detail' : '一個文字值,指定要返回的儲存格資訊的類型。',\r\n 'example': '\"type\"',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'reference',\r\n 'detail' : '需要其相關資訊的儲存格。',\r\n 'example': 'C2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'NA',\r\n 't': 15,\r\n 'd': '返回錯誤值#N/A。',\r\n 'a': '返回錯誤值#N/A。',\r\n 'm': [0, 0],\r\n 'p': []\r\n }, {\r\n 'n': 'ERROR_TYPE',\r\n 't': 15,\r\n 'd': '返回與其他儲存格中的錯誤值相對應的數位。',\r\n 'a': '返回與其他儲存格中的錯誤值相對應的數位。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'error_val',\r\n 'detail' : '用於查找錯誤號的儲存格,雖然您也可以直接提供錯誤值。',\r\n 'example': 'A3',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISBLANK',\r\n 't': 15,\r\n 'd': '檢查所引用的儲存格是否為空。',\r\n 'a': '檢查所引用的儲存格是否為空。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '對要檢查其是否為空的儲存格的引用。\\n\\n如果是空儲存格,則TRUE;否則返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'ISERR',\r\n 't': 15,\r\n 'd': '檢查某個值是否為#N/A以外的錯誤值。',\r\n 'a': '檢查某個值是否為#N/A以外的錯誤值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要驗證其是否為#N/A以外的錯誤類型的值。\\n\\n如果值是除#N/A之外的任何錯誤(包括#DIV/0!、#NAME?、#NULL!、#NUM!、#VALUE!和#REF!),ISERR將返回TRUE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISERROR',\r\n 't': 15,\r\n 'd': '檢查某個值是否為錯誤值。',\r\n 'a': '檢查某個值是否為錯誤值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要驗證其是否為錯誤類型的值。\\n\\n只要值是某種錯誤值(包括#DIV/0!、#N/A、#NAME?、#NULL!、#NUM!、#VALUE!和#REF!),ISERROR就會返回TRUE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISLOGICAL',\r\n 't': 15,\r\n 'd': '檢查某個值是TRUE還是FALSE。',\r\n 'a': '檢查某個值是TRUE還是FALSE。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要驗證其為邏輯 TRUE 還是邏輯 FALSE 的值。\\n\\n*如果值為TRUE或FALSE,或為指向值為TRUE或FALSE的儲存格的引用,ISLOGICAL將返回TRUE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISNA',\r\n 't': 15,\r\n 'd': '檢查某個值是否為錯誤值#N/A。',\r\n 'a': '檢查某個值是否為錯誤值#N/A。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要與錯誤值#N/A進行比較的值。\\n\\n*如果值為#N/A或指向包含#N/A的儲存格的引用,則ISNA將返回TRUE,否則返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISNONTEXT',\r\n 't': 15,\r\n 'd': '檢查某個值是否為非文字。',\r\n 'a': '檢查某個值是否為非文字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要檢查的文字。\\n\\n*如果參數為文字值或指向包含文字的儲存格的引用,ISNONTEXT將返回FALSE,否則返回TRUE。\\n\\n當值為指向空儲存格的引用時,ISNONTEXT會返回TRUE。\\n\\n當值為空字串時,ISNONTEXT將返回FALSE,因為空串被視作文字。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISNUMBER',\r\n 't': 15,\r\n 'd': '檢查某個值是否為數位。',\r\n 'a': '檢查某個值是否為數位。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要驗證其是否為數位的值。\\n\\n*如果參數為數位或指向內容為數位值的儲存格的引用,ISNUMBER將返回TRUE,否則返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'ISREF',\r\n 't': 15,\r\n 'd': '檢查某個值是否為有效的儲存格引用。',\r\n 'a': '檢查某個值是否為有效的儲存格引用。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要驗證其是否為儲存格引用的值。\\n\\n*如果參數是有效的儲存格引用,ISREF將返回TRUE,否則返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'ISTEXT',\r\n 't': 15,\r\n 'd': '檢查某個值是否為文字。',\r\n 'a': '檢查某個值是否為文字。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要驗證其是否為文字的值。\\n\\n如果參數為文字值或指向包含文字值的儲存格的引用,ISTEXT將返回TRUE,否則返回FALSE。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TYPE',\r\n 't': 15,\r\n 'd': '返回數值的類型。',\r\n 'a': '返回數值的類型。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要確定其類型的數據。\\n\\n數位返回1;\\n\\n文字返回2;\\n\\n邏輯值返回4;\\n\\n錯誤值返回16;\\n\\n數組返回64;',\r\n 'example': 'C4',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'N',\r\n 't': 15,\r\n 'd': '返回轉化為數值後的值。',\r\n 'a': '返回轉化為數值後的值。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要轉換為數位的參數。\\n\\n如果值為數位,則返回該數位。\\n\\n如果值為日期,則返回該日期的序號。\\n\\n如果值為TRUE,則返回1。\\n\\n如果值為FALSE,則返回0。\\n\\n如果值為錯誤值,則返回錯誤值。\\n\\n如果值為其他值,則返回0。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TO_DATE',\r\n 't': 16,\r\n 'd': '將指定的數位轉換為日期。',\r\n 'a': '將指定的數位轉換為日期。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要轉換為日期的參數或其儲存格引用。\\n\\n如果值為數位或指向內容為數值的儲存格的引用,TO_DATE會將值轉換為相應的日期並返回,值代表從十二月30日到對應的日期之間的天數,\\n\\n負值表示對應的日期在十二月30日之前,而小數值則代表一天中從午夜算起的時間。\\n如果值不是數位或指向內容為數值的儲存格的引用,則TO_DATE將在不做任何修改的情况下返回值。',\r\n 'example': '25405',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TO_PURE_NUMBER',\r\n 't': 16,\r\n 'd': '將給定的日期/時間、百分比、貨幣金額或其他格式的數值轉換為不帶格式的純數位。',\r\n 'a': '將給定的日期/時間、百分比、貨幣金額或其他格式的數值轉換為不帶格式的純數位。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要轉換為純數位的參數或其儲存格引用。\\n\\n如果值為數位或指向包含數值的儲存格的引用,TO_PURE_NUMBER將以不帶任何格式與解釋的形式返回值。\\n\\n如果值不是數位或指向內容為數值的儲存格的引用,則TO_PERCENT將在不做任何修改的情况下返回值。',\r\n 'example': '50%',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TO_TEXT',\r\n 't': 16,\r\n 'd': '將給定的數位值轉換為文本格式。',\r\n 'a': '將給定的數位值轉換為文本格式。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要轉換為文字的參數或其儲存格引用。\\n\\n如果值為數位或指向包含數值的儲存格的引用,TO_TEXT將返回字串形式的值,並保持現有格式。即原為貨幣的仍為貨幣,原為十進位數的仍為十進位數,原為百分比的仍為百分比,原為日期的仍為日期。\\n\\n如果值不是數位或指向內容為數值的儲存格的引用,則TO_TEXT將在不做任何修改的情况下返回值。',\r\n 'example': '24',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'TO_DOLLARS',\r\n 't': 16,\r\n 'd': '將指定的數位轉換為美元金額。',\r\n 'a': '將指定的數位轉換為美元金額。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要轉換為美元金額的參數或其儲存格引用。\\n\\n如果值不是數位或指向內容為數值的儲存格的引用,則TO_DOLLARS將在不做任何修改的情况下返回值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'TO_PERCENT',\r\n 't': 16,\r\n 'd': '將指定的數位轉換為百分比。',\r\n 'a': '將指定的數位轉換為百分比。',\r\n 'm': [1, 1],\r\n 'p': [{\r\n 'name' : 'value',\r\n 'detail' : '要轉換為百分比的參數或其儲存格引用。\\n\\n如果值為數位或指向包含數值的儲存格的引用,TO_PERCENT會以1 = 100%為標準,將值轉換為百分比。\\n\\n如果值不是數位或指向內容為數值的儲存格的引用,則TO_PERCENT將在不做任何修改的情况下返回值。',\r\n 'example': 'A2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'DGET',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,從清單或資料庫的列中選取符合指定條件的單個值。',\r\n 'a': '使用SQL式査詢,從清單或資料庫的列中選取符合指定條件的單個值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DMAX',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的最大數位。',\r\n 'a': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的最大數位。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DMIN',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的最小數位。',\r\n 'a': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的最小數位。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DAVERAGE',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,對清單或資料庫中滿足指定條件的記錄欄位(列)中的數值求平均值。',\r\n 'a': '使用SQL式査詢,對清單或資料庫中滿足指定條件的記錄欄位(列)中的數值求平均值。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DCOUNT',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中包含數位的儲存格的個數。',\r\n 'a': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中包含數位的儲存格的個數。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DCOUNTA',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的非空儲存格的個數。',\r\n 'a': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的非空儲存格的個數。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DPRODUCT',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的數值的乘積。',\r\n 'a': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的數值的乘積。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DSTDEV',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回利用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位作為一個樣本估算出的總體標準差。',\r\n 'a': '使用SQL式査詢,返回利用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位作為一個樣本估算出的總體標準差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DSTDEVP',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回利用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位作為樣本總體計算出的總體標準差。',\r\n 'a': '使用SQL式査詢,返回利用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位作為樣本總體計算出的總體標準差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DSUM',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的數位之和。',\r\n 'a': '使用SQL式査詢,返回列表或資料庫中滿足指定條件的記錄欄位(列)中的數位之和。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DVAR',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,返回利用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位作為一個樣本估算出的總體方差。',\r\n 'a': '使用SQL式査詢,返回利用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位作為一個樣本估算出的總體方差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n 'n': 'DVARP',\r\n 't': 17,\r\n 'd': '使用SQL式査詢,通過使用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位計算樣本總體的樣本總體方差。',\r\n 'a': '使用SQL式査詢,通過使用清單或資料庫中滿足指定條件的記錄欄位(列)中的數位計算樣本總體的樣本總體方差。',\r\n 'm': [3, 3],\r\n 'p': [{\r\n 'name' : 'database',\r\n 'detail' : '構成清單或資料庫的儲存格區域,清單的第一行包含每一列的標籤。',\r\n 'example': 'A2:F20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'field',\r\n 'detail' : '指定database中的哪一列包含要選取和用於計算的值。\\n\\nfield可以是與database第一行中某個列標題對應的文字標籤,也可以是指定相關列的數位索引,第一列的索引值為1。',\r\n 'example': 'G2',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'criteria',\r\n 'detail' : '包含所指定條件的儲存格區域。計算之前將使用這些條件來過濾database中的值。',\r\n 'example': 'A22:D23',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }]\r\n }, {\r\n \"n\": \"AGE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"據中國身份證號計算出年齡。支持15位或18位身份證\",\r\n \"a\": \"據中國身份證號計算出年齡\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": \"A1\",\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"截止日期\",\r\n \"example\": '\"2017-10-01\"',\r\n \"detail\" : \"年齡計算的截止日期或範圍,默認為當日。\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangedatetime\"\r\n }]\r\n },\r\n // SEX_BY_IDCARD\r\n {\r\n \"n\": \"SEX_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根據中國身份證號計算出性別。支持15位或18位身份證\",\r\n \"a\": \"根據身份證號得到性別。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n // BIRTHDAY_BY_IDCARD\r\n {\r\n \"n\": \"BIRTHDAY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根據中國身份證號計算出生日。支持15位或18位身份證\",\r\n \"a\": \"根據身份證號得到生日。\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"生日格式\",\r\n \"example\": '0',\r\n \"detail\" : \"日期類型,默認0:[1900/01/01],1:[1900-01-01],2:[1900年1月1日]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n // PROVINCE_BY_IDCARD\r\n {\r\n \"n\": \"PROVINCE_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根據中國身份證號計算出籍貫的省份。支持15位或18位身份證\",\r\n \"a\": \"根據身份證號得到籍貫的省份。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n // CITY_BY_IDCARD\r\n {\r\n \"n\": \"CITY_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根據中國身份證號計算出籍貫的都市。支持15位或18位身份證\",\r\n \"a\": \"根據身份證號得到籍貫的都市。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n // STAR_BY_IDCARD\r\n {\r\n \"n\": \"STAR_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根據中國身份證號計算出星座。支持15位或18位身份證\",\r\n \"a\": \"根據身份證號得到星座。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n // ANIMAL_BY_IDCARD\r\n {\r\n \"n\": \"ANIMAL_BY_IDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"根據中國身份證號計算出生肖(鼠、牛、虎、兔…)。支持15位或18位身份證\",\r\n \"a\": \"根據身份證號得到生肖。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n // ISIDCARD\r\n {\r\n \"n\": \"ISIDCARD\",\r\n \"t\": \"3\",\r\n \"d\": \"驗證身份證的格式是否正確。支持15位或18位身份證\",\r\n \"a\": \"驗證身份證格式正確性。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\" : \"身份證號\",\r\n \"example\": '\"31033519900101XXXX\"',\r\n \"detail\" : \"15位或者18位的身份證號或範圍。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n // DM_TEXT_CUTWORD\r\n {\r\n \"n\": \"DM_TEXT_CUTWORD\",\r\n \"t\": \"4\",\r\n \"d\": \"文字分詞。把一連串文字折開為一系列單獨詞語\",\r\n \"a\": \"中文文字分詞。\",\r\n \"m\": [1, 2],\r\n \"p\": [{\r\n \"name\" : \"文字\",\r\n \"example\": '\"我來到北京清華大學\"',\r\n \"detail\" : \"任意需要分詞的文字。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"分詞模式\",\r\n \"example\": '0',\r\n \"detail\" : \"默認為0[精確模式],1[全模式],2[搜尋引擎模式]。\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DM_TEXT_TFIDF\r\n {\r\n \"n\": \"DM_TEXT_TFIDF\",\r\n \"t\": \"4\",\r\n \"d\": \"採用tf-idf算灋進行關鍵字選取。從一連串文字中識別關鍵字\",\r\n \"a\": \"tf-idf關鍵字識別。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"文字\",\r\n \"example\": '\"我來到北京清華大學\"',\r\n \"detail\" : \"任意需要分詞的文字。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"關鍵字個數\",\r\n \"example\": '20',\r\n \"detail\" : \"算灋返回的關鍵字個數,默認20\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }, {\r\n \"name\" : \"語料庫\",\r\n \"example\": '1',\r\n \"detail\" : \"選擇特定領域的語料庫,默認0[通用],1[金融],2[醫療]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DM_TEXT_TEXTRANK\r\n {\r\n \"n\": \"DM_TEXT_TEXTRANK\",\r\n \"t\": \"4\",\r\n \"d\": \"採用TextRank算灋進行關鍵字選取。從一連串文字中識別關鍵字\",\r\n \"a\": \"TextRank關鍵字識別。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"文字\",\r\n \"example\": '\"我來到北京清華大學\"',\r\n \"detail\" : \"任意需要分詞的文字。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"關鍵字個數\",\r\n \"example\": '20',\r\n \"detail\" : \"算灋返回的關鍵字個數,默認20\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }, {\r\n \"name\" : \"語料庫\",\r\n \"example\": '1',\r\n \"detail\" : \"選擇特定領域的語料庫,默認0[通用],1[金融],2[醫療]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_CLOSE\r\n {\r\n \"n\": \"DATA_CN_STOCK_CLOSE\",\r\n \"t\": \"5\",\r\n \"d\": \"根據股票代碼和日期,返回A股對應股票收盤價。\",\r\n \"a\": \"返回A股對應股票收盤價。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"股票代碼\",\r\n \"example\": '\"000001\"',\r\n \"detail\" : \"6位股票代碼,必填項。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\" : \"股票的交易日,默認為最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangedate\"\r\n }, {\r\n \"name\" : \"複權除權\",\r\n \"example\": '0',\r\n \"detail\" : \"選擇股票的除權複權類型,默認0[前複權],1[原始價格],2[後複權]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_OPEN\r\n {\r\n \"n\": \"DATA_CN_STOCK_OPEN\",\r\n \"t\": \"5\",\r\n \"d\": \"根據股票代碼和日期,返回A股對應股票開盤價。\",\r\n \"a\": \"返回A股對應股票開盤價。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"股票代碼\",\r\n \"example\": '\"000001\"',\r\n \"detail\" : \"6位股票代碼,必填項。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\" : \"股票的交易日,默認為最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangedate\"\r\n }, {\r\n \"name\" : \"複權除權\",\r\n \"example\": '0',\r\n \"detail\" : \"選擇股票的除權複權類型,默認0[前複權],1[原始價格],2[後複權]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_MAX\r\n {\r\n \"n\": \"DATA_CN_STOCK_MAX\",\r\n \"t\": \"5\",\r\n \"d\": \"根據股票代碼和日期,返回A股對應股票最高價。\",\r\n \"a\": \"返回A股對應股票最高價。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"股票代碼\",\r\n \"example\": '\"000001\"',\r\n \"detail\" : \"6位股票代碼,必填項。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\" : \"股票的交易日,默認為最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangedate\"\r\n }, {\r\n \"name\" : \"複權除權\",\r\n \"example\": '0',\r\n \"detail\" : \"選擇股票的除權複權類型,默認0[前複權],1[原始價格],2[後複權]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_MIN\r\n {\r\n \"n\": \"DATA_CN_STOCK_MIN\",\r\n \"t\": \"5\",\r\n \"d\": \"根據股票代碼和日期,返回A股對應股票最低價。\",\r\n \"a\": \"返回A股對應股票最低價。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"股票代碼\",\r\n \"example\": '\"000001\"',\r\n \"detail\" : \"6位股票代碼,必填項。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\" : \"股票的交易日,默认为最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangedate\"\r\n }, {\r\n \"name\" : \"複權除權\",\r\n \"example\": '0',\r\n \"detail\" : \"選擇股票的除權複權類型,默認0[前複權],1[原始價格],2[後複權]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_VOLUMN\r\n {\r\n \"n\": \"DATA_CN_STOCK_VOLUMN\",\r\n \"t\": \"5\",\r\n \"d\": \"根據股票代碼和日期,返回A股對應股票成交量。\",\r\n \"a\": \"返回A股對應股票成交量。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"股票代碼\",\r\n \"example\": '\"000001\"',\r\n \"detail\" : \"6位股票代碼,必填項。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\" : \"股票的交易日,默認為最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangedate\"\r\n }, {\r\n \"name\" : \"複權除權\",\r\n \"example\": '0',\r\n \"detail\" : \"選擇股票的除權複權類型,默認0[前複權],1[原始價格],2[後複權]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // DATA_CN_STOCK_AMOUNT\r\n {\r\n \"n\": \"DATA_CN_STOCK_AMOUNT\",\r\n \"t\": \"5\",\r\n \"d\": \"根據股票代碼和日期,返回A股對應股票成交額。\",\r\n \"a\": \"返回A股對應股票成交額。\",\r\n \"m\": [1, 3],\r\n \"p\": [{\r\n \"name\" : \"股票代碼\",\r\n \"example\": '\"000001\"',\r\n \"detail\" : \"6位股票代碼,必填項。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }, {\r\n \"name\" : \"日期\",\r\n \"example\": '2015-01-08',\r\n \"detail\" : \"股票的交易日,默認為最新交易日\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangedate\"\r\n }, {\r\n \"name\" : \"複權除權\",\r\n \"example\": '0',\r\n \"detail\" : \"選擇股票的除權複權類型,默認0[前複權],1[原始價格],2[後複權]\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangenumber\"\r\n }]\r\n },\r\n // ISDATE\r\n {\r\n \"n\": \"ISDATE\",\r\n \"t\": \"6\",\r\n \"d\": \"驗證日期的格式是否正確。支持多種日期格式\",\r\n \"a\": \"驗證日期格式正確性。\",\r\n \"m\": [1, 1],\r\n \"p\": [{\r\n \"name\" : \"日期\",\r\n \"example\": '\"1990-01-01\"',\r\n \"detail\" : \"日期值,例如1990/01/01, 1990年1月1日等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }]\r\n },\r\n //sparklines函数,线图\r\n {\r\n \"n\": \"LINESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的折線圖sparklines,用於描述數據的連續走勢\",\r\n \"a\": \"生成儲存格折線圖\",\r\n \"m\": [1, 8],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20,{1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //lineColor\r\n {\r\n \"name\" : \"線條顏色\",\r\n \"example\": '#2ec7c9',\r\n \"detail\" : \"線圖的線條顏色,可以是否個範圍A1、色錶索引數值或者具體顏色值,設定為0或false則不顯示,支持regx、rgb、rgba等。默認#2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n // {\r\n // \"name\": \"填充顏色\",\r\n // \"example\": '#CCF3F4',\r\n // \"detail\": \"形成面积图,同线条顏色配置,默认0不显示\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // },\r\n //lineWidth\r\n {\r\n \"name\" : \"線條粗細\",\r\n \"example\": '1',\r\n \"detail\" : \"折線圖線段粗細,默認為1px\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //normalRangeMin和normalRangeMax设为相同的值,min、max、avg、median需要计算\r\n {\r\n \"name\" : \"輔助線\",\r\n \"example\": 'avg',\r\n \"detail\" : \"一條橫線,可以是min、max、avg、median、範圍或自定義數值,默認0無\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //normalRangeColor\r\n {\r\n \"name\" : \"輔助線顏色\",\r\n \"example\": '#000',\r\n \"detail\" : \"輔助線的顏色設定,同線條顏色配寘,默認#000\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //maxSpotColor\r\n {\r\n \"name\" : \"最大值標識\",\r\n \"example\": '#fc5c5c',\r\n \"detail\" : \"標識線圖最大值,同線條顏色配寘,默認0不顯示\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //minSpotColor\r\n {\r\n \"name\" : \"最小值標識\",\r\n \"example\": '#fc5c5c',\r\n \"detail\" : \"標識線圖最小值,同線條顏色配寘,默認0不顯示\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //spotRadius\r\n {\r\n \"name\" : \"標識大小\",\r\n \"example\": '1.5',\r\n \"detail\" : \"最大值和最小值的標識大小設定,默認為1.5\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines面积图\r\n {\r\n \"n\": \"AREASPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的面積圖sparklines,一般用於描述數據的連續累積值走勢\",\r\n \"a\": \"生成儲存格面積圖\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20,{1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //lineColor\r\n {\r\n \"name\" : \"線條顏色\",\r\n \"example\": '#2ec7c9',\r\n \"detail\" : \"線圖的線條顏色,可以是否個範圍A1、色錶索引數值或者具體顏色值,設定為0或false則不顯示,支持regx、rgb、rgba等。默認#2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //fillColor\r\n {\r\n \"name\" : \"填充顏色\",\r\n \"example\": '#CCF3F4',\r\n \"detail\" : \"形成面積圖,同線條顏色配寘,默認0不顯示\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //lineWidth\r\n {\r\n \"name\" : \"線條粗細\",\r\n \"example\": '1',\r\n \"detail\" : \"折線圖線段粗細,默認為1px\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //normalRangeMin和normalRangeMax设为相同的值,min、max、avg、median需要计算\r\n {\r\n \"name\" : \"輔助線\",\r\n \"example\": 'avg',\r\n \"detail\" : \"一條橫線,可以是min、max、avg、median、範圍或自定義數值,默認0無\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //normalRangeColor\r\n {\r\n \"name\" : \"輔助線顏色\",\r\n \"example\": '#000',\r\n \"detail\" : \"輔助線的顏色設定,同線條顏色配寘,默認#000\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }\r\n // //maxSpotColor\r\n // {\r\n // \"name\": \"最大值标识\",\r\n // \"example\": '#fc5c5c',\r\n // \"detail\": \"标识线图最大值,同线条顏色配置,默认0不显示\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // },\r\n // //minSpotColor\r\n // {\r\n // \"name\": \"最小值标识\",\r\n // \"example\": '#fc5c5c',\r\n // \"detail\": \"标识线图最大值,同线条顏色配置,默认0不显示\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // },\r\n // //spotRadius\r\n // {\r\n // \"name\": \"标识大小\",\r\n // \"example\": '1.5',\r\n // \"detail\": \"最大值和最小值的标识大小设置,默认为1.5\",\r\n // \"require\": \"o\",\r\n // \"repeat\": \"n\",\r\n // \"type\": \"rangeall\"\r\n // }\r\n ]\r\n },\r\n //sparklines柱状图\r\n {\r\n \"n\": \"COLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的垂直柱狀圖sparklines,一般用於描述離散數據之間的大小情况\",\r\n \"a\": \"生成儲存格垂直柱狀圖\",\r\n \"m\": [1, 6],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20,{1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\" : \"柱條間隔\",\r\n \"example\": '1',\r\n \"detail\" : \"柱條之間的間隔距離,默認為1\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //barColor\r\n {\r\n \"name\" : \"柱條顏色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\" : \"線圖的線條顏色,可以是否個範圍A1、色錶索引數值或者具體顏色值,設定為0或false則不顯示,支持regx、rgb、rgba等。默認#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //negBarColor\r\n {\r\n \"name\" : \"負向柱條顏色\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"負向柱條顏色設定,代表負值的顏色,同柱條顏色配寘,默認#97b552\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\" : \"最大值\",\r\n \"example\": '100',\r\n \"detail\" : \"柱圖最大值,用於規範柱圖長度,默認為自動計算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //colorMap\r\n {\r\n \"name\" : \"色板\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"調色板可以單獨設定每個柱條的顏色,可設定多個,支持兩種格式:1顏色例如#000,代表第一個柱的顏色是黑色;2數值範圍:顏色,例如-2:#000表示數值為-2的柱為黑色,0:5:#000表示數值0-5的柱為黑色,默認為空\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines累积柱状图\r\n {\r\n \"n\": \"STACKCOLUMNSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的累積垂直柱狀圖sparklines,一般用於描述離散數據多個維度的數值大小\",\r\n \"a\": \"生成儲存格累積垂直柱狀圖\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20,{1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //stackconfig\r\n {\r\n \"name\" : \"按列堆積\",\r\n \"example\": '1',\r\n \"detail\" : \"如果需要按行堆積則本項設為false或0,默認為是1\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\" : \"柱條間隔\",\r\n \"example\": '1',\r\n \"detail\" : \"柱條之間的間隔距離,默認為1\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\" : \"最大值\",\r\n \"example\": '100',\r\n \"detail\" : \"累積柱圖最大值,用於規範柱圖長度,默認為自動計算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //stackedBarColor\r\n {\r\n \"name\" : \"累積色板\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"調色板可以單獨設定每個維度的柱條顏色,可設定為A1:A10等範圍,默認為#2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines条形图\r\n {\r\n \"n\": \"BARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的橫向條形圖sparklines,一般用於描述離散數據之間的大小情况\",\r\n \"a\": \"生成儲存格橫向條形圖\",\r\n \"m\": [1, 6],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\" : \"柱條間隔\",\r\n \"example\": '1',\r\n \"detail\" : \"柱條之間的間隔距離,默認為1\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //barColor\r\n {\r\n \"name\" : \"柱條顏色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\" : \"線圖的線條顏色,可以是否個範圍A1、色錶索引數值或者具體顏色值,設定為0或false則不顯示,支持regx、rgb、rgba等。默認#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //negBarColor\r\n {\r\n \"name\" : \"負向柱條顏色\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"負向柱條顏色設定,代表負值的顏色,同柱條顏色配寘,默認#97b552\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\" : \"最大值\",\r\n \"example\": '100',\r\n \"detail\" : \"柱圖最大值,用於規範柱圖長度,默認為自動計算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //colorMap\r\n {\r\n \"name\" : \"色板\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"調色板可以單獨設定每個柱條的顏色,可設定多個,支持兩種格式:1顏色例如#000,代表第一個柱的顏色是黑色;2數值範圍:顏色,例如-2:#000表示數值為-2的柱為黑色,0:5:#000表示數值0-5的柱為黑色,默認為空\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines累积条形图\r\n {\r\n \"n\": \"STACKBARSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的累積橫向條形圖sparklines,一般用於描述離散數據多個維度的數值大小\",\r\n \"a\": \"生成儲存格累積橫向條形圖\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //stackconfig\r\n {\r\n \"name\" : \"按列堆積\",\r\n \"example\": '1',\r\n \"detail\" : \"如果需要按行堆積則本項設為false或0,默認為是1\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\" : \"柱條間隔\",\r\n \"example\": '1',\r\n \"detail\" : \"柱條之間的間隔距離,默認為1\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //chartRangeMax\r\n {\r\n \"name\" : \"最大值\",\r\n \"example\": '100',\r\n \"detail\" : \"累積柱圖最大值,用於規範柱圖長度,默認為自動計算false、auto、null\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //stackedBarColor\r\n {\r\n \"name\" : \"累積色板\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"調色板可以單獨設定每個維度的柱條顏色,可設定為A1:A10等範圍,默認為#2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines离散图\r\n {\r\n \"n\": \"DISCRETESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的離散圖sparklines,一般用於描述離散數據走勢\",\r\n \"a\": \"生成儲存格離散圖\",\r\n \"m\": [1, 4],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //thresholdValue\r\n {\r\n \"name\" : \"分割閾值\",\r\n \"example\": '1',\r\n \"detail\" : \"離散圖柱形顏色的區分,例如:該值為0,則大於0為藍色,小於0為紅色,默認為0\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //lineColor\r\n {\r\n \"name\" : \"閾值以上顏色\",\r\n \"example\": '#2ec7c9',\r\n \"detail\" : \"線圖的線條顏色,可以是否個範圍A1、色錶索引數值或者具體顏色值,設定為0或false則不顯示,支持regx、rgb、rgba等。默認#2ec7c9\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //thresholdColor\r\n {\r\n \"name\" : \"閾值以下顏色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\" : \"閾值以下柱條顏色設定,同閾值以上顏色,默認#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines三态图\r\n {\r\n \"n\": \"TRISTATESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的三態圖sparklines,一般用於描述三種態勢的走勢例如勝負平\",\r\n \"a\": \"生成儲存格三態圖\",\r\n \"m\": [1, 6],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //barSpacing\r\n {\r\n \"name\" : \"柱條間隔\",\r\n \"example\": '1',\r\n \"detail\" : \"柱條之間的間隔距離,默認為1\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //posBarColor\r\n {\r\n \"name\" : \"柱條顏色\",\r\n \"example\": '#fc5c5c',\r\n \"detail\" : \"線圖的線條顏色,可以是否個範圍A1、色錶索引數值或者具體顏色值,設定為0或false則不顯示,支持regx、rgb、rgba等。默認#fc5c5c\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //negBarColor\r\n {\r\n \"name\" : \"负向柱條顏色\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"負向柱條顏色設定,代表負值的顏色,同柱條顏色配寘,默認#97b552\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //zeroBarColor\r\n {\r\n \"name\" : \"零值柱條顏色\",\r\n \"example\": '#999',\r\n \"detail\" : \"零值柱條顏色設定,代表0值顏色,同柱條顏色配寘,默認#999\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //colorMap\r\n {\r\n \"name\" : \"色板\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"調色板可以單獨設定每個柱條的顏色,可設定多個,支持兩種格式:1顏色例如#000,代表第一個柱的顏色是黑色;2數值範圍:顏色,例如-2:#000表示數值為-2的柱為黑色,0-5:#000表示數值0-5的柱為黑色,默認為空\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines饼图\r\n {\r\n \"n\": \"PIESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的餅圖sparklines,一般用於描述數據占比\",\r\n \"a\": \"生成儲存格餅圖\",\r\n \"m\": [1, 5],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //offset\r\n {\r\n \"name\" : \"旋轉角度\",\r\n \"example\": '0',\r\n \"detail\" : \"餅圖的旋轉角度,默認為0\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //borderWidth\r\n {\r\n \"name\" : \"餅圖邊框\",\r\n \"example\": '0',\r\n \"detail\" : \"餅圖邊框大小,默認為無0\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //borderColor\r\n {\r\n \"name\" : \"邊框顏色\",\r\n \"example\": '#000',\r\n \"detail\" : \"餅圖邊框顏色,默認為#000\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //sliceColors\r\n {\r\n \"name\" : \"餅圖色板\",\r\n \"example\": '#97b552',\r\n \"detail\" : \"調色板可以設定切片的顏色,可設定為A1:A10等範圍,默認為#2ec7c9, #fc5c5c, #5ab1ef, #ffb980...\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines箱线图\r\n {\r\n \"n\": \"BOXSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的箱線圖sparklines,一般用於描述數據集的統計分佈\",\r\n \"a\": \"生成儲存格箱線圖\",\r\n \"m\": [1, 4],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"數據範圍\",\r\n \"example\": 'A1:A20',\r\n \"detail\" : \"數據範圍,數值才能被有效計算,例如A1:A20, {1,2,3,4,5}等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //outlierIQR,如果为0或false则showOutliers设为false,否则为true\r\n {\r\n \"name\" : \"離群點比例\",\r\n \"example\": '1.5',\r\n \"detail\" : \"離群點的閾值範圍,如果為0或false則不顯示,默認為1.5倍\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //target\r\n {\r\n \"name\" : \"目標點值\",\r\n \"example\": '10',\r\n \"detail\" : \"箱線圖上的目標值設定,默認為false不顯示\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //spotRadius\r\n {\r\n \"name\" : \"數據點大小\",\r\n \"example\": '1.5',\r\n \"detail\" : \"目標點和離群點的半徑大小設定,默認為1.5\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines子弹图\r\n {\r\n \"n\": \"BULLETSPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"生成嵌入在儲存格內的子彈圖sparklines,一般用於描述任務達成率\",\r\n \"a\": \"生成儲存格子彈圖\",\r\n \"m\": [2, 3],\r\n \"p\": [\r\n //目标data1\r\n {\r\n \"name\" : \"目標\",\r\n \"example\": '10',\r\n \"detail\" : \"達成的目標值,數值才能被有效計算,例如A1,100等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //目前达成data2\r\n {\r\n \"name\" : \"實際完成\",\r\n \"example\": '8',\r\n \"detail\" : \"現時完成值,數值才能被有效計算,例如A1,100等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"n\",\r\n \"type\" : \"rangeall\"\r\n },\r\n //对比值datax\r\n {\r\n \"name\" : \"對比值\",\r\n \"example\": '12',\r\n \"detail\" : \"對比值,例如超額、最低、獲獎底線等,數值才能被有效計算,例如A1,100等。可以設定最多9個對比值\",\r\n \"require\": \"o\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //sparklines组合图,支持多個类型的图画在同一個单元格\r\n {\r\n \"n\": \"COMPOSESPLINES\",\r\n \"t\": \"3\",\r\n \"d\": \"支持多個類型的圖畫在同一個儲存格,每個參數代表一個sparklines圖\",\r\n \"a\": \"組合sparklines圖到一個儲存格\",\r\n \"m\": [1, 1],\r\n \"p\": [\r\n //data\r\n {\r\n \"name\" : \"圖設定\",\r\n \"example\": 'PIESPLINES(A1:A20)',\r\n \"detail\" : \"sparklines圖設定,例如A1:A20,一個完成的餅圖、線圖設定等。\",\r\n \"require\": \"m\",\r\n \"repeat\" : \"y\",\r\n \"type\" : \"rangeall\"\r\n }\r\n ]\r\n },\r\n //动态数组公式\r\n {\r\n 'n': 'SORT',\r\n 't': '14',\r\n 'd': '返回數組中元素的排序數組。返回的數組與提供的數組參數形狀相同。',\r\n 'a': '返回數組中元素的排序數組。返回的數組與提供的數組參數形狀相同。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '要排序的範圍或數組。',\r\n 'example': 'A2:A17',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'sort_index',\r\n 'detail' : '[可選] - 表示要排序的行或列的數位。(默認row1/col1)',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'sort_order',\r\n 'detail' : '[可選] - 表示所需排序順序的數位;1表示昇冪(默認),-1表示降序。',\r\n 'example': '-1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'by_col',\r\n 'detail' : '[可選] - 表示所需排序方向的邏輯值;按行排序為FALSE()(默認),按列排序為TRUE()。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'FILTER',\r\n 't': '14',\r\n 'd': '基於一個布林(真/假)數組過濾一個數組。',\r\n 'a': '基於一個布林(真/假)數組過濾一個數組。',\r\n 'm': [2, 3],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '要篩選的數組或範圍。',\r\n 'example': 'A5:D20',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'include',\r\n 'detail' : '布林數組,其高度或寬度與數組相同',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'range'\r\n }, {\r\n 'name' : 'if_empty',\r\n 'detail' : '[可選] - 如果包含數組中的所有值都為空(filter不返回任何值),則返回的值。',\r\n 'example': '\"\"',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'UNIQUE',\r\n 't': '14',\r\n 'd': '返回列表或區域中的唯一值的清單。',\r\n 'a': '返回列表或區域中的唯一值的清單。',\r\n 'm': [1, 3],\r\n 'p': [{\r\n 'name' : 'array',\r\n 'detail' : '從其返回唯一值的數組或區域。',\r\n 'example': 'A2:B26',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'by_col',\r\n 'detail' : '[可選] - 邏輯值,訓示如何比較;按行= FALSE()或省略;按列= TRUE()。',\r\n 'example': 'TRUE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }, {\r\n 'name' : 'occurs_once',\r\n 'detail' : '[可選] - 邏輯值,僅返回唯一值中出現一次= TRUE();包括所有唯一值= FALSE()或省略。',\r\n 'example': 'FALSE()',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangeall'\r\n }]\r\n }, {\r\n 'n': 'RANDARRAY',\r\n 't': '14',\r\n 'd': '返回0到1之間的隨機數位數組。',\r\n 'a': '返回0到1之間的隨機數位數組',\r\n 'm': [0, 2],\r\n 'p': [{\r\n 'name' : 'rows',\r\n 'detail' : '[可選] - 要返回的行數。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cols',\r\n 'detail' : '[可選] - 要返回的列數。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n }, {\r\n 'n': 'SEQUENCE',\r\n 't': '14',\r\n 'd': '生成數位序列的清單。',\r\n 'a': '生成數位序列的清單。',\r\n 'm': [1, 4],\r\n 'p': [{\r\n 'name' : 'rows',\r\n 'detail' : '要返回的行數。',\r\n 'example': '1',\r\n 'require': 'm',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'cols',\r\n 'detail' : '[可選] - 要返回的列數。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'start',\r\n 'detail' : '[可選] - 序列中的第一個數位。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }, {\r\n 'name' : 'step',\r\n 'detail' : '[可選] -序列中每個序列值的增量。',\r\n 'example': '1',\r\n 'require': 'o',\r\n 'repeat' : 'n',\r\n 'type' : 'rangenumber'\r\n }]\r\n },{\r\n 'n': 'EVALUATE',\r\n 't': '3',\r\n 'd': '對以文字表示的公式或者表達式求值,並返回結果。',\r\n 'a': '根據文字公式或者表達式求值。',\r\n 'm': [1, 1],\r\n \"p\": [{\r\n \"name\": \"公式\",\r\n \"example\": '\"A1+5*2^2\"',\r\n \"detail\": \"公式或表達式\",\r\n \"require\": \"m\",\r\n \"repeat\": \"n\",\r\n \"type\": \"rangeall\"\r\n }]\r\n },\r\n ],\r\n toolbar: {\r\n undo : '撤銷',\r\n redo : '重做',\r\n paintFormat : '格式刷',\r\n currencyFormat : '貨幣格式',\r\n percentageFormat : '百分比格式',\r\n numberDecrease : '减少小數位數',\r\n numberIncrease : '新增小數位數',\r\n moreFormats : '更多格式',\r\n font : '字體',\r\n fontSize : '字型大小',\r\n bold : '粗體(Ctrl+B)',\r\n italic : '斜體(Ctrl+I)',\r\n strikethrough : '删除線(Alt+Shift+5)',\r\n underline : '底線',\r\n textColor : '文字顏色',\r\n chooseColor : '顏色選擇',\r\n resetColor : '重置顏色',\r\n customColor : '自定義',\r\n alternatingColors : '交替顏色',\r\n confirmColor : '確定顏色',\r\n cancelColor : '取消',\r\n collapse : '收起',\r\n fillColor : '儲存格顏色',\r\n border : '邊框',\r\n borderStyle : '邊框類型',\r\n mergeCell : '合併儲存格',\r\n chooseMergeType : '選擇合併類型',\r\n horizontalAlign : '水准對齊',\r\n verticalAlign : '垂直對齊',\r\n alignment : '對齊管道',\r\n textWrap : '文字換行',\r\n textWrapMode : '換行管道',\r\n textRotate : '文字旋轉',\r\n textRotateMode : '旋轉管道',\r\n freezeTopRow : '凍結首行',\r\n sortAndFilter : '排序和篩選',\r\n findAndReplace : '查找替換',\r\n sum : '求和',\r\n autoSum : '自動求和',\r\n moreFunction : '更多函數',\r\n conditionalFormat : '條件格式',\r\n postil : '批註',\r\n pivotTable : '數據透視錶',\r\n chart : '圖表',\r\n screenshot : '截圖',\r\n splitColumn : '分列',\r\n insertImage : '插入圖片',\r\n insertLink : '插入連結',\r\n dataVerification : '數據驗證',\r\n protection : '保護工作表內容',\r\n clearText : '清除顏色選擇',\r\n noColorSelectedText: '沒有顏色被選擇',\r\n toolMore : '更多',\r\n toolLess : '少於',\r\n toolClose : '收起',\r\n toolMoreTip : '更多功能',\r\n moreOptions : '更多選項',\r\n cellFormat : '設定儲存格格式',\r\n print : '列印'\r\n },\r\n alternatingColors: {\r\n applyRange : '應用範圍',\r\n selectRange : '選擇應用範圍',\r\n header : '頁眉',\r\n footer : '頁腳',\r\n errorInfo : '不能對多重選擇區域執行此操作,請選擇單個區域,然後再試',\r\n textTitle : '格式樣式',\r\n custom : '自定義',\r\n close : '關閉',\r\n selectionTextColor: '選擇文字顏色',\r\n selectionCellColor: '選擇儲存格顏色',\r\n removeColor : '移除交替顏色',\r\n colorShow : '顏色',\r\n currentColor : '當前顏色',\r\n tipSelectRange : '請選擇交替顏色應用範圍',\r\n errorNoRange : '您選擇的應用範圍不是選區!',\r\n errorExistColors : '您選擇的應用範圍已存在交替顏色且不屬於你要編輯的應用範圍!',\r\n },\r\n button: {\r\n confirm: '確定',\r\n cancel : '取消',\r\n close : \"關閉\",\r\n update : \"Update\",\r\n delete : \"Delete\",\r\n insert : \"新建\",\r\n },\r\n paint: {\r\n start : '格式刷開啟',\r\n end : 'ESC鍵退出',\r\n tipSelectRange: '請選擇需要複製格式的區域',\r\n tipNotMulti : '無法對多重選擇區域執行此操作',\r\n },\r\n format: {\r\n moreCurrency : '更多貨幣格式',\r\n moreDateTime : '更多日期與時間格式',\r\n moreNumber : '更多數位格式',\r\n titleCurrency: '貨幣格式',\r\n decimalPlaces: '小數位數',\r\n titleDateTime: '日期與時間格式',\r\n titleNumber : '數位格式'\r\n },\r\n info: {\r\n detailUpdate: '新打開',\r\n detailSave : '已恢復本地緩存',\r\n row : '行',\r\n column : '列',\r\n loading : '渲染中',\r\n\r\n copy : '副本',\r\n return: '返回',\r\n rename: '重命名',\r\n tips : '表格重命名',\r\n noName: '無標題的試算表',\r\n wait : '待更新',\r\n\r\n add : '添加',\r\n addLast : '在底部添加',\r\n backTop : '回到頂部',\r\n pageInfo: '共${total}條,${totalPage}頁,當前已顯示${currentPage}頁',\r\n nextPage: '下一頁',\r\n\r\n tipInputNumber : '請輸入數位',\r\n tipInputNumberLimit: '新增範圍限制在1-100',\r\n\r\n tipRowHeightLimit : '行高必須在0 ~ 545之間',\r\n tipColumnWidthLimit: '列寬必須在0 ~ 2038之間',\r\n pageInfoFull : '共${total}條,${totalPage}頁,已顯示全部數據',\r\n },\r\n currencyDetail: {\r\n RMB : '人民幣',\r\n USdollar : '美元',\r\n EUR : '歐元',\r\n GBP : '英鎊',\r\n HK : '港元',\r\n JPY : '日元',\r\n AlbanianLek : '阿爾巴尼亞列克',\r\n AlgerianDinar : '阿爾及利亞第納爾',\r\n Afghani : '阿富汗尼',\r\n ArgentinePeso : '阿根廷比索',\r\n UnitedArabEmiratesDirham : '阿拉伯聯合大公國迪拉姆',\r\n ArubanFlorin : '阿魯巴弗羅林',\r\n OmaniRial : '阿曼裡亞爾',\r\n Azerbaijanimanat : '阿塞拜疆馬納特',\r\n EgyptianPound : '埃及鎊',\r\n EthiopianBirr : '衣索比亞比爾',\r\n AngolaKwanza : '安哥拉寬紮',\r\n AustralianDollar : '澳大利亞元',\r\n Patacas : '澳門元',\r\n BarbadosDollar : '巴巴多斯元',\r\n PapuaNewGuineaKina : '巴布亞新幾內亞基那',\r\n BahamianDollar : '巴哈馬元',\r\n PakistanRupee : '巴基斯坦盧比',\r\n ParaguayanGuarani : '巴拉圭瓜拉尼',\r\n BahrainiDinar : '巴林第納爾',\r\n PanamanianBalboa : '巴拿馬巴波亞',\r\n Brazilianreal : '巴西裏亞伊',\r\n Belarusianruble : '白俄羅斯盧布',\r\n BermudianDollar : '百慕大元',\r\n BulgarianLev : '保加利亞列弗',\r\n IcelandKrona : '冰島克朗',\r\n BosniaHerzegovinaConvertibleMark: '波黑可兌換馬克',\r\n PolishZloty : '波蘭茲羅提',\r\n Boliviano : '玻利維亞諾',\r\n BelizeDollar : '貝裡斯元',\r\n BotswanaPula : '波劄那普拉',\r\n NotDannuzhamu : '不丹努紮姆',\r\n BurundiFranc : '布隆迪法郎',\r\n NorthKoreanWon : '朝鮮圓',\r\n DanishKrone : '丹麥克朗',\r\n EastCaribbeanDollar : '東加勒比元',\r\n DominicaPeso : '多明尼加比索',\r\n RussianRuble : '俄國盧布',\r\n EritreanNakfa : '厄利垂亞納克法',\r\n CFAfranc : '非洲金融共同體法郎',\r\n PhilippinePeso : '菲律賓比索',\r\n FijiDollar : '斐濟元',\r\n CapeVerdeEscudo : '佛得角埃斯庫多',\r\n FalklandIslandsPound : '福克蘭群島鎊',\r\n GambianDalasi : '岡比亞達拉西',\r\n Congolesefranc : '剛果法郎',\r\n ColombianPeso : '哥倫比亞比索',\r\n CostaRicanColon : '哥斯大黎加科朗',\r\n CubanPeso : '古巴比索',\r\n Cubanconvertiblepeso : '古巴可兌換比索',\r\n GuyanaDollar : '蓋亞那元',\r\n KazakhstanTenge : '哈薩克共和國堅戈',\r\n Haitiangourde : '海地古德',\r\n won : '韓元',\r\n NetherlandsAntillesGuilder : '荷屬安的列斯盾',\r\n Honduraslempiras : '洪都拉斯拉倫皮拉',\r\n DjiboutiFranc : '吉布提法郎',\r\n KyrgyzstanSom : '吉爾吉斯斯坦索姆',\r\n GuineaFranc : '幾內亞法郎',\r\n CanadianDollar : '加拿大元',\r\n GhanaianCedi : '加納塞地',\r\n Cambodianriel : '高棉瑞爾',\r\n CzechKoruna : '捷克克朗',\r\n ZimbabweDollar : '辛巴威元',\r\n QatariRiyal : '卡塔爾裡亞爾',\r\n CaymanIslandsDollar : '開曼群島元',\r\n Comorianfranc : '科摩羅法郎',\r\n KuwaitiDinar : '科威特第納爾',\r\n CroatianKuna : '克羅地亞庫納',\r\n KenyanShilling : '肯雅先令',\r\n LesothoLoti : '萊索托洛蒂',\r\n LaoKip : '老撾基普',\r\n LebanesePound : '黎巴嫩鎊',\r\n Lithuanianlitas : '立陶宛立特',\r\n LibyanDinar : '利比亞第納爾',\r\n LiberianDollar : '利比亞元',\r\n RwandaFranc : '盧安達法郎',\r\n RomanianLeu : '羅馬尼亞列伊',\r\n MalagasyAriary : '馬拉加西阿裏亞裏',\r\n MaldivianRufiyaa : '瑪律地夫拉菲亞',\r\n MalawiKwacha : '馬拉威克瓦查',\r\n MalaysianRinggit : '馬來西亞林吉特',\r\n MacedoniawearingDinar : '馬其頓戴第納爾',\r\n MauritiusRupee : '模裡西斯盧比',\r\n MauritanianOuguiya : '茅利塔尼亞烏吉亞',\r\n MongolianTugrik : '蒙古圖格裡克',\r\n BangladeshiTaka : '孟加拉塔卡',\r\n PeruvianNuevoSol : '秘魯新索爾',\r\n MyanmarKyat : '緬甸開亞特',\r\n MoldovanLeu : '莫爾達瓦列伊',\r\n MoroccanDirham : '摩洛哥迪拉姆',\r\n MozambiqueMetical : '莫三比克梅蒂卡爾',\r\n MexicanPeso : '墨西哥比索',\r\n NamibianDollar : '納米比亞元',\r\n SouthAfricanRand : '南非蘭特',\r\n SouthSudanesePound : '南蘇丹鎊',\r\n NicaraguaCordoba : '尼加拉瓜科多巴',\r\n NepaleseRupee : '尼泊爾盧比',\r\n NigerianNaira : '奈及利亞奈拉',\r\n NorwegianKrone : '挪威克朗',\r\n GeorgianLari : '喬治亞拉瑞',\r\n RMBOffshore : '人民幣(離岸)',\r\n SwedishKrona : '瑞典克朗',\r\n SwissFranc : '瑞士法郎',\r\n SerbianDinar : '塞爾維亞第納爾',\r\n SierraLeone : '塞拉里昂利昂',\r\n SeychellesRupee : '塞舌耳盧比',\r\n SaudiRiyal : '沙特裡亞爾',\r\n SaoTomeDobra : '聖多美多布拉',\r\n SaintHelenapound : '聖赫倫那群島磅',\r\n SriLankaRupee : '斯里蘭卡盧比',\r\n SwazilandLilangeni : '史瓦濟蘭裏蘭吉尼',\r\n SudanesePound : '蘇丹鎊',\r\n Surinamesedollar : '蘇利南元',\r\n SolomonIslandsDollar : '所羅門群島元',\r\n SomaliShilling : '索馬利亞先令',\r\n TajikistanSomoni : '塔吉克共和國索莫尼',\r\n PacificFranc : '太平洋法郎',\r\n ThaiBaht : '泰國銖',\r\n TanzanianShilling : '坦尚尼亞先令',\r\n TonganPaanga : '東加潘加',\r\n TrinidadandTobagoDollar : '千裡達托貝哥元',\r\n TunisianDinar : '突尼斯第納爾',\r\n TurkishLira : '土耳其里拉',\r\n VanuatuVatu : '瓦努阿圖瓦圖',\r\n GuatemalanQuetzal : '瓜地馬拉格查爾',\r\n CommissionBolivar : '委內瑞拉博利瓦',\r\n BruneiDollar : '汶萊元',\r\n UgandanShilling : '烏干達先令',\r\n UkrainianHryvnia : '烏克蘭格裡夫尼亞',\r\n UruguayanPeso : '烏拉圭比索',\r\n Uzbekistansom : '烏茲別克蘇姆',\r\n WesternSamoaTala : '薩摩亞塔拉',\r\n SingaporeDollar : '新加坡元',\r\n NT : '新臺幣',\r\n NewZealandDollar : '新西蘭元',\r\n HungarianForint : '匈牙利福林',\r\n SyrianPound : '敘利亞鎊',\r\n JamaicanDollar : '牙買加元',\r\n ArmenianDram : '亞美尼亞德拉姆',\r\n YemeniRial : '葉門裡亞爾',\r\n IraqiDinar : '伊拉克第納爾',\r\n IranianRial : '伊朗裡亞爾',\r\n NewIsraeliShekel : '以色列新謝克爾',\r\n IndianRupee : '印度盧比',\r\n IndonesianRupiah : '印尼盧比',\r\n JordanianDinar : '約旦第納爾',\r\n VND : '越南盾',\r\n ZambianKwacha : '尚比亞克瓦查',\r\n GibraltarPound : '直布羅陀鎊',\r\n ChileanPeso : '智利比索',\r\n CFAFrancBEAC : '中非金融合作法郎',\r\n },\r\n defaultFmt: [\r\n { \"text\": '自動', \"value\": \"General\", \"example\": \"\" },\r\n { \"text\": '純文字', \"value\": \"@\", \"example\": \"\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '數位', \"value\": \"##0.00\", \"example\": \"1000.12\" },\r\n { \"text\": '百分比', \"value\": \"#0.00%\", \"example\": \"12.21%\" },\r\n { \"text\": '科學計數', \"value\": \"0.00E+00\", \"example\": \"1.01E+5\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '會計', \"value\": \"¥(0.00)\", \"example\": \"¥(1200.09)\" },\r\n //{ \"text\": \"財務\", \"value\": \"(#.####)\", \"example\": \"(1200.09)\" },\r\n { \"text\": '萬元', \"value\": \"w\", \"example\": \"1亿2000万2500\" },\r\n { \"text\": '貨幣', \"value\": \"¥0.00\", \"example\": \"¥1200.09\" },\r\n //{ \"text\": \"貨幣整數\", \"value\": \"¥####\", \"example\": \"¥1200\" },\r\n { \"text\": '萬元2位小數', \"value\": \"w0.00\", \"example\": \"2万2500.55\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '日期', \"value\": \"yyyy-MM-dd\", \"example\": \"2017-11-29\" },\r\n { \"text\": '時間', \"value\": \"hh:mm AM/PM\", \"example\": \"3:00 PM\" },\r\n { \"text\": '時間24H', \"value\": \"hh:mm\", \"example\": \"15:00\" },\r\n { \"text\": '日期時間', \"value\": \"yyyy-MM-dd hh:mm AM/PM\", \"example\": \"2017-11-29 3:00 PM\" },\r\n { \"text\": '日期時間24H', \"value\": \"yyyy-MM-dd hh:mm\", \"example\": \"2017-11-29 15:00\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": '自定義格式', \"value\": \"fmtOtherSelf\", \"example\": \"more\" }\r\n ],\r\n dateFmtList: [\r\n {\r\n \"name\" : \"1930-08-05\",\r\n \"value\": \"yyyy-MM-dd\"\r\n },\r\n {\r\n \"name\" : \"1930/8/5\",\r\n \"value\": \"yyyy/MM/dd\"\r\n },\r\n {\r\n \"name\" : \"1930年8月5日\",\r\n \"value\": 'yyyy\"年\"M\"月\"d\"日\"'\r\n },\r\n {\r\n \"name\" : \"08-05\",\r\n \"value\": \"MM-dd\"\r\n },\r\n {\r\n \"name\" : \"8-5\",\r\n \"value\": \"M-d\"\r\n },\r\n {\r\n \"name\" : \"8月5日\",\r\n \"value\": 'M\"月\"d\"日\"'\r\n },\r\n {\r\n \"name\" : \"13:30:30\",\r\n \"value\": \"h:mm:ss\"\r\n },\r\n {\r\n \"name\" : \"13:30\",\r\n \"value\": \"h:mm\"\r\n },\r\n {\r\n \"name\" : \"下午01:30\",\r\n \"value\": '上午/下午 hh:mm'\r\n },\r\n {\r\n \"name\" : \"下午1:30\",\r\n \"value\": '上午/下午 h:mm'\r\n },\r\n {\r\n \"name\" : \"下午1:30:30\",\r\n \"value\": '上午/下午 h:mm:ss'\r\n },\r\n {\r\n \"name\" : \"08-05 下午01:30\",\r\n \"value\": \"MM-dd 上午/下午 hh:mm\"\r\n },\r\n // {\r\n // \"name\": \"1930年8月5日星期二\",\r\n // \"value\": ''\r\n // },\r\n // {\r\n // \"name\": \"1930年8月5日星期二 下午1:30:30\",\r\n // \"value\": ''\r\n // },\r\n ],\r\n fontFamily: {\r\n MicrosoftYaHei: \"Microsoft YaHei\",\r\n },\r\n fontarray: [\"Times New Roman\", \"Arial\", \"Tahoma\", \"Verdana\", \"微軟雅黑\", \"宋體\", \"黑體\", \"楷體\", \"仿宋\", \"新宋體\", \"華文新魏\", \"華文行楷\", \"華文隸書\"],\r\n fontjson : { \"times new roman\": 0, \"arial\": 1, \"tahoma\": 2, \"verdana\": 3, \"微軟雅黑\": 4, \"microsoft yahei\": 4, \"宋體\": 5, \"simsun\": 5, \"黑體\": 6, \"simhei\": 6, \"楷體\": 7, \"kaiti\": 7, \"仿宋\": 8, \"fangsong\": 8, \"新宋體\": 9, \"nsimsun\": 9, \"華文新魏\": 10, \"stxinwei\": 10, \"華文行楷\": 11, \"stxingkai\": 11, \"華文隸書\": 12, \"stliti\": 12, },\r\n border : {\r\n borderTop : '上框線',\r\n borderBottom : '下框線',\r\n borderLeft : '左框線',\r\n borderRight : '右框線',\r\n borderNone : '無',\r\n borderAll : '所有',\r\n borderOutside : '外側',\r\n borderInside : '內側',\r\n borderHorizontal: '內側橫線',\r\n borderVertical : '內側分隔號',\r\n borderColor : '邊框顏色',\r\n borderSize : '邊框粗細'\r\n },\r\n merge: {\r\n mergeAll : \"全部合併\",\r\n mergeV : \"垂直合併\",\r\n mergeH : \"水平合併\",\r\n mergeCancel : \"取消合併\",\r\n overlappingError: \"不能合併重疊區域\",\r\n partiallyError : \"無法對部分合併儲存格執行此操作\",\r\n },\r\n align: {\r\n left : \"左對齊\",\r\n center: \"中間對齊\",\r\n right : \"右對齊\",\r\n\r\n top : \"頂部對齊\",\r\n middle: \"居中對齊\",\r\n bottom: \"底部對齊\",\r\n },\r\n textWrap: {\r\n \"overflow\": \"溢出\",\r\n \"wrap\" : \"自動換行\",\r\n \"clip\" : \"截斷\",\r\n },\r\n rotation: {\r\n \"none\" : \"無旋轉\",\r\n \"angleup\" : \"向上傾斜\",\r\n \"angledown\" : \"向下傾斜\",\r\n \"vertical\" : \"豎排文字\",\r\n \"rotationUp\" : \"向上90°\",\r\n \"rotationDown\": \"向下90°\"\r\n },\r\n freezen: {\r\n default : \"凍結首行\",\r\n freezenRow : \"凍結首行\",\r\n freezenColumn : \"凍結首列\",\r\n freezenRC : \"凍結行列\",\r\n freezenRowRange : \"凍結行到選區\",\r\n freezenColumnRange: \"凍結列到選區\",\r\n freezenRCRange : \"凍結行列到選區\",\r\n freezenCancel : \"取消凍結\",\r\n\r\n noSeletionError: \"没有選區\",\r\n },\r\n sort: {\r\n \"asc\" : \"昇冪\",\r\n \"desc\" : \"降序\",\r\n \"custom\": \"自定義排序\",\r\n\r\n \"hasTitle\" : \"數據具有標題行\",\r\n \"sortBy\" : \"排序依據\",\r\n \"addOthers\": \"添加其他排序列\",\r\n \"close\" : \"關閉\",\r\n \"confirm\" : \"排序\",\r\n\r\n \"columnOperation\": \"列\",\r\n \"secondaryTitle\" : \"次要排序\",\r\n\r\n \"sortTitle\": \"排序範圍\",\r\n\r\n \"sortRangeTitle\" : \"排序範圍從\",\r\n \"sortRangeTitleTo\": \"到\",\r\n\r\n\r\n \"noRangeError\": \"不能對多重選擇區域執行此操作,請選擇單個區域,然後再試\",\r\n \"mergeError\" : \"選區有合併儲存格,無法執行此操作!\",\r\n\r\n },\r\n filter: {\r\n \"filter\" : \"篩選\",\r\n \"clearFilter\": \"清除篩選\",\r\n\r\n sortByAsc : \"以A-Z昇冪排列\",\r\n sortByDesc : \"以Z-A降序排列\",\r\n filterByColor : \"按顏色篩選\",\r\n filterByCondition: \"按條件過濾\",\r\n filterByValues : \"按值過濾\",\r\n\r\n filiterInputNone: \"無\",\r\n\r\n filiterInputTip : \"輸入篩選值\",\r\n filiterRangeStartTip: \"範圍開始\",\r\n filiterRangeEndTip : \"範圍结束\",\r\n\r\n filterValueByAllBtn : \"全選\",\r\n filterValueByClearBtn : \"清除\",\r\n filterValueByInverseBtn: \"反選\",\r\n filterValueByTip : \"按照值進行篩選\",\r\n filterConform : \"確 認\",\r\n filterCancel : \"取 消\",\r\n clearFilter : \"清除篩選\",\r\n\r\n conditionNone : \"無\",\r\n conditionCellIsNull : \"儲存格為空\",\r\n conditionCellNotNull : \"儲存格有數據\",\r\n conditionCellTextContain : \"文字包含\",\r\n conditionCellTextNotContain: \"文字不包含\",\r\n conditionCellTextStart : \"文字開頭為\",\r\n conditionCellTextEnd : \"文字結尾為\",\r\n conditionCellTextEqual : \"文字等於\",\r\n conditionCellDateEqual : \"日期等於\",\r\n conditionCellDateBefore : \"日期早於\",\r\n conditionCellDateAfter : \"日期晚於\",\r\n conditionCellGreater : \"大於\",\r\n conditionCellGreaterEqual : \"大於等於\",\r\n conditionCellLess : \"小於\",\r\n conditionCellLessEqual : \"小于等於\",\r\n conditionCellEqual : \"等於\",\r\n conditionCellNotEqual : \"不等於\",\r\n conditionCellBetween : \"介於\",\r\n conditionCellNotBetween : \"不在其中\",\r\n\r\n filiterMoreDataTip : \"數據量大!請稍後\",\r\n filiterMonthText : \"月\",\r\n filiterYearText : \"年\",\r\n filiterByColorTip : \"按儲存格顏色篩選\",\r\n filiterByTextColorTip : \"按儲存格字體顏色篩選\",\r\n filterContainerOneColorTip: \"本列僅包含一種顏色\",\r\n filterDateFormatTip : \"日期格式\",\r\n\r\n valueBlank: \"(空白)\",\r\n mergeError: \"篩選選區有合併儲存格,無法執行此操作!\",\r\n },\r\n rightclick: {\r\n copy : '複製',\r\n copyAs : '複製為',\r\n paste : '粘貼',\r\n insert : '插入',\r\n delete : '删除',\r\n deleteCell : '删除儲存格',\r\n deleteSelected : '删除選中',\r\n hide : '隱藏',\r\n hideSelected : '隱藏選中',\r\n showHide : '顯示隱藏',\r\n to : '向',\r\n left : '左',\r\n right : '右',\r\n top : '上',\r\n bottom : '下',\r\n moveLeft : '左移',\r\n moveUp : '上移',\r\n add : '新增',\r\n row : '行',\r\n column : '列',\r\n width : '寬',\r\n height : '高',\r\n number : '數位',\r\n confirm : '確認',\r\n orderAZ : 'A-Z順序排列',\r\n orderZA : 'Z-A降序排列',\r\n clearContent : '清除內容',\r\n matrix : '矩陣操作選區',\r\n sortSelection : '排序選區',\r\n filterSelection : '篩選選區',\r\n chartGeneration : '圖表生成',\r\n firstLineTitle : '首行為標題',\r\n untitled : '無標題',\r\n array1 : '一維數組',\r\n array2 : '二維陣列',\r\n array3 : '多元數組',\r\n diagonal : '對角線',\r\n antiDiagonal : '反對角線',\r\n diagonalOffset : '對角偏移',\r\n offset : '偏移量',\r\n boolean : '布林值',\r\n flip : '翻轉',\r\n upAndDown : '上下',\r\n leftAndRight : '左右',\r\n clockwise : '順時針',\r\n counterclockwise : '逆時針',\r\n transpose : '轉置',\r\n matrixCalculation: '矩陣計算',\r\n plus : '加',\r\n minus : '减',\r\n multiply : '乘',\r\n divided : '除',\r\n power : '次方',\r\n root : '次方根',\r\n log : 'log',\r\n delete0 : '删除兩端0值',\r\n removeDuplicate : '删除重複值',\r\n byRow : '按行',\r\n byCol : '按列',\r\n generateNewMatrix: '生成新矩陣',\r\n },\r\n comment: {\r\n \"insert\" : \"新建批註\",\r\n \"edit\" : \"編輯批註\",\r\n \"delete\" : \"删除\",\r\n \"showOne\": \"顯示/隱藏批註\",\r\n \"showAll\": \"顯示/隱藏所有批註\"\r\n },\r\n screenshot: {\r\n screenshotTipNoSelection: \"請框選需要截圖的範圍\",\r\n screenshotTipTitle : \"提示!\",\r\n screenshotTipHasMerge : \"無法對合併儲存格執行此操作\",\r\n screenshotTipHasMulti : \"無法對多重選擇區域執行此操作\",\r\n screenshotTipSuccess : \"截取成功\",\r\n screenshotImageName : \"截圖\",\r\n\r\n downLoadClose: \"關閉\",\r\n downLoadCopy : \"複製到剪切板\",\r\n downLoadBtn : \"下載\",\r\n browserNotTip: \"下載功能IE瀏覽器不支持!\",\r\n rightclickTip: \"請在圖片上右鍵點擊'複製'\",\r\n successTip : \"已成功複製(如果粘貼失敗,請在圖片上右鍵點擊'複製圖片')\",\r\n },\r\n splitText: {\r\n splitDelimiters : \"分割符號\",\r\n splitOther : \"其它\",\r\n splitContinueSymbol: \"連續分隔符號視為單個處理\",\r\n splitDataPreview : \"數據預覽\",\r\n splitTextTitle : \"文字分列\",\r\n splitConfirmToExe : \"此處已有數據,是否替換它?\",\r\n\r\n tipNoMulti : \"能對多重選擇區域執行此操作,請選擇單個區域,然後再試\",\r\n tipNoMultiColumn: \"一次只能轉換一列數據,選定區域可以有多行,但不能有多列,請在選定單列區域以後再試\",\r\n },\r\n imageText: {\r\n imageSetting: '圖片設定',\r\n close : '關閉',\r\n conventional: '常規',\r\n moveCell1 : '移動並調整儲存格大小',\r\n moveCell2 : '移動並且不調整儲存格的大小',\r\n moveCell3 : '不要移動儲存格並調整其大小',\r\n fixedPos : '固定位置',\r\n border : '邊框',\r\n width : '寬度',\r\n radius : '半徑',\r\n style : '樣式',\r\n solid : '實線',\r\n dashed : '虛線',\r\n dotted : '點狀',\r\n double : '雙線',\r\n color : '顏色',\r\n },\r\n punctuation: {\r\n \"tab\" : \"Tab 鍵\",\r\n \"semicolon\": \"分號\",\r\n \"comma\" : \"逗號\",\r\n \"space\" : \"空格\",\r\n\r\n },\r\n findAndReplace: {\r\n find : \"查找\",\r\n replace : \"替換\",\r\n goto : \"轉到\",\r\n location : \"定位條件\",\r\n formula : \"公式\",\r\n date : \"日期\",\r\n number : \"數位\",\r\n string : \"字元\",\r\n error : \"錯誤\",\r\n condition : \"條件格式\",\r\n rowSpan : \"間隔行\",\r\n columnSpan : \"間隔列\",\r\n locationExample : \"定位\",\r\n lessTwoRowTip : \"請選擇最少兩行\",\r\n lessTwoColumnTip: \"請選擇最少兩行\",\r\n\r\n findTextbox : \"查找内容\",\r\n replaceTextbox: \"替換內容\",\r\n\r\n regexTextbox : \"規則運算式匹配\",\r\n wholeTextbox : \"整詞匹配\",\r\n distinguishTextbox: \"區分大小寫匹配\",\r\n\r\n allReplaceBtn: \"全部替換\",\r\n replaceBtn : \"替換\",\r\n allFindBtn : \"查找全部\",\r\n findBtn : \"查找下一個\",\r\n\r\n noFindTip: \"沒有查找到該內容\",\r\n modeTip : \"該模式下不可進行此操作\",\r\n\r\n searchTargetSheet: \"工作表\",\r\n searchTargetCell : \"儲存格\",\r\n searchTargetValue: \"值\",\r\n\r\n searchInputTip: \"請輸入查找內容\",\r\n\r\n noReplceTip: \"沒有可替換的內容\",\r\n noMatchTip : \"找不到匹配項\",\r\n\r\n successTip: \"已經幫您蒐索並進行了${xlength}處替換\",\r\n\r\n locationConstant : \"常數\",\r\n locationFormula : \"公式\",\r\n locationDate : \"日期\",\r\n locationDigital : \"數位\",\r\n locationString : \"字元\",\r\n locationBool : \"邏輯值\",\r\n locationError : \"錯誤\",\r\n locationNull : \"空值\",\r\n locationCondition : \"條件格式\",\r\n locationRowSpan : \"間隔行\",\r\n locationColumnSpan: \"間隔列\",\r\n\r\n locationTiplessTwoRow : \"請選擇最少兩行\",\r\n locationTiplessTwoColumn: \"請選擇最少兩列\",\r\n locationTipNotFindCell : \"未找到儲存格\"\r\n\r\n },\r\n sheetconfig: {\r\n delete : '删除',\r\n copy : '複製',\r\n rename : '重命名',\r\n changeColor: '更改顏色',\r\n hide : '隱藏',\r\n unhide : '取消隱藏',\r\n moveLeft : '向左移',\r\n moveRight : '向右移',\r\n resetColor : '重置顏色',\r\n cancelText : '取消',\r\n chooseText : '確定顏色',\r\n\r\n tipNameRepeat : \"籤頁的名稱不能重複!請重新修改\",\r\n noMoreSheet : \"工作薄內至少含有一張可視工作表。若需删除選定的工作表,請先插入一張新工作表或顯示一張隱藏的工作表。。\",\r\n confirmDelete : \"是否删除\",\r\n redoDelete : \"可以通過Ctrl+Z撤銷删除\",\r\n noHide : \"不能隱藏,至少保留一個sheet標籤\",\r\n chartEditNoOpt : \"圖表編輯模式下不允許該操作!\",\r\n sheetNameSpecCharError : \"名稱不能包含:[ ] : \\ ? * / ' \\\"\",\r\n sheetNamecannotIsEmptyError: \"名稱不能為空\"\r\n },\r\n conditionformat: {\r\n conditionformat_greaterThan : '條件格式——大於',\r\n conditionformat_greaterThan_title : '為大於以下值的儲存格設定格式',\r\n conditionformat_lessThan : '條件格式——小於',\r\n conditionformat_lessThan_title : '為小於以下值的儲存格設定格式',\r\n conditionformat_betweenness : '條件格式——介於',\r\n conditionformat_betweenness_title : '為介於以下值的儲存格設定格式',\r\n conditionformat_equal : '條件格式——等於',\r\n conditionformat_equal_title : '為等於以下值的儲存格設定格式',\r\n conditionformat_textContains : '條件格式——文字包含',\r\n conditionformat_textContains_title : '為包含以下文字的儲存格設定格式',\r\n conditionformat_occurrenceDate : '條件格式——發生日期',\r\n conditionformat_occurrenceDate_title: '為包含以下日期的儲存格設定格式',\r\n conditionformat_duplicateValue : '條件格式——重複值',\r\n conditionformat_duplicateValue_title: '為包含以下類型值的儲存格設定格式',\r\n conditionformat_top10 : '條件格式——前10項',\r\n conditionformat_top10_percent : '條件格式——前10%',\r\n conditionformat_top10_title : '為值最大的那些儲存格設定格式',\r\n conditionformat_last10 : '條件格式——最後10項',\r\n conditionformat_last10_percent : '條件格式——最後10%',\r\n conditionformat_last10_title : '為值最小的那些儲存格設定格式',\r\n conditionformat_AboveAverage : '條件格式——高於平均值',\r\n conditionformat_AboveAverage_title : '為高於平均值的儲存格設定格式',\r\n conditionformat_SubAverage : '條件格式——低於平均值',\r\n conditionformat_SubAverage_title : '為低於平均值的儲存格設定格式',\r\n rule : '規則',\r\n newRule : '新建規則',\r\n editRule : '編輯規則',\r\n deleteRule : '删除規則',\r\n deleteCellRule : '清除所選儲存格的規則',\r\n deleteSheetRule : '清除整個工作表的規則',\r\n manageRules : '管理規則',\r\n showRules : '顯示其格式規則',\r\n highlightCellRules : '突出顯示儲存格規則',\r\n itemSelectionRules : '項目選取規則',\r\n conditionformatManageRules : '條件格式規則管理器',\r\n format : '格式',\r\n setFormat : '設定格式',\r\n setAs : '設定為',\r\n setAsByArea : '針對選定區域,設定為',\r\n applyRange : '應用範圍',\r\n selectRange : '點擊選擇應用範圍',\r\n selectRange_percent : '所選範圍的百分比',\r\n selectRange_average : '選定範圍的平均值',\r\n selectRange_value : '選定範圍中的數值',\r\n pleaseSelectRange : '請選擇應用範圍',\r\n selectDataRange : '點擊選擇數據範圍',\r\n selectCell : '選擇儲存格',\r\n pleaseSelectCell : '請選擇儲存格',\r\n pleaseSelectADate : '請選擇日期',\r\n pleaseEnterInteger : '請輸入一個介於1和1000之間的整數',\r\n onlySingleCell : '只能對單個儲存格進行引用',\r\n conditionValueCanOnly : '條件值只能是數位或者單個儲存格',\r\n ruleTypeItem1 : '基於各自值設定所有儲存格的格式',\r\n ruleTypeItem2 : '只為包含以下內容的儲存格設定格式',\r\n ruleTypeItem2_title : '只為滿足以下條件的儲存格',\r\n ruleTypeItem3 : '僅對排名靠前或靠後的數值設定格式',\r\n ruleTypeItem3_title : '為以下排名內的值',\r\n ruleTypeItem4 : '僅對高於或低於平均值的數值設定格式',\r\n ruleTypeItem4_title : '為滿足以下條件的值',\r\n ruleTypeItem5 : '僅對唯一值或重複值設定格式',\r\n ruleTypeItem6 : '使用公式確定要設置格式的單元格',\r\n formula : '公式',\r\n textColor : '文字顏色',\r\n cellColor : '儲存格顏色',\r\n confirm : '確定',\r\n confirmColor : '確定顏色',\r\n cancel : '取消',\r\n close : '關閉',\r\n clearColorSelect : '清除顏色選擇',\r\n sheet : '錶',\r\n currentSheet : '當前工作表',\r\n dataBar : '數據條',\r\n dataBarColor : '數據條顏色',\r\n gradientDataBar_1 : '藍-白漸變數據條',\r\n gradientDataBar_2 : '綠-白漸變數據條',\r\n gradientDataBar_3 : '紅-白漸變數據條',\r\n gradientDataBar_4 : '柳丁-白漸變數據條',\r\n gradientDataBar_5 : '淺藍-白漸變數據條',\r\n gradientDataBar_6 : '紫-白漸變數據條',\r\n solidColorDataBar_1 : '藍色數據條',\r\n solidColorDataBar_2 : '綠色數據條',\r\n solidColorDataBar_3 : '紅色數據條',\r\n solidColorDataBar_4 : '橙色數據條',\r\n solidColorDataBar_5 : '淺藍色數據條',\r\n solidColorDataBar_6 : '紫色數據條',\r\n colorGradation : '色階',\r\n colorGradation_1 : '綠-黃-紅色階',\r\n colorGradation_2 : '紅-黃-綠色階',\r\n colorGradation_3 : '綠-白-紅色階',\r\n colorGradation_4 : '紅-白-綠色階',\r\n colorGradation_5 : '藍-白-紅色階',\r\n colorGradation_6 : '紅-白-藍色階',\r\n colorGradation_7 : '白-紅色階',\r\n colorGradation_8 : '紅-白色階',\r\n colorGradation_9 : '綠-白色階',\r\n colorGradation_10 : '白-綠色階',\r\n colorGradation_11 : '綠-黃色階',\r\n colorGradation_12 : '黃-綠色階',\r\n icons : '圖標集',\r\n pleaseSelectIcon : '請點擊選擇一組圖標:',\r\n cellValue : '儲存格值',\r\n specificText : '特定文字',\r\n occurrence : '發生日期',\r\n greaterThan : '大於',\r\n lessThan : '小於',\r\n between : '介於',\r\n equal : '等於',\r\n in : '和',\r\n to : '到',\r\n between2 : '之間',\r\n contain : '包含',\r\n textContains : '文字包含',\r\n duplicateValue : '重複值',\r\n uniqueValue : '唯一值',\r\n top : '前',\r\n top10 : '前10項',\r\n top10_percent : '前10%',\r\n last : '後',\r\n last10 : '後10項',\r\n last10_percent : '後10%',\r\n oneself : '個',\r\n above : '高於',\r\n aboveAverage : '高於平均值',\r\n below : '低於',\r\n belowAverage : '低於平均值',\r\n all : '全部',\r\n yesterday : '昨天',\r\n today : '今天',\r\n tomorrow : '明天',\r\n lastWeek : '上周',\r\n thisWeek : '本周',\r\n lastMonth : '上月',\r\n thisMonth : '本月',\r\n lastYear : '去年',\r\n thisYear : '本年',\r\n last7days : '最近7天',\r\n last30days : '最近30天',\r\n next7days : '未來7天',\r\n next30days : '未來30天',\r\n next60days : '未來60天',\r\n chooseRuleType : '選擇規則類型',\r\n editRuleDescription : '編輯規則說明',\r\n newFormatRule : '新建格式規則',\r\n editFormatRule : '編輯格式規則',\r\n formatStyle : '格式樣式',\r\n fillType : '填充類型',\r\n color : '顏色',\r\n twocolor : '雙色',\r\n tricolor : '三色',\r\n multicolor : '彩色',\r\n grayColor : '灰色',\r\n gradient : '漸變',\r\n solid : '實心',\r\n maxValue : '最大值',\r\n medianValue : '中間值',\r\n minValue : '最小值',\r\n direction : '方向',\r\n threeWayArrow : '三向箭頭',\r\n fourWayArrow : '四向箭頭',\r\n fiveWayArrow : '五向箭頭',\r\n threeTriangles : '3個三角形',\r\n shape : '形狀',\r\n threeColorTrafficLight : '三色交通燈',\r\n fourColorTrafficLight : '四色交通燈',\r\n threeSigns : '三標誌',\r\n greenRedBlackGradient : '綠-紅-黑漸變',\r\n rimless : '無邊框',\r\n bordered : '有邊框',\r\n mark : '標記',\r\n threeSymbols : '三個符號',\r\n tricolorFlag : '三色旗',\r\n circled : '有圓圈',\r\n noCircle : '無圓圈',\r\n grade : '等級',\r\n grade4 : '四等級',\r\n grade5 : '五等級',\r\n threeStars : '3個星形',\r\n fiveQuadrantDiagram : '五象限圖',\r\n fiveBoxes : '5個框',\r\n },\r\n insertLink: {\r\n linkText : \"文字\",\r\n linkType : \"連結類型\",\r\n external : \"外部連結\",\r\n internal : \"内部連結\",\r\n linkAddress : \"連結地址\",\r\n linkSheet : \"工作表\",\r\n linkCell : \"儲存格引用\",\r\n linkTooltip : \"提示\",\r\n placeholder1: \"請輸入網頁連結位址\",\r\n placeholder2: \"請輸入要引用的儲存格,例A1\",\r\n placeholder3: \"請輸入提示內容\",\r\n tooltipInfo1: \"請輸入有效的連結\",\r\n tooltipInfo2: \"請輸入正確的儲存格引用\",\r\n },\r\n dataVerification: {\r\n cellRange : '儲存格範圍',\r\n selectCellRange : '點擊選擇儲存格範圍',\r\n selectCellRange2 : '請選擇儲存格範圍',\r\n verificationCondition: '驗證條件',\r\n dropdown : '下拉清單',\r\n checkbox : '核取方塊',\r\n number : '數位',\r\n number_integer : '數位-整數',\r\n number_decimal : '數位-小數',\r\n text_content : '文字-內容',\r\n text_length : '文字-長度',\r\n date : '日期',\r\n validity : '有效性',\r\n placeholder1 : '請輸入選項,以英文逗號分隔,如1,2,3,4,5',\r\n placeholder2 : '請輸入內容',\r\n placeholder3 : '數值,如10',\r\n placeholder4 : '請輸入指定的文字',\r\n placeholder5 : '請輸入選中儲存格時顯示的提示語',\r\n selected : '選擇時',\r\n notSelected : '未選擇',\r\n between : '介於',\r\n notBetween : '不介於',\r\n equal : '等於',\r\n notEqualTo : '不等於',\r\n moreThanThe : '大於',\r\n lessThan : '小於',\r\n greaterOrEqualTo : '大於等於',\r\n lessThanOrEqualTo : '小於等於',\r\n include : '包括',\r\n exclude : '不包括',\r\n earlierThan : '早於',\r\n noEarlierThan : '不早於',\r\n laterThan : '晚於',\r\n noLaterThan : '不晚於',\r\n identificationNumber : '身份證號碼',\r\n phoneNumber : '手機號',\r\n remote : '自動遠程獲取選項',\r\n prohibitInput : '輸入數據無效時禁止輸入',\r\n hintShow : '選中儲存格時顯示提示語',\r\n deleteVerification : '删除驗證',\r\n tooltipInfo1 : '下拉清單選項不可為空',\r\n tooltipInfo2 : '核取方塊內容不可為空',\r\n tooltipInfo3 : '輸入的值不是數值類型',\r\n tooltipInfo4 : '數值2不能小於數值1',\r\n tooltipInfo5 : '文字內容不能為空',\r\n tooltipInfo6 : '輸入的值不是日期類型',\r\n tooltipInfo7 : '日期2不能小於日期1',\r\n },\r\n formula: {\r\n sum : \"求和\",\r\n average : \"平均值\",\r\n count : \"計數\",\r\n max : \"最大值\",\r\n min : \"最小值\",\r\n ifGenerate: \"if公式生成器\",\r\n find : \"更多函數\",\r\n\r\n tipNotBelongToIf: \"該儲存格函數不屬於if公式!\",\r\n tipSelectCell : \"請選擇儲存格插入函數\",\r\n\r\n ifGenCompareValueTitle: \"比较值\",\r\n ifGenSelectCellTitle : \"點擊選擇儲存格\",\r\n ifGenRangeTitle : \"範圍\",\r\n ifGenRangeTo : \"至\",\r\n ifGenRangeEvaluate : \"範圍評估\",\r\n ifGenSelectRangeTitle : \"點擊選擇範圍\",\r\n ifGenCutWay : \"劃分管道\",\r\n ifGenCutSame : \"劃分值相同\",\r\n ifGenCutNpiece : \"劃分为N份\",\r\n ifGenCutCustom : \"自定義輸入\",\r\n ifGenCutConfirm : \"生成\",\r\n\r\n ifGenTipSelectCell : \"選擇儲存格\",\r\n ifGenTipSelectCellPlace: \"請選擇儲存格\",\r\n\r\n ifGenTipSelectRange : \"選擇單範圍\",\r\n ifGenTipSelectRangePlace: \"請選擇範圍\",\r\n\r\n ifGenTipNotNullValue : \"比較值不能為空!\",\r\n ifGenTipLableTitile : \"標籤\",\r\n ifGenTipRangeNotforNull : \"範圍不能為空!\",\r\n ifGenTipCutValueNotforNull: \"劃分值不能為空!\",\r\n ifGenTipNotGenCondition : \"沒有生成可用的條件!\",\r\n },\r\n formulaMore: {\r\n valueTitle : \"值\",\r\n tipSelectDataRange : \"選取數據範圍\",\r\n tipDataRangeTile : \"數據範圍\",\r\n findFunctionTitle : \"查找函數\",\r\n tipInputFunctionName: \"請輸入您要查找的函數名稱或函數功能的簡要描述\",\r\n\r\n Array : \"數組\",\r\n Database : \"資料來源\",\r\n Date : \"日期\",\r\n Engineering: \"工程計算\",\r\n Filter : \"篩檢程式\",\r\n Financial : \"財務\",\r\n luckysheet : \"Luckysheet內寘\",\r\n other : \"其它\",\r\n Logical : \"邏輯\",\r\n Lookup : \"查找\",\r\n Math : \"數學\",\r\n Operator : \"運算子\",\r\n Parser : \"轉換工具\",\r\n Statistical: \"統計\",\r\n Text : \"文字\",\r\n dataMining : \"資料挖掘\",\r\n\r\n selectFunctionTitle: \"選擇函數\",\r\n calculationResult : \"計算結果\",\r\n\r\n tipSuccessText : \"成功\",\r\n tipParamErrorText: \"參數類型錯誤\",\r\n\r\n helpClose : \"關閉\",\r\n helpCollapse: \"收起\",\r\n helpExample : \"示例\",\r\n helpAbstract: \"摘要\",\r\n\r\n execfunctionError : '提示\", \"公式存在錯誤',\r\n execfunctionSelfError : '公式不可引用其本身的儲存格',\r\n execfunctionSelfErrorResult: '公式不可引用其本身的儲存格,會導致計算結果不準確',\r\n\r\n allowRepeatText: \"可重複\",\r\n allowOptionText: \"可選\",\r\n\r\n selectCategory: \"或選擇類別\",\r\n },\r\n drag: {\r\n noMerge : \"無法對合併儲存格執行此操作\",\r\n affectPivot: \"無法對所選儲存格進行此更改,因為它會影響數據透視錶!\",\r\n noMulti : \"無法對多重選擇區域執行此操作,請選擇單個區域\",\r\n noPaste : \"無法在此處粘貼此內容,請選擇粘貼區域的一個儲存格,然後再次嘗試粘貼\",\r\n noPartMerge: \"無法對部分合併儲存格執行此操作\",\r\n\r\n inputCorrect : \"請輸入正確的數值\",\r\n notLessOne : \"行列數不能小於1\",\r\n offsetColumnLessZero: \"偏移列不能為負數!\",\r\n\r\n pasteMustKeybordAlert : \"Copy and paste in the Sheet: Ctrl + C to copy, Ctrl + V to paste, Ctrl + X to cut\",\r\n pasteMustKeybordAlertHTMLTitle: \"Copy and paste in the Sheet\",\r\n pasteMustKeybordAlertHTML : \"Ctrl + C  to copy
Ctrl + V  to paste
Ctrl + X  to cut\",\r\n },\r\n pivotTable: {\r\n title : \"數據透視錶\",\r\n closePannel : \"關閉\",\r\n editRange : \"編輯範圍\",\r\n tipPivotFieldSelected: \"選擇需要添加到數據透視錶的欄位\",\r\n tipClearSelectedField: \"清除所有已選欄位\",\r\n btnClearSelectedField: \"清除\",\r\n btnFilter : \"篩選\",\r\n titleRow : \"行\",\r\n titleColumn : \"列\",\r\n titleValue : \"數值\",\r\n tipShowColumn : \"統計欄位顯示為列\",\r\n tipShowRow : \"統計欄位顯示為行\",\r\n\r\n titleSelectionDataRange: \"選取數據範圍\",\r\n titleDataRange : \"數據範圍\",\r\n\r\n valueSum: \"總計\",\r\n\r\n valueStatisticsSUM : \"求和\",\r\n valueStatisticsCOUNT : \"數值計數\",\r\n valueStatisticsCOUNTA : \"計數\",\r\n valueStatisticsCOUNTUNIQUE: \"去重計數\",\r\n valueStatisticsAVERAGE : \"平均值\",\r\n valueStatisticsMAX : \"最大值\",\r\n valueStatisticsMIN : \"最小值\",\r\n valueStatisticsMEDIAN : \"中位數\",\r\n valueStatisticsPRODUCT : \"乘積\",\r\n valueStatisticsSTDEV : \"標準差\",\r\n\r\n valueStatisticsSTDEVP: \"整體標準差\",\r\n valueStatisticslet : \"方差\",\r\n valueStatisticsVARP : \"整體方差\",\r\n\r\n errorNotAllowEdit : \"非編輯模式下禁止該操作!\",\r\n errorNotAllowMulti : \"不能對多重選擇區域執行此操作,請選擇單個區域,然後再試\",\r\n errorSelectRange : \"請選擇新建透視錶的區域\",\r\n errorIsDamage : \"此數據透視錶的源數據已損壞!\",\r\n errorNotAllowPivotData: \"不可選擇數據透視錶為源數據!\",\r\n errorSelectionRange : \"選擇失敗,輸入範圍錯誤!\",\r\n errorIncreaseRange : \"請擴大選擇的數據範圍!\",\r\n\r\n titleAddColumn : \"添加列到數據透視錶\",\r\n titleMoveColumn : \"移動該列到下方白框\",\r\n titleClearColumnFilter: \"清除該列的篩選條件\",\r\n titleFilterColumn : \"篩選該列\",\r\n\r\n titleSort : \"排序\",\r\n titleNoSort : \"無排序\",\r\n titleSortAsc : \"昇冪\",\r\n titleSortDesc : \"降序\",\r\n titleSortBy : \"排序依據\",\r\n titleShowSum : \"顯示總計\",\r\n titleStasticTrue : \"是\",\r\n titleStasticFalse: \"否\",\r\n },\r\n dropCell: {\r\n copyCell : \"複製儲存格\",\r\n sequence : \"填充序列\",\r\n onlyFormat : \"僅填充格式\",\r\n noFormat : \"不帶格式填充\",\r\n day : \"以天數填充\",\r\n workDay : \"以工作日填充\",\r\n month : \"以月填充\",\r\n year : \"以年填充\",\r\n chineseNumber: \"以中文小寫數位填充\"\r\n },\r\n imageCtrl: {\r\n borderTile: \"圖片邊框顏色選擇\",\r\n borderCur : \"當前顏色\",\r\n },\r\n protection: {\r\n protectiontTitle : \"保護工作表\",\r\n enterPassword : \"請輸入密碼(可留空)\",\r\n enterHint : \"您試圖更改的儲存格或圖表位於受保護的工作表中。若要更改,請取消工作表保護。您可能需要輸入密碼\",\r\n swichProtectionTip : \"保護工作表及鎖定的儲存格內容\",\r\n authorityTitle : \"允許此工作表的用戶進行:\",\r\n selectLockedCells : \"定鎖定儲存格\",\r\n selectunLockedCells : \"選定解除鎖定的儲存格\",\r\n formatCells : \"設定儲存格格式\",\r\n formatColumns : \"設定列格式\",\r\n formatRows : \"設定行格式\",\r\n insertColumns : \"插入列\",\r\n insertRows : \"插入行\",\r\n insertHyperlinks : \"插入超連結\",\r\n deleteColumns : \"删除列\",\r\n deleteRows : \"删除行\",\r\n sort : \"排序\",\r\n filter : \"使用自動篩選\",\r\n usePivotTablereports: \"使用數據透視錶和報表\",\r\n editObjects : \"編輯對象\",\r\n editScenarios : \"編輯方案\",\r\n\r\n allowRangeTitle: \"允許用戶編輯區域\",\r\n allowRangeAdd : \"新建...\",\r\n\r\n allowRangeAddTitle : \"標題\",\r\n allowRangeAddSqrf : \"引用儲存格\",\r\n selectCellRange : '點擊選擇儲存格範圍',\r\n selectCellRangeHolder : \"請輸入儲存格範圍\",\r\n allowRangeAddTitlePassword : \"密碼\",\r\n allowRangeAddTitleHint : \"提示\",\r\n allowRangeAddTitleHintTitle: \"設置密碼後,提示用戶輸入密碼(可留空)\",\r\n allowRangeAddtitleDefault : \"請輸入區域名稱\",\r\n\r\n rangeItemDblclick : \"按兩下進行編輯\",\r\n rangeItemHasPassword: \"已設置密碼\",\r\n\r\n rangeItemErrorTitleNull: \"標題不能為空\",\r\n rangeItemErrorRangeNull: \"儲存格範圍不能為空\",\r\n rangeItemErrorRange : \"儲存格範圍格式錯誤\",\r\n\r\n validationTitle : \"驗證提示\",\r\n validationTips : \"需要輸入密碼來撤銷工作表的保護\",\r\n validationInputHint: \"請輸入密碼\",\r\n\r\n checkPasswordNullalert : \"密碼不能為空!\",\r\n checkPasswordWrongalert: \"密碼錯誤,請重試!\",\r\n\r\n checkPasswordSucceedalert: \"解鎖成功,可以編輯該區域!\",\r\n defaultRangeHintText : \"該儲存格正在受密碼保護\",\r\n defaultSheetHintText : \"該儲存格或圖表位於受保護的工作表中,若要進行更改,請取消工作表保護,您可能需要輸入密碼。\",\r\n },\r\n cellFormat: {\r\n cellFormatTitle : \"設定儲存格格式\",\r\n protection : \"保護\",\r\n locked : \"鎖定儲存格\",\r\n hidden : \"隱藏公式\",\r\n protectionTips : \"只有保護工作表功能(在功能表列點擊保護工作表按鈕進行設定)開啟後,鎖定儲存格或隱藏公式才能生效\",\r\n tipsPart : \"部分選中\",\r\n tipsAll : \"全部選中\",\r\n selectionIsNullAlert: \"請選擇一個範圍!\",\r\n sheetDataIsNullAlert: \"數據為空無法設定!\",\r\n },\r\n print: {\r\n normalBtn: \"常規視圖\",\r\n layoutBtn: \"頁面佈局\",\r\n pageBtn : \"分頁預覽\",\r\n\r\n menuItemPrint : \"列印(Ctrl+P)\",\r\n menuItemAreas : \"列印區域\",\r\n menuItemRows : \"列印標題行\",\r\n menuItemColumns: \"列印標題列\",\r\n },\r\n edit: {\r\n typing: \"正在輸入\",\r\n },\r\n websocket: {\r\n success: 'WebSocket連接成功',\r\n refresh: 'WebSocket連接發生錯誤,請刷新頁面!',\r\n wait : 'WebSocket連接發生錯誤,請耐心等待!',\r\n close : 'WebSocket連接關閉',\r\n contact: '服務器通信發生錯誤,請刷新頁面後再試,如若不行請聯系管理員!',\r\n support: '當前瀏覽器不支持WebSocket',\r\n }\r\n\r\n};\r\n","import locale from '../locale/locale';\r\nimport Store from '../store';\r\nimport luckysheetConfigsetting from './luckysheetConfigsetting';\r\nimport { getObjType } from '../utils/util';\r\n//dom variable\r\nconst gridHTML = function(){ \r\n const _locale = locale();\r\n const locale_info = _locale.info;\r\n const locale_print = _locale.print;\r\n const userInfo = luckysheetConfigsetting.userInfo === true ? ' Lucky' : luckysheetConfigsetting.userInfo; // When true, use the default HTML string. The rendering of userInfo below uses nested template strings. Otherwise, when display is used and the image path is not passed in, there will be an undefined request\r\n\r\n return `
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
${locale_info.detailUpdate}
\r\n
${locale_info.wait}
\r\n \r\n \\${functionButton}\r\n \r\n ${getObjType(userInfo) === 'string' ? `
\r\n ${userInfo}
` : ''}\r\n\r\n ${getObjType(userInfo) === 'object' ? `
\r\n \r\n ${userInfo.userName}\r\n
` : ''}\r\n \r\n
\r\n
\\${menu}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\\${columnHeader}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\\${rowHeader}\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\\${flow} \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
100%
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
`;\r\n}\r\n\r\nconst columeHeader_word = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],\r\n columeHeader_word_index = { 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9, 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18, 'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25 },\r\n flow = '
${flow}
',\r\n colsmenuHTML = '';\r\n\r\n//右键菜单dom\r\nfunction rightclickHTML(){\r\n const _locale = locale();\r\n const rightclick = _locale.rightclick;\r\n const toolbar = _locale.toolbar;\r\n\r\n const config = customCellRightClickConfig();\r\n\r\n // 当一个功能菜单块内所有的按钮都隐藏的时候,它顶部的分割线也需要隐藏掉\r\n let handleincellMenuseparator = true;\r\n\r\n if(!config.insertRow && !config.insertColumn && !config.deleteRow && !config.deleteColumn && !config.deleteCell ){\r\n handleincellMenuseparator = false;\r\n }\r\n\r\n let dataMenuseparator = true;\r\n\r\n if(!config.clear && !config.matrix && !config.sort && !config.filter && !config.chart && !config.image && !config.link && !config.data && !config.cellFormat){\r\n dataMenuseparator = false;\r\n }\r\n\r\n const rightclickContainer = `
\r\n
\r\n
${rightclick.copy}
\r\n
\r\n
\r\n
\r\n ${rightclick.copyAs}\r\n
\r\n
\r\n
\r\n
${rightclick.paste}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.insert}${rightclick.row}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.insert}${rightclick.column}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.deleteSelected}${rightclick.row}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.deleteSelected}${rightclick.column}\r\n
\r\n
\r\n \r\n
\r\n
\r\n ${rightclick.deleteCell}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.to}\r\n ${rightclick.left}\r\n ${rightclick.add}\r\n \r\n ${rightclick.column}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.to}\r\n ${rightclick.right}\r\n ${rightclick.add}\r\n \r\n ${rightclick.column}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.deleteSelected}\r\n ${rightclick.column}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.hideSelected}\r\n ${rightclick.column}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.showHide}\r\n ${rightclick.column}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.column}\r\n ${rightclick.width}\r\n \r\n px\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
${rightclick.orderAZ}
\r\n
\r\n
\r\n
${rightclick.orderZA}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
${rightclick.clearContent}
\r\n
\r\n
\r\n
\r\n ${rightclick.matrix}\r\n
\r\n
\r\n
\r\n
${rightclick.sortSelection}
\r\n
\r\n
\r\n
${rightclick.filterSelection}
\r\n
\r\n
\r\n
${rightclick.chartGeneration}
\r\n
\r\n
\r\n
${toolbar.insertImage}
\r\n
\r\n
\r\n
${toolbar.insertLink}
\r\n
\r\n
\r\n
${toolbar.dataVerification}
\r\n
\r\n
\r\n
${toolbar.cellFormat}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
Json ${rightclick.firstLineTitle}
\r\n
\r\n
\r\n
Json ${rightclick.untitled}
\r\n
\r\n
\r\n
${rightclick.array1}
\r\n
\r\n
\r\n
${rightclick.array2}
\r\n
\r\n
\r\n
\r\n ${rightclick.array3}\r\n \r\n ×\r\n \r\n
\r\n
\r\n
\r\n
\r\n
${rightclick.diagonal}
\r\n
\r\n
\r\n
${rightclick.antiDiagonal}
\r\n
\r\n
\r\n
\r\n ${rightclick.diagonalOffset}\r\n \r\n ${rightclick.column}\r\n
\r\n
\r\n
\r\n
${rightclick.boolean}
\r\n
\r\n
\r\n \r\n \r\n\r\n \r\n\r\n \r\n\r\n
\r\n
\r\n
\r\n ${rightclick.moveLeft}\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.moveUp}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.flip}\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.flip}\r\n \r\n \r\n
\r\n
\r\n
\r\n
${rightclick.transpose}
\r\n
\r\n
\r\n
\r\n
\r\n
${rightclick.matrixCalculation}
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.delete0}\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n ${rightclick.removeDuplicate}\r\n \r\n \r\n
\r\n
\r\n
`;\r\n\r\n return rightclickContainer;\r\n}\r\n\r\nconst pivottableconfigHTML = function(){\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n\r\n return '
'+locale_pivotTable.titleSort+'
'+locale_pivotTable.titleSortBy+'
'+locale_pivotTable.titleShowSum+'
';\r\n} \r\n\r\nconst pivottablesumHTML = function(){\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n\r\n return '
'+locale_pivotTable.valueStatisticsSUM+'
'+locale_pivotTable.valueStatisticsCOUNT+'
'+locale_pivotTable.valueStatisticsCOUNTA+'
'+locale_pivotTable.valueStatisticsCOUNTUNIQUE+'
'+locale_pivotTable.valueStatisticsAVERAGE+'
'+locale_pivotTable.valueStatisticsMAX+'
'+locale_pivotTable.valueStatisticsMIN+'
'+locale_pivotTable.valueStatisticsMEDIAN+'
'+locale_pivotTable.valueStatisticsPRODUCT+'
'+locale_pivotTable.valueStatisticsSTDEV+'
'+locale_pivotTable.valueStatisticsSTDEVP+'
'+locale_pivotTable.valueStatisticslet+'
'+locale_pivotTable.valueStatisticsVARP+'
';\r\n} \r\n\r\nconst sheetHTML = '
${name} ${colorset}
',\r\n columnHeaderHTML = '
${column}
',\r\n sheetselectlistHTML = '
${item}
',\r\n sheetselectlistitemHTML = '
${icon}${name}
',\r\n inputHTML = '
',\r\n modelHTML = '
${title}\t
${content}
\t ${botton}
',\r\n\r\n maskHTML = '
';\r\n\r\n//底部 表格标签操作dom\r\nfunction sheetconfigHTML(){\r\n const sheetconfig = locale().sheetconfig;\r\n\r\n const config = customSheetRightClickConfig();\r\n\r\n /* 如果配置项全部为flase,则隐藏入口且不再菜单项 */\r\n if(Object.values(config).every(ele=> !ele)){\r\n $('#luckysheet-sheet-container-c').addClass(\"luckysheet-sheet-container-menu-hide\");\r\n return \"\";\r\n }\r\n\r\n let hideTopMenuseparator = true;\r\n let moveTopMenuseparator = true;\r\n\r\n // 1. 当一个功能菜单块上方的功能块按钮都隐藏的时候,下方的功能块的顶部分割线也需要隐藏\r\n if(!config.delete && !config.copy && !config.rename && !config.color){\r\n hideTopMenuseparator = false;\r\n if(!config.hide){\r\n moveTopMenuseparator = false;\r\n }\r\n }\r\n\r\n // 2. 当一个功能菜单块内所有的按钮都隐藏的时候,它顶部的分割线也需要隐藏掉\r\n if(!config.hide){\r\n hideTopMenuseparator = false;\r\n }\r\n if(!config.move){\r\n moveTopMenuseparator = false;\r\n }\r\n\r\n\r\n const sheetconfigModel = `
\r\n
\r\n
${sheetconfig.delete}
\r\n
\r\n
\r\n
${sheetconfig.copy}
\r\n
\r\n
\r\n
${sheetconfig.rename}
\r\n
\r\n
\r\n
\r\n ${sheetconfig.changeColor} \r\n
\r\n
\r\n
\r\n
\r\n
${sheetconfig.hide}
\r\n
\r\n
\r\n
${sheetconfig.unhide}
\r\n
\r\n
\r\n
\r\n
${sheetconfig.moveLeft}
\r\n
\r\n
\r\n
${sheetconfig.moveRight}
\r\n
\r\n
\r\n
\r\n
\r\n
${sheetconfig.resetColor}
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
`;\r\n\r\n return sheetconfigModel;\r\n}\r\n\r\nconst luckysheetPivotTableHTML = function(){\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n // return '
'+locale_pivotTable.title+'
'+locale_pivotTable.editRange+'
'+locale_pivotTable.tipPivotFieldSelected+' '+locale_pivotTable.btnClearSelectedField+'
'+locale_pivotTable.btnFilter+'
'+locale_pivotTable.titleRow+'
'+locale_pivotTable.titleColumn+'
'+locale_pivotTable.titleValue+'
';\r\n return `\r\n
\r\n
${locale_pivotTable.title}
\r\n
\r\n
\r\n
\r\n
${locale_pivotTable.editRange}
\r\n
\r\n
${locale_pivotTable.tipPivotFieldSelected} ${locale_pivotTable.btnClearSelectedField}
\r\n
\r\n
\r\n
\r\n
${locale_pivotTable.btnFilter}
\r\n
\r\n
\r\n
\r\n
${locale_pivotTable.titleRow}
\r\n
\r\n
\r\n
\r\n
${locale_pivotTable.titleColumn}
\r\n
\r\n
\r\n
\r\n
${locale_pivotTable.titleValue}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n `;\r\n} \r\n\r\nfunction filtermenuHTML() { \r\n const _locale = locale();\r\n const locale_filter = _locale.filter;\r\n \r\n return `
${locale_filter.sortByAsc}
${locale_filter.sortByDesc}
${locale_filter.filterByColor}
${locale_filter.filterByCondition}
${locale_filter.filiterInputNone}
${locale_filter.filterByValues}
${locale_filter.filterValueByAllBtn} - ${locale_filter.filterValueByClearBtn} - ${locale_filter.filterValueByInverseBtn}
${locale_filter.filterConform}
${locale_filter.filterCancel}
${locale_filter.clearFilter}
`\r\n}\r\n\r\nfunction filtersubmenuHTML() {\r\n const _locale = locale();\r\n const locale_filter = _locale.filter;\r\n \r\n return `
${locale_filter.conditionNone}
${locale_filter.conditionCellIsNull}
${locale_filter.conditionCellNotNull}
${locale_filter.conditionCellTextContain}
${locale_filter.conditionCellTextNotContain}
${locale_filter.conditionCellTextStart}
${locale_filter.conditionCellTextEnd}
${locale_filter.conditionCellTextEqual}
${locale_filter.conditionCellDateEqual}
${locale_filter.conditionCellDateBefore}
${locale_filter.conditionCellDateAfter}
${locale_filter.conditionCellGreater}
${locale_filter.conditionCellGreaterEqual}
${locale_filter.conditionCellLess}
${locale_filter.conditionCellLessEqual}
${locale_filter.conditionCellEqual}
${locale_filter.conditionCellNotEqual}
${locale_filter.conditionCellBetween}
${locale_filter.conditionCellNotBetween}
`\r\n}\r\n\r\nfunction luckysheetAlternateformatHtml(){\r\n const _locale = locale()\r\n const alternatingColors =_locale.alternatingColors;\r\n const toolbar = _locale.toolbar;\r\n\r\n\r\n return '
'+\r\n '
'+\r\n ''+ toolbar.alternatingColors +''+\r\n ''+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n '
'+ alternatingColors.applyRange +'
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n '
'+alternatingColors.textTitle+'
'+\r\n '
'+\r\n '
'+alternatingColors.custom+'
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+ alternatingColors.header +'
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+ alternatingColors.colorShow +'1
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+ alternatingColors.colorShow +'2
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+ alternatingColors.footer +'
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n ''+\r\n '
'+\r\n '
';\r\n}\r\n\r\nconst luckysheetchartpointconfigHTML = '
选择维度
排序
全选 - 清除 - 反选可以直接框选数据点
数据点设置
图形颜色
图形大小
图形形状
边框粗细
边框样式
边框颜色
文字标签
数值比例
小数位数
标签格式
数据名称
标签位置

';\r\nconst luckysheetToolHTML = '
组合图表
';\r\n\r\n// toolbar\r\nfunction menuToolBar (){\r\n const toolbar = locale().toolbar;\r\n const fontarray = locale().fontarray;\r\n const defaultFmtArray = locale().defaultFmt;\r\n \r\n // \r\n return `
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${defaultFmtArray[0].text}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${fontarray[0]}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${toolbar.sum}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n `;\r\n} \r\n\r\nconst luckysheetlodingHTML = function(){ \r\n const _locale = locale()\r\n const info =_locale.info;\r\n return'
'+info.loading+'...
';\r\n}\r\n// var menusetting = {\r\n// menu_selectall: '
全选
',\r\n// menu_copy: '
复制
',\r\n// menu_undo: '
撤销
',\r\n// menu_redo: '
恢复
',\r\n// menu_paste: '
粘贴
',\r\n// menu_download: '
下载
',\r\n// menu_share: '
分享
',\r\n// menu_chart: '
图表生成
',\r\n// menu_pivot: '
数据透视表
',\r\n// menu_freezenrow: '
冻结首行
',\r\n// menu_freezencolumn: '
冻结首列
',\r\n// };\r\n\r\nconst luckyColor = [\r\n \"#c1232b\",\r\n \"#27727b\",\r\n \"#fcce10\",\r\n \"#e87c25\",\r\n \"#b5c334\",\r\n \"#fe8463\",\r\n \"#9bca63\",\r\n \"#fad860\",\r\n \"#f3a43b\",\r\n \"#60c0dd\",\r\n \"#d7504b\",\r\n \"#c6e579\",\r\n \"#f4e001\",\r\n \"#f0805a\",\r\n \"#26c0c0\",\r\n \"#c12e34\",\r\n \"#e6b600\",\r\n \"#0098d9\",\r\n \"#2b821d\",\r\n \"#005eaa\",\r\n \"#339ca8\",\r\n \"#cda819\",\r\n \"#32a487\",\r\n \"#3fb1e3\",\r\n \"#6be6c1\",\r\n \"#626c91\",\r\n \"#a0a7e6\",\r\n \"#c4ebad\",\r\n \"#96dee8\"\r\n];\r\n\r\nconst keycode = {\r\n\r\n BACKSPACE: 8,\r\n TAB: 9,\r\n ENTER: 13,\r\n SHIFT: 16,\r\n CTRL: 17,\r\n PAUSE: 19,\r\n CAPSLOCK: 20,\r\n ESC: 27,\r\n\r\n SPACE: 33,\r\n PAGEUP: 33,\r\n PAGEDOWN: 34,\r\n END: 35,\r\n HOME: 36,\r\n LEFT: 37,\r\n UP: 38,\r\n RIGHT: 39,\r\n DOWN: 40,\r\n INSERT: 45,\r\n DELETE: 46,\r\n\r\n WIN: 91,\r\n WIN_R: 92,\r\n MENU: 93,\r\n\r\n F1: 112,\r\n F2: 113,\r\n F3: 114,\r\n F4: 115,\r\n F5: 116,\r\n F6: 117,\r\n F7: 118,\r\n F8: 119,\r\n F9: 120,\r\n F10: 121,\r\n F11: 122,\r\n F12: 123,\r\n NUMLOCK: 144,\r\n SCROLLLOCK: 145\r\n};\r\n\r\nconst luckysheetdefaultstyle = {\r\n fillStyle: \"#000000\",\r\n textBaseline: \"middle\",\r\n strokeStyle: \"#dfdfdf\",\r\n rowFillStyle: \"#5e5e5e\",\r\n textAlign: 'center'\r\n}\r\n\r\nconst luckysheetdefaultFont = function(){\r\n return 'normal normal normal '+ Store.defaultFontSize +'pt '+ locale().fontarray[0] +', \"Helvetica Neue\", Helvetica, Arial, \"PingFang SC\", \"Hiragino Sans GB\", \"Heiti SC\", \"WenQuanYi Micro Hei\", sans-serif';\r\n} \r\n\r\nconst luckysheet_CFiconsImg = new Image();\r\nluckysheet_CFiconsImg.src = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZoAAAGACAYAAACUS6SeAAAACXBIWXMAAC4jAAAuIwF4pT92AAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/sl0p8zAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAHBbSURBVHja7J13mFxV+cc/M7OzLbvpjZBKQhISUgAhgAlVkADSRcDyky4iYAAhAmpQQtMIiqigYkV6FRHphgBBKSGBkB5IIb1sdrO72dmZ+f3xniGTzZR755a5s/t+nmefTGbuPec7Z8497ynveU9on5m3YJMuwNnAt4B9gA3A48CPgY0UyPxJUzN/MLMShxwDXAMcAmwGbgD+UlBKhzVn/+yqqwrVFwIuBL7tZnkyYwaK98yaNb/QW6uBk4DLgfHAduDfwI+ApYUmOnHiKC+0AowAfgh8EYgAvwF+AMTd1OlQ40nAtcB+QIMpzx8Cy70oT8U6YZvXn2x+tN8A44ByYE/gMmA18B9g7wB9v58AzwNfADoBA4A/m4c5KPwWuCdDef4X6KVVtF1yGPAx8IDpAFUBPYGvAguBucCRAdJ7CvAecA7QA+gKfB94DKgMiMargaeAQ0159gK+BrwNqLUoIUNzFPAw0C3L5+XmAXoZ6B+A7/ZNM3rJxDTgl2Y0UUwmAxdl+WwI8HOtou2OzwFP5+hERIAxwDPAhADoHQvcbxrvTB3PZ4HaImscDmSbmukO/F6rXWkYmgnAP4wxyUd/U/m6FPF7lQO35bnmMuCvQLSIOs/J8/npQIVW03bDPjaejWrgn8boFJPpRks2jgReKfLo+yygLMfnhwCDtPoF29CMMUam2ka6Y8wDVV2k73Uw0NvCdV9F1kOqiqQzX+WvQqfP2gsDkWlcO79nD/McFWuGoAJZk8nHAcBM8x2LwRAL1+ytVTC4hmawqeiFNHaHInPQkSJ8rxob156ILBp2LYLOkAu/kRJ8egEvFWgw+iPT0cXocJTnGSmkMxJ4zfxbDJ1WjKYSQEPTC3jBYW/qJODX+L8WMhuos3H9JDP876NVQnGZLsbIDHOQxt5mVqGTz9rrgTdtjtpmmhGOouQ1NF2MkRnmQh4XATf7/L02GyO3zcY944FZZhSnKG5QDfwLd9ZZJiBOBOU+f4evAAtsjt5eIVhec0oADU21qdDjXMxnKnCJz99tJuIpt97GPcOA14HRWjUUh5QDTyAL0W5xFPAn/J2OXoV4k75j455aZMr9ZK0GSiZDE0XWVQ7zIK+7kI2efvKO+S6f2LinnzFSB2v1UAokAvwNONaDtM82z5KfbDBG7lUb91Qi+2z+T6uDkm5oQsAfkSknrx6+P5kK6ycLkTWYj2zc0x14EYkqoCh2CCGbcL/sYR6XIDve/WQbsu/rKZvP/B+BKVotOjbpHiW/RNx9vZ5OeByZv32vwDQmG51DsOdJYne/TCdk09xXgUcdfN9DkE2urwGbXCjDLsDvEG+5rcCTSASENVqdA8HtwAU+5HOjGWn8psD7RxmDNRZ7TgZ2p+1CyMbjzkZzoR3izyGOSf8DVrrUFv0S2cvWgqyl3Qgs0SrsnaH5IfAdn/LsgrgTH2rzR031FC/ysXzKzSjsBex5sQGci2wa7ZXWIzzZ5vRDW6oR76NJ5v9VprE4wxie/2qVLirXIaFQ/OIu03l52OZ93wTuxd/NytOQdZv/2bzvGMRzNeWY1Aqch2y2djLqvK9Nx/prSKidc8wzprhI2PxoN/qcby/Tg7CzN+BbPhuZ9JHNWTbvmW4qcvr362xGH/sXqCOCrJ9NylKezwB9tUoXjfPM7+4nEdPg2pmOHoXE1itGRIyLbV7/VdNODGvTOXY6xf8rMs/e1AAPoc5Anhia64uU9zDsxSD6VhHL6ds2e2DX5RjNPYd9t/GQeThOymO8r9cqXTSKVfblyNRuZ4vXX4D/LtLpowarcdGGmPYhksXAPkhh671T8zzPVfi/HaNDGJo9LF77EWAlhvetNvK342s/oojlZGe387UWRnN2A4/ebNHQnqpVumhYfY5WIfu18vFzZO3ACt2QfWBW2KeIZVSB9ZhjV5A7MnQVst5rZ3PoNy0akckUL3xWuzU0b1h8OI5FNkLm4zc2jI2dDZUbi1hOG2xce6iFawYg61TdLVx7iemFWaGzVumi8YbFenQcsMLCtS8jrsxWz3tpKIHnCGCLxeusRK7ugkytWYl1dpIZIVmJUhLFXhgrxYKhud3Cw3GUMTZWuQ5ZuM/HEzbSfLqI5fSkjWuten+Nwto5GVNt5P2KVumike8EwTrEYeNDG2k+jkQZz8cyrHtxPlHEMnoLObfKTYPUC2ubYi/Cusfc+9jb6K1YMDTP5xhO1plh5GKb6SYRL7an8/Ss7Cye/gg5LMpvmhCPGatML9JvuQR/3GqVzLyU47dvBE6jMK/A35B9zS/1rH3X/GvV0DxVpDK6zsa1P8H61KHbsxdnaHV239CALGSex65TRNsQd793Ckw7bob+r2X5MU8E1tqsABOQHdfNPpbRbJvTDffZNExuPRyTsTfFp7jPDchO+LVtjMyZyFSYk9HS3VmesSuw546bRDaT3oi/02hbsrQF2XgT2SIQ91FjI/AldC+N66Rv2PwjcpLeoUjI/FkuVMTUD/d7Y1i24GyD4Xrg66bn3gfrIcwxUxDftZnfJxTmUn2jGdJf6sNvmBp16sMRDP6CuKEfjBzP/KbNDlWu+rsNcQqJIGGSbkKmo+wSM52hn5jnyM5xzIcj0+J2PNe2m05nzKbOvyPrML/24XdrQQKIvqVV2FtDkyrsVz1oCN0Ox7EDawuqIIt/PynAyHyALNyudtAwdMXbaAstZkrmHa3KgSJms/dudSRyHfamn6zMOnxq4/pTTaNvx8hsAk5w0ID/BnGaucnD3yuJzOg8o1XXG9r7oVoRJFyL3T0Os5BgnKtdqLxeOTHETfovazVWfOAi4BGbo5+V5jlyOkqYDvzCw+92HTKbo6ihsU3Kz/58m/c9jbhyb3FBQwvZ16mccpk+HIpP/BCJJmAnztl84PNY23tnhSke1fefYW/vn6KG5jO6IN50dsNU/AGZimpyUUtqnWqei2neSuHBFBXFKiHECcFuiKo3kVBJK13UkkQ2XLo5Q3A/cI3+zGpoCuVeYGIBw/ML8cbLpQ44GncW7H+Hu/P0ipKNb2Mv/BLIOscXsLa52y6tZobgPy6k9SIy9ZzUn1kNTaF80ca1CeByxDXVy0q3AZmSW+UgjaeRSAH6cCh+MNnm9X9CHAYaPdTUiERBn+sgjbdMGi36EwfT0Fhp4BIB+F5Wp75akLDgfp1YuBw4nsLOpXkDeyFJFMUp221ce5sZIbT6oKvOjJoKmSFYgkxlN+rPG1xDk8+luIlgbBq0Emaj3jT6D/msbR7i7tlo857j9eFoN6x04VnzAysRBJLIQv1Un0fahcwQrEK2LOjG5oAbmnxeH48he1yKzfQ8lWkdEjn6pSLpewtxVGix+HAcj/2D15Tg8mCekf/7uOs84kTnm3lmBL4G3FkkfXZmCOrMtUu1+vlPmc3r/4UsRl+Y5Ue/MiDfa7UZNfyT3Q9XW4as4RR7J/1LyE7k+5Aw722JmYf8Apyt6yjBYw4Su+8nGT7bioSxCQIJJAzVv9j9wL4G4HTEu7OYzEPWkv6BRDloS9xcc4mbxnvWrPmB+IEmThxVEhW+EGeAi82PNtf0aFYju4UPCtiQ9H/AOGT9ZRUyrfcY4tsflHAtTyIhzi/NUJ79kHAfi1HaIzchMdBmI7H7NpsRxEFmRBMU1iMenFORM6l2GM2HB8DIpD/rQ0x5vmnKcxMyA7M3sJ/RrJTIiAZkHva3WDsGoNisQTzKLg+wxjpjWH6t1bFDUY1sgEyav4TpfScCqLUJWey/LcDl2YRELnikBH77k5EDEsebkeG/KF50en8MzfxJU/WRd4MZM7QMFKschhy/nD6tW4XExTsL2U1/BR3wfKHUVFCxp6Y8nJK6po3BrgK+gawfTQIW6IimKI9kM4rSjvgcsh+qS5bPI8AYZOPjUbgYTXjixFFWGvAIsmbY3fzb9nWuz3Yga7h3k8VrzmEDPhwYbUYBb2L9VNFUg/4dY8hHmbZvCTKd/jNkbcxrRpL97K+eSJifw9XQKIrihH2AZ3MYmXSqEWeWI/HOA60PEl7mc0APYzScHAdebXrs1yBrjlchO/Cd0h/4K3BE2nv1yHTTneR3q+6OBJ8dl6Hhv96MJCfhvdPN2eSOF3cYMJBguLa7a2hGvVb8eHLtYvruqquCo0Wn8YLIQGTxvJeNe3oYw3SIB41gZyRK+TCPvu9Y4DkkUsA/HKTTAwlKO7jN+7XAz5HF/kvzGJvpGYxMOoMR54xvelwHBlu4ZkB7NDRhff4VxXN6Ie7s/Qvszb9s00BZ4bseGpkUEeTQw04O0rg+TwN9CRIMN9dIYYKFfD7nR8fewjWh9vgAhB1WgM3m73qUFF8CPkRCcSR9+ms1eZ6kxR84uhgj46RR39uMCjq5qOsMn75/byQieqGcbuGac5GTTbMZGysLvT20qgbP0HzJDDVTi4A3aSP3GX9GFhsjPuYZMXn+RYs/UFQjrqtjXEhrAuJEUO6StmE+lsP3HdxrdRR4DvBwlvKxEkm6m1bXYBma/mTe8zHDg+F9KfJQB81b2ZVyJObeIS6meRQSIdmNToyf+3VGOrjXztrUaYgXWUUBhqYC8UxTAmBouiCLk/2z9JAecrHHVapcgr1z2N3ieiRqg1J8IsDfkKCPbnM27kQb93OjipN1h6dsXn8iMs1Ynfae1dNydVTjEWU2H57780wDHImc7X2JawpnVgantKzv6TkTWcD1y+g+CNyi1TkQhJCoGV/2uDOzFvixgzQeBg70qUycbIb7MbKTfqCNe44xHeITkb02dgzNp1qFizuiuQsJVJmPb2H/VL72xuv4d3rf28D56GFoQeF2JBCq19zosEP3K5wdHmYHJxHdNxrDYfdY6FQsti42DI1Th4Awspb2JSRWoRuUIxs5601Z/AUY2l4NzVSblfpOZD7ZbWqR8A2fIHPMXnlxJUwet5k8C+F+vD9y+VO8P9FQsc51wNU+5neXGT0XOso4GtnJPx8JTPk8Mv39G2QH+/eQTZfFrl+LjOH42OZ9hyAef1an7pxMnU0GFiLBO59Gotmf5fB7p6ZgLwJqjCH8OhL9e3IpPRhWps5OQjY82SFqKuwhuBcpuRqYiQSi82P6YyCyw/lYJOJzIQ/brchu8G94NB1xGnqEQFA4r4DnxCkRZMf8RmSqtpDRwkU5Pu9sjE91AMp3ObJz/kUkFI1VDjDPoJeG5qtmpBFuMxL5i2k3nnbQkcg0BVuDxMo7gBKJjZZvRDMBeIDCvNN6Il43XVzSer1PRqYt43G2T+jCAhsBK+m+hRIUirWXrNw0Op1dTrcaibc2IUBlvBIJQ/NRAd/FK0OzN7JhNJylw/2AMZB2yTeLVF2Ejo0nhmYvdvfesMu+Zujnhjvm2UUsJyd5t5iRh5vxqm435aoEhz0sXrcKCf2Sj59j7QTWVAPpZiesCvH2mhTAcl6DTKPN8SDtQgzNVezuTt3WIDyNhOSxyiVkD76ZzomzZs0vD8ohbIUYmi7IoVxu7Is50WKh5WPPIpaT07zrkLUUNw6Gewbv134U+7xh4ZoNyJn1VmJZvWw6OHGL+Te49D1SI6QvBLisNyDrS28HwNAcYOGaLsiU3xAL156ETJmFLP5WnUrh4QhnEf847uxmTnENcra4E1YXsZzcyHsp4o3iZGH1Q1OOcZSgkc+9vM50uj60kebjwGUWrlsGvOfCdyhDXOWPd7ls6jwo783GGL7uYprdC7hnq8XremFt8+73sD4D9DbWPeoCZ2juxRuPsd/hbL73gSKWk1t5v2V6qYW4Im9Czm+vQwkiL5F9zrwRmT79bwHp/ibPCDaJBMh06t6e8nA6tYTKvM6MEP9TREPzQ6xPcbo9qju7VH6otoZmKvB/HuVVaXpo/Qu8fzrezMvmYw7uLro9jf2pr1bEjXUJSpC5wTw/a9sYmdQGXiejpbszvB9HTuL8h0PdISTK8lds3vc84tJbTBrMCOzfLqRVyNTZm/i3Zy69Tn2plNqDdEPzVdxZS8lFP2Nsqgss3MOQmGp+nNewAlmQPQz39xHcanqqVvku3niuKe7zF8Q1/jAzihmKHGDmlMuMwdkCbEPW6j6P83A0IVMXv2nzvv+Y0Y9fvfnO5rvOR6ahlwLvINNHM3FnDbdQ9+b7kdM7/aDFzGyUlMdpah/NocB9+HMWwoGIO+A5BfQC6pENcVdT+lyGnLORb+PVPVl6s0pwiSGHdblJ0oyE3XYE+Tn2Y+S9ifP1Rrsd4ieREFde4mTD5q+RdZhpHupLmtHTC6X2QKQMzSP4GwzzLMTdN/8I6rBm2ilxZI71NbI7XrwCXK7ttuIRl5vRsh3eMZ2jeh91nuaDkXFqaEDCAvVCTvz0gmvN6KnkCJthc78i5D0dCT7YkalD5pcz7e5fisyZt6Ao7lNlGkY7zAO+yK4OKVY2czvtLZ7uU5m40au9zCNjcCvw01KtbGG8jTJrZWTT0VlF5iCkV+LOvhtFycQEoKuN6z9C9q5savO+lViAOxxqHe5TmfzZhTRS01vPuKjLj7iJnhua85EFNj/3ZsRNnv+nzzsgXkM3ID75683rp7VYFA+xEyx2CRJBeUOBowCnbUvYpzL5lUvptJjZCDf2+PwT/73aXKcMCTXxlD53RWc6JRS7SCl5rG4c/QTZV5dt0/LLFkYcTj2kluB9nMMluOuq3Ygcq5JrDRYL5XYm7WD6vEyfN5eYMUPLQCklliFhUXKFmlllPs91FsxU05B+PsvnryOL2E54AjjDw7JIIjvy3R411CHR319DTiC2a/j89Ozz1tDMnzRVHzlF8Rcrh3j5sVfsXNMIDs6i8RjybwqsQ/YMnYl4h40w7y9FTvF8GDnfyQkPIftUDvGgDLYi3ndPelTGaxEvvVexvtdnFeJl127WaHVEoyj+86DpQWdbe3gfd6N952rQPocccfBlJGrHKmRT9XRkvdAKCfOdHvRIZxyZhrrNGLVo2mchcjs1VJM5uvJyxJPrYazHKyuUJcbYvEb+Y1NyeaKWrqEZ9dqtgRCiIyufuOqqYOnpmFOOc4AfAT/J0sP200lmE+LheGVQCidL2Pst5D6kzRMNEyeOcivJecg02jNkjorfYurFFW52MoJyhEDpjGhmVhY3//a7cVQpDjchi89XIgvdjUjssB8Ci7V42iX/RaYpT0M2dY4HtgP/An6A/aOqS2dEU8A9XZAd7d9CjkjdYIbaP0aOhu3YtF+DGEJO9fy2/u6uUI1ETE6avwQyRZTQonHEPsZYH2PK91dIWJigHK3RiETJLoWDC7+JbEAdbUa+T5myXG83IbuG5mTgj+waqmFPI+ZiYDZwgY89sj2Rk0ArkXnaKvOXel1ptKa/rmxzTRVyBvd7wJ3I/pXt+rzuxm/bTF2kfvcTkc1/urnUOocjYZ/Sp1CqkMC2ZyF7zK5AQhAp1jkN2dyY3tu7ARiFxFbc4VZGqSm1Yk9NuTi115Y7TR1M0Q85+fN4YCI215DsGJqjkIWzbDHRypGFupcR7xAvF7MipuE7H/cCgR4E/N00mBfizt6iEOLZc4Xpae1AFgSnYf9skqh5YHoCnwKLfOylTSb7/PgQJDDj17Wds8SBpm51yVG3xyBz+UfhfZTersjR4HYX2TtlaQuWIlGmH0GiTPvFOPP8VmQxQM8iUY/9iNE2wjyrDUgAUjunn1aZ9uJMk0YYcSZ4xDxnfpxHdVgbI5POIKPjTDsJWt1xOwHZvW4l8GZ/86N28bAgrjYjJy+iTfcCHjOF7dTI3IdEqh5rHuIa02i/bvRboQb4mTGAc5C9D/ONsbkO66fxOeGcPJ+fTu5z05Wd0zr/tPhsVJtrx3ioJ2Ke1QtN47hX2t8QMwOQ7S9bWzAUOdtmKd7ufWnLLXnq4FHI4XQ9PNTQ34xCFyDTys+b5/S7Fu/vaTqgtwD7me8TZed04DvAHj6UZb4D1U7B5hHSVgzNGGNk7JwhM8ZU4GqPHg6vPWQipnF32jh/M8dI8l5knSsX5UhI8KsyNE69ERfUe32oeIMs9MJ6qR3JW4bP2yynHuY56u+Rpq/gzd6UVKP5EOJp5TVVFvM50MwoeFGePUzaR7R5vxa4A1krytcxvhnYN8fnQ43B8ZoBFmZXbJVhPkMz2FT0QhqRQ5EjkN3uce9jGlk/pjic9B7yGZEQcoZFrgOTTgUOzpPOuRYqhlNCLtSljkxvMxItpIHrj0xHe2HIvT62OYwcVOg1lTbamX2AWbgfqPN6Mm98TXEpcrZUrufkIAv5HBSQOl1utyJko5fpTTux/ieZxtTNKa4ePhbmjx0aRCsN+C/JfubMEItpDEIJKl2MkRnmII29zaxCJ5e1DfXh++9rsR47YQty0qad0eVMZHrKLawcZXAhEiE6m1GMWUijWyk+BOEcD8cLDh+OFBfh7hHRW30sHyfHGFhdAAwBvyDzdGCTxTRqUYJINbJHwo11lgmIR6SbBxT6FRH4Uh/yOANxkLFKHyQszOEu5W+1Q/41xGkhmsVg5qN7ezE01aZCj3Mxn6mIa5wbzMe/0/2cjMRetHn9DHY/otpqQL1qlKBRjgSDdHMN5CjgT7g3Hb3Ip7I414c8PkEceN61cU9n0xH4kgv52/GyPZPMpxpbMTRd8McByFNDE0XWVQ7zIK+7yO/NYIUY8DufysdJ5NRbsO+K+FNjlFNY3c+jhiZYRJD9HF4shJ9tniU3eMyn8vBrF/M6JBjlf2zcU4V4iH3NYd52t0OcbO6psmlooASnz8Jteu9/RNZVvHr4/mR6ZU6ZhvinB9nQLEWm3pps3ncLO0/Ts7oPoUbb9sAQQhZ9vXTtvQR3vI8eR6aPvGaLj+W/DdlC8A8b95QBfyH7WqkVfoz9vYPHsatH76b2amjSN2z+EtmZ7PV0wuOm1/Geg3TqETfCVMTZHcYo1JmGvRHx5jrZhUrrhOcQn/MnbI46ppvfZpbF62td+F0OMRX4NRsVPt8Q/3dI5ICtSBj2nwBr2rmhuR3ZSOw1NyJ7q37jII2EeUamI8c0p/ah1LEzFE4lEoLECZsd3LsvEnVkLPacIexGPUmtldZQ2JryRuTsHrvehUcD/0aiU/s1ooki3qw9gTfMSNApnZGtFieZ+vOPdOOb+jF+SG43WzfpYgr2UPKfdZGLFjM9kYkfuWBkwJ1QNM+bwn/aprG5EXEtt4KTqbNzkfDrvdKM68kOe7rVpqJNSpueuMT08k/EflSEUuE6dl9n85K7TKfgYYedqcty/I5PFtHQnGdGh34G//0JslH2/QLuXcjO6CiDbdw30bQTj/hgaL6C7Ozvl9bGnWmjrcnWUX2CnbNVVYiH3anGgP43bH7MG31+IHshi3Be7A24HplacwO3Trd7yRS43fSO99jQTEeiF/Rq0zN5Eti/wDQjyDrfpCy/+zNA33ZoZM7D/6O4I8BfcWc6ui01pvE5xoW0Cpk6G10EIwOynODEcWk54slmtxM9AevbKQo1NNcgZwb1S3uvkzFwBzuog/dnqYM9U8972DTMxWAYEqrCTaYi4dfdws1jVF9F5o4bPGoU7HIMO9eCMo06n8O+e3sI2QF9Up5ORrHqnJcU6zuVA4+aDoKbsw7P457rbyGG5iKKd4zJN3G2Z2mFKbuPCpgJsEIhLs4HI+u/2fJ9jsLc8O8i93pkL+AHYazvfv8IcS3Oh52T1I50sXJcnaMgnUwruMlMY2zcds8uZI0m3znuvcwUgJ355pvJHxEBvN+RXgysPkersLb29nNkethqD3e8S9+juxmBu+mWXYih2aeIv2UFzjdBf4qsI8/1QF8hI5qryb1Bv5DOpdVtKyeHkcUgKw/HsViba/2NDWPjVkM+BXENdhsvjguYZYyNm1FYC5k6O9TCNQOQ9TQrPahL2NU1OxedaX9YeY42IJ5GKyxc+zLiymw1QrcbI+XeJt8DXC6bQgzNpiL/nm7kvx6ZUnrXZW3dPHre+yFLGr0tPu9WO/a9w4iXTL6H4yjsue5dh4Txz8cTLhT6Fab3ZwerD2+jR5X4ddPguGVsCjE0Vr2/Rpk/K70bq7THc1byPXR1iCPEhzbSfJzsC/XpLMOZF2dqRPYq7m7UdmJonijib/km7nhipQzWUbi7HaMQQ7PW4nXDkDiPVgyNVf4RRuZib87xcEzG/kFmScSL7ekc12zE+eLpZUhkVDvUYX0+vdHDyjzbjBK3upBWIWs004v0EC/B+hEJpcRLOcq0ETkTpRBvu9+QfS0t9ax9F2fhZAYaI2N3usrq81HI6OARZCG5GHzf5fTqgC8iWweKZWhuxr+QQ+ksBS5Pzdldj3jNpJ+SuA3ZA/JOgRnEzdD/tSyjpBNtWNlsFvUX2AsTU4csgltdpHM6tRdBDgSbgUwnXofENLsI2czZz7zvtAIUskZzH+5551llg+m4tNfTOG8A/q9NvW5E3EdfdjhaujvLM3YF9jYntmUIspPebjTj/2F902ghI5qkMc434e802mbTCXSbejOL8aILaRViaB5Fjhvx+3k/Dlid7tXxR8RN7VDkZL1ZOD8LvhGJI/R7Y1i24M7GvQvMg2fXyBxnHpBzLN7jZI0mjIT4ONmHH7RQ9+YbkUV/P4IepkbHS2jf/AVx705tiHvTYYcqffS+DXG2iCCOJTfh7ATO4abhs3vMxCzzPFsdmRY6ao8BPzAdoj7YC2VzpBkNRm3csx3nRz53ZvcNsFvTOpNuhOMp1L35DvO8f9+H5yDV9i+B3d0HW3A/JEUdsoPfLQ4yFciOkalH9qTMtjkCcDJ19nWfjIwTQ5NqwLribVSIFtM7fYeOQczFaZL0Hv515J5Gs0NPJEK7XSPzimlAttto8JyGoIkjXlxWOcN0RO0YmU3IXjcnhjuMxC87wuP65eSolOvM836Jx8/7yellWYqHVV2PPf/6BmNk3iigYXZiaM7zsUycxDpLGq1Pe6QtbtJ/GSVI/ABZm7HDv81IJjXSt7qfw89YZ99GNiXaOVr8E2R3/lsO8z7NByPjZEST3rl80CNtqfbkxbYWuNSws/em0fRSZhU4AnCyRrOfj2VS5UIP5GwPeuGpSn2/tuuB4xSb1z+NbMRN73wFzdDcaEYydsLofwB8HljgQv6n+/Q9dzi8P46sJb7ggbZrMz3vpWhorM5xNpqRzEwHIwAnazRVPpbJHBfSSM2pznNR1604C/qoeEc/G9c+ikx/txTQs64HWj3+LqmI2XYjWs9CYpOtdknHCJ9+u/tcSKPFdDbecvl5z7ifsRQNjZWGsNH0vv7j0Ag4MTQrfSwTt85lr0MWMd1YsP8d7q0nKO5jdc3jfsRDMlOUAiuGxg+PscsRT067I7RjXR5thXz67e52KZ1UZ9yNzuX9uZ73UjQ0v87zeZOx1C/luMbK5rbN2Ntc15YXfSqPjTiLvNqWDeYBXOUgjaeRxcYkSlCxcujZH5AplmwbnK0cK+3HtJndEzL/gKynNLmsww+Pyg+Aj11Mb7MxNssdpPFPZF0m6ZahsdJwJHwYNv4xxzD9FPLPPf6N3HsPms0D5sQZ4Kd4u+ET0wCcj/uBOpebyldIb/QN7IVOUYrD9DwN1m+QUO+5fkcr0y7/8+G71Nn83hd6VD+9jmaQwJu9MKkQY4Xsb3sL2SeWMy6fXUOTL0ZTE95vxkuaxvUbSCiXTUbXn5AF+OctNtCnGGPyH2Og4ubBuxeJYup0V/Ji0+Bu9qgc3jaVwytvsXnYP9pgnjFQjSi5WOnCs+aUTchRDq9m6KxdieytytexvN70sLOxDH+OILHSwCeQKbYbPBxpP4Q3mz1TMxdnWmzfCh2NfcGm0V5iRpN5n3e7YbjvJ/d+i8dw7hFh1dj81fw56R38xfx5xdPIPoXhyL6FSmR9qFva667m39TrSsQrLv11F/N5Ajnk6gfY21dQKG8ha13PWpgmWWWMTB1KPh4Evpejo/c+7jpl5PrNjjT1c7QZGb9pY4S8EdnXdoVpBEchHl9LTFvwM9wJsZSPBxC35mwRp1tMx/QhH2YYjkcOEjyMXffxhMwznY1OWZ6xpUhkiEdwP5p8W+aa5/1f5PfMTdUdSwMLu4bmX8gi74VZpluu7LBNx8ysznCNuOMVZl3HYc1upvgScirffWRe/I2ZxukCnK3r7MpVVwXr950xw83U5iCnwP4kw2dbzUjbTxaZv0JoQryNbi3irxNHNmlmOlOlHjmW4iWftGzBvmNCoFoyxMPw76aDm+l5fxuZVbL8vBdysNDFSNjrS4CRxqI9ZR6cjZ59fXcbT8UeTyI7wr9qfn//fvf2y03I0b9XImfJNJppkR9iP4itIiP8CWZ09Q1gr7R26n0tHls8i5xDdZYZKY5GplqfMbMptiNbF2JoUmeJJNv0KIo1YvAH7w3dMchRq4cg6zo34O20nl3qEI+/Xwf8IQmZEfe3kWjEG5Bw+z8OoEF8BOvnxLvCxImjaMf4Prpqx+XZgMSodOUUZLuG5mTE4yt9CmVPZPf3xchC2AXaI7PNT4xhSdEJ+DMSWdfdxdTUFFD7Ndy/bTN1kaqfJ5oer6vOKu284VZKnKDUTzuG5ihkITrbonA5sgD2sumVr/JB/56mMU5fVK80hjD9db5F+Bpkb82diNtzg4+/wTfbGJl0piEB9K7A2z0pIeBck88+iEPHayZ/u2eoRJFF4Z5mOmMR/rk6Tyb7/PgQ5IC8r2vzo42jEkxDM8E0wFY2aPVH5vgm4Z0HUgj4pZkecWvT6UHIAthGMyp7yofyL0c8VHJxGRJT6lxkIc6LsrzPGLx0YzEZmc67xOLwucYYpgvYdRFxPXJu0G0+GJx8xz+cbvTt0EdfUfzDSiM9xhgZO6HoxxhjU+2R7suREzy9iGzQE3HNPMyH8j8Ya+dzfxVZZ/Aifto5bYxM247IvcgZKPkM5gvIZrK2niq9kU1y9/pQnoPyfF6FnMehKEqADM1gYzAKeTgPRfzbIy5rDgFXe1wuEWQPgNfYCe9/IhKmvavLGr5lobx/bQx7Nk41RjMX52L/7JNC6oYbnStFUXwyNL1ML7W/g/RPMo2Um8HmhjrUZJUDgT08zmM29qYXJyFuxn1c1GDlnPjUVOXlWT4fYjGNQfrIKYoamhRdjJEZ5kIeFwE3u6i5t4/l82OP099sjLGdHb/jkfDmg13SYNXxIYSstWTalGs1OGGtPnKKooYGZF3laWCci/lMxb2jQ/3cC3GWD3nMRDz61tu4ZxgS5220C/nbjTI9g92nLq3GNqvWR05R1NBEkXUVLxbC70KCTDplCf6ccZHqxfvBO6bMP7FxTz9jpA52mPct2PcO/KnpPKSwem6PGhpF6eCGJoRsxjzJo7wiSITloxymk0A25fmBn1GIFyJrMB/ZuKe7GZEc4yDfpWbkZvdsjlvYedCR1am/Gn3kFKXjkb6P5pfkjszsBuWIm+6RWDt8LBs3mxHApAAbmsmmPIcAFTbui9rMpxMSg+iryJG7hfAccmzCEzZHHdNNHZpl8fpaF+rPIcjG29dcGtl2QQLFnogEtHwSidSwRpsHRXHX0PyQ3O6rbtIFcdM9lMJPpGtEjhz+MuIyu8O8V4ccWrYdWRM6zaHWQsJyh9g9DIrXlJvR4gsUvkn2eTOafdqmsbkR6yd8Opk6OxfZ9Nkr7bc5md3PU7FDNbJHLNVhqTL15gxjeP6rTYSiuGNozsOfw4nS6YUcOXAohceeiiE7+TPxfReMDFhfe0jnWxQnTHgnZArsHgdpvIQcdvZPm0bheI8NzXR2P4+8sxl9HIVE6bVLBFmPnJSlfj4DjAXWajOhKM4II6fkFYNhuBQZtA3fwz136kKmzr5VxN/z2y6k8Soy7edFvLdC1miOyWBk0kfHz2HfDT8E/Irc65G9ivhsKEq7MzRWNyV+BMy3cJ2dEN1Huvx9pgC3u5heIYZmRBF/z5EupTPTGJt6l/UVskYz1cLo+GXsbeK92WKH4FRtIhTFHUPzhoXrViHn02+2cO1vbBgbN48mvQKJzusmhegr5pknbobAn2WMjZuBUQuZOjvEwjUDkHW/7hauvcSC8UrRWZsIRXHH0OQbAWxA5sHthP2/DmsuyE+49D2+A9zhQfkUskbzdBF/zyddTu914DgXjU0hhsaq99co8+d0hJTOK9pEKIo7huZ5sq9p1Jlerd2DzJKm8X86T89/ugvf4RLENTtkU58VCpk6+xHwcRF+yyYkTL/bzDaj2a0upFXIGs30Ij0bS5AjBRRFcUjKvfl682C1dR89Bdm1XghxJBLAc+zu2bMB+BLOPXouBO62aWTqTONlZS2nEEOzATm/ZwbiJuvXUZazKXzaLoIcFzAe8ebbhriJN6S9vhXZpOkkWkIhazT3IVNj03x8LjaYDtYGbSIUxT1DAxIV4H7E5bgrMkfvdL2h0RiU3yP7Erbg3oa48xBXXrtGZjLW5vJTxrYQ1iMnOV6ARFq2c5LpZcB3beb3CYW7VIeR83dO9qG+FerefKPpAF3qg8ZUHVmizYOiuG9oAFpwtgEu24P7ZZfT/Bqym9uOkalH9nu8ifWYa9sd6twBrLB4bcgYYLtG5gNkHWV1gRq/7pORcWJoUga4K95Gr2hB9l+9o02DonhnaEqB/YE/YO8Aq+3GyLxhs8HzK9ZZxIzOzrd53yxkL8gWhyNDv3AS6yxptNbiTTy+uEn/ZW0WFMVdSvG0weuQkCtWaTRGZlYBPWs/DE0VEv/NrpF5Glmk3+Iw//18/O2cHkXdYkajr3mg7TJk6lhRFDU0tgJpNiJrQzPbvN/J4v3bPP4uXdgZY8wOf0CmeJpc0FDl4283x4U0Uut+81zUdSuy/0tRFDU0toxEI+I1l2kvhNWNeNs9/i73AhNt3jMd8baLu6RhpY+/3QyX0qlDgqq6sWD/O7KHuFEUpYMamrkWrmk2Pf4XsnxudW3Ka0PzRRvXJoDLgRuwvg/ICi/69LttxHqUZytsQKYOVzlI42lkH1ZSmwJFCY6hsfJAJjzWfFeez1uQGFX/znGNlbNwNgMfevxdrE59tSD7XO7yQMNP8X4tKo6sQbkdqHM5sv5WyLk0byDrPXFtBhQlWIYmn6tuE95vcnsAme7IRIMxMs/lSeNhcoe/aQb+z4cG2EoInpRb9kMeaVhsGtzNHqX/thl5eBWaZx5ytEGjzXuOx98TVBWlw2LXvfl+cu9jeAzZO+I1FyFuqJcAo02D8Qqyc32BxR72Gch+nHMRl+lOyHrF86aX78eGvelGR68sn68zjajX+zqeRnbfDwd6ItEMqpCTLFOvu5p/U68rEe+99NddzOcJY8x/AHzqQzm+hThUPEt+j8RVxsjU6eOvKME0NP8yo4kLs0xjXOm6wplZI7g8aP4KJQH8xfxZ03FYc/bPnypo0/pqTr47ddBYW2OzDPgiT11q3+AdVlB5NOKOV1ixeAn4ChKypluGz2PIZt0LcLauo3jMxRdfHBgt99xzj/4gRTA0ABcjJxpegpx/sgF4CgkmuVGL1CZPXfo/Tr57HHIq6KlAD9Mz/w5PXaqnO9rjSTOy/aqpp57Xz1JpFLXxVkrF0NQg0zhHIsEX+yLOAT2R6Z8DTI/4FdNDbyjSd2qrcwgypQMyXbI8cDqfurStzkmm0fROZ67RWWlTB/za/BWDPZCp3QPwbo9SEzKdei+FxwwsFZ19kaC/JyKH25UhzjG5PEIbzAg2E0l2j0QeQyKuP4Ksm6oXYhEMzTDgWmTBONselt7mb4LpSW5HFu1vw8Jax/xJU934Lp7rdIlS0VlcZswoRdWnIFOxtT7k9SXgKiRW3VPtVOcYxP2+d5v3y8m9FtetAJ0HA2eZTt2ZqKOIq+TyOqtEdkx/iMxrd7KRbidzz4emcfQyVL7qVILAvsiaYa2PedYi3oj7tkOd5WZ00dvn3/EE3NtYrOQxNEORhdNrsRdXLFNlucakNcwD/apTCQo/ACqKkG+Fybu96TzJPDfF4EJkmk7x0NDsjxzhO97FfMYjQS33dzFN1emuTsUZRxUx7yPboc4Di6gzQqG+m0pG2q7RDEM2O/byIK8+Ju1Dcb7OoDrd1ak4p6edi+NlYbb0q6KuTyVNtVGSYQgloKo+Rpd1zXT7tIlIq+UgG7280llR1srofqsZ0WctvWrqiYQTxBNhNjTUsnBdXz78dE92tJZ5odPW1F6nUIgxkQj7lpWxRzhMp1CIeDJJXTLJikSCD1pbmR+P2wlb0kWrtDeGpgp41KNGMb2iPYYsvBUaeVh1uqtT8ZGWqggrxnRl3dBaEpHdz+3bQhWfjuhMOJ6kz9J6Bs7bSnmT/1FyOlc1ccK+7/P5oUuIRjLnf8TwBcTiEV5fOox/fjCObU1VvuvsFApxXHk5R0ajRNt+GArRExgaiXBkNMrmZJJnW1qYFYupW5nPpE+dTQPG+ZDnWJyd/6463dWp+MSGwZ14++T+rBneOaORSScRCbFmeGfePrk/GwZ38lXngYOWc9NJj3PE8IVZjUyKaCTOEcMXctNJj3PgoOW+6hwdiXBjdTXHZjIyGegeCvG1igqmVFXRORTSClkEQzMUmOJjvlMobDFbdbqrU/GJT8Z1Y8HE3sTL7IUXjJeFWTCxN5+M6+aLzi+NncP5E2dSUdZq676KslbOnziTk8bO8ccYlpXxnaoqagswGCMiEa6tqqKbGhvfDc1UsNQpcIuoydMuqtNdnYoPrN6nCyvGdHWUxooxXVm9j7fLBl8YOZ8Tx7xPoc1vCDhhzPt8YeR8N+RkXfjZOxLhm5WVjs446RkOc1lVVS4XUJ1dc9nQ1CKbB/3mLOwt+KlOd3UqPrC9WznL93NnNLJ8v25s71buic7+3TZz6n7uxG49db93GNDNcTDwjPOFFaEQ51VWFhQ7qy17hsOcWpHV03ub1l53Dc3x2Ns86BadTN5WUZ3u6lR8YNkB3UmG3ZmiSYZDLDuguyc6v7z/25SF3TlKqiyc4Iz93/ZE59HRKN1dnPI6IhqldzisFdUHQ3N0EfM/2qNrVadSdBq6l7O1r7ueWFv7VtHQ3d1RzYBumxnZd42raY7su8aNUc1ujdWR0Wjg01Qyl/PYIuY/1qNrVadSdDYMqimJdA8c7I23mNvpDotEPPEW26+sTCurD4ZmaBHzH+rRtapTKTp1fSpLIt29e6/zRKfb6Q6NRDzR2S0Uood6oHluaDoXMf/OHl2rOpWi01xbVhLp9q71Zt3b7XR7e2gMdJ3Ge0OjKIoHxMq96YHHKtxNt1N5iyc6O1U4OtV9t8WtMg8NTYa0m7UGu2toiunGt82ja1WnUnQicW+2YkRa3U23Je6NQWxpdTTy2s3jwctAPK3J3cp0h9Zgdw3N0iLmv9Sja1WnUnQqtreWRLqbt3vjje92uhsTCc9+q01J3Z/ptaGZW8T853p0repUik7N5h0lke6KzT080el2usvj3oxp6pNJNnhoxBQxNC8VMf+XPLpWdSpFp8dKb04D7rHK3XTnrBroic73Vw1wNb2F8TjbPRh5zGlt1XgzPhiaZ5Ez6f2m0eRtFdXprk7Fa0OzqtH1EP/lTXHXDdjcVQPY2lTtappbm6p532UD1grMisVcTTMJvOpymkpmQ1OPnCHuNw+YvC2PcFWnqzoVjwklkgx6f4uraQ56fwuhhLv979ZEmGfmunuixTNzx9GacN+p9d+xGPUujmr+29rKKp0288XQANwK+GnWY8BtBdynOt3VqXhM3yX1dPvUnTPpun3aRN+l3vQlZi0Zzodr+rmS1odr+jFr6d5Ok8kYIHZ7Mslfd+xwZaprUzLJQzuyrnepB6cHhmYJcIeP+d4JLC7gPtXprk7FB0a+tp5OW5ztVem0pYWRr633LHh9Evjda4ezaquzSNOrtnbjd68dTjLpeM9L1uHQ+62tPObQ2NQnk/yqqSnXmo8u23hgaEBOafTDa2kuzk+uVJ3u6VQ8piyWYOwLa+i6rrA9gF3XNTP2hTWUxbyd4mmKlfPzF77IwnV9C7p/4bq+/PyFL9IUK/e8TF+IxfhTczOFmO9PEwlub2riU50yK4qhaQJOBzZ4mN8Gk4eT1UzV6a5OxQ9j05Jg3xfXsNc7mylrSVi+Z693NrPvi2ss3+OU7S0V3PnSsTzyzoE0tlgzGI0t5TzyzoHc+dKxbG+p8K1MZ7e2cmNjI/+z6DXWnEzyj5YWbm5sZL0aGX/rf5v/LwGOQ7yX+ric1zrkvJQlLqSlOt3VqTinGcgZ7TKUhD0/qqPvknrW7VXDpv7V1PesIB7d2d+LxBLUbtxBj1WN9FnWQMTaKKbZTZ2JZIgXF4xi1tK9OXjIUsYPWMGQHhupjO5cdmyORVm+qSdzVg5k9vKhNMeibuu0tEayMZHg983NPB0Os19ZGaMjEXqGQnQxscu2JhKsTCT4MB7n7dZWmqw7EmzXKu2doQF4F5gIPIZ7Yefnmp63m42i6lQjEyTmAAdbuTASS9Bv4Tb6LZS2NFYZIV4WItKaJNocLzRv13U2x6K8umgkry4aCUBtZTMVZTF2tEapb670Wucb2DjIb30iwb9bWvi3O79lE7BQq7R7hHP0xCcAt+PMeypm0pjgUaOoOpWgcG+hN0ab41Q2tBZqZOzmXbDO+uZKNjbUFmpk7OZ9D7C5SL/lfeh0tC+GJjXMvRYYDfzeZsE3AX8w916Lt5FQVWdbrrpKa7b//Am4vwj53m/ybm86NwKnAVt91vkOMFWrs7tYCa+6GLgQmAKcCBwJjAeGAF3NNVuB5WZo/ArwDNDghsBRoWlWL10MXDg/Oc2WzlGhaZZ1znenzItanopnJIFvAP8Fvmt+Ty9ZjrjQ3409V9xg69y1k/QfYIx5Vo5G9tZUA7k8DroChfhWrzYjmVutdAJnzZofmIo3ceKodmFo2lbS9L9ElveLhjEcD1Kc3fl2SNc5wlTwY035zQKuBpZp+11SJIBfmr8eQJe2F8Sj4fDy/bqNbexafmhrNDwyGQ7tmQzJdaEkdaFEcnVZLLGgemvszSHvbX4/EsvoHlUHbPJSZ2U0Fj51/Dtj9+y69dDKaGxkWTixZziU7AKQSIbqWhPh1c2x6II1dV3ffOy9A95vjkW90AmwCsg6RL+npiYMHGgM0ThgEJDaDLQF+AR4H3j5rqam9z6IxzPF2on50JGzrNN0AtqVW5wVQzPMTNecDWSL+93b/E0ALkY8Nh5AdqsXey3hOGTaqRm4FHguYL/B54Dn0yodwKnAJOAY7C2gKsFhU3oj+9rXhnQz9e9CIFcQsPHACXW9K1kzvHYF8Dvg7kl/W77FD533fPXPtnTu3Xsdh+298DOdF9//f1v8KNx7amqs6pwAnAlwWVXVTp0NDVt8qge2dQKf6TRGqOQJ7TPzlmyfVSIbAaeQ4RAii7Qgu9Z/RI51hfmTsk+JjnrtViffr4cZFaSOON5mpgoKWmTMpbPAdZHPAS+wc8qsLRsLNjYzZmhT78cIOn/9DAHfBm7K8TvnYyvwA+DXuXq6OevnzMrA6OSwZifPkX86czxDFqbOfNNZClNn2ZwBhgJvmpGMk22+5cA1Jq1hRfh+J6UZGczrEwM0knkhTyXsaa4Zr016SVIDPAH8ykFjg7n3LuBxk6bqVJ0lRSZDsz/wusuN23hk3WF/H79b1Bi5tlxOYYuFfhsZNTalzWDTwTrZxTRPNmkOVp2qs5QNzTBkDaOPB3n1MWn7NbK5FBiZ4f0DgHNKxMiosSlNepnfa18P0t7XpN1LdarOUjQ0VcCjHn+RXsgO+SqPv1dPZF0oG9PJ7SIZJCOjxqa0iJg67mWHahgynVKmOlVnqRmaaYjbndeMxftowz/O05gPAr5TQkZGjU3pcC3iMeg1E8k8Naw6VWdgDc1QxLvML6Z4aPn3RVwJ83E90L2EjIwam+DT39Qrv7je5Kk6VWdJGJqpyOK5X0TxLszDnRaHlt2AG0rMyKixCTZXIzvX/aLa5Kk6VWfgDU0tshnTb84iy3GtDjgF2XlrlW/jrSeHF0ZGjU0wqQTOLUK+52JvzVN1dkydRTc0x5N9x7+XdMJGGHALVCCRje3ec3MJGhk1NsFjMrvu2fKLziZv1ak6A21oji5i/m7mfRmwd4EjqwNL0MiosQkWXyiR50h1dkydRTc0Y4uYv1t590FCNRRCqICRUC729tHIpBub54G9tL0vGsU09ONUp+oMuqEZWsT83cr7JofD1yNwLzTNz3w2Mil6IRGgleKwdxHzHq46VWfQDU3nIubvRt7jgfNcSOc23NkIVcyh9LHa3pd0XfYjb9XZMXUW3dCUOne69D1GuWSwikkcpSM+S2HVqTqD/nBsK2L+TvP+MnC4i3puxLkH3vNFLM8Xtb0v2brsV96qs2PqLLqhWVrE/J3kXYlMd7lJX5xvhLoa2FCEstxACYamaEcsL2Ley1Sn6gy6oZlbxPyd5H0l3px3frUxOE6M57E4P8LWrpE5EjkOVim9uuxn3qqzY+osuqF5qYj5F5r3HsD3PdJUg0yhOWEO4hTgh7FJGZkPta0vKi8XMe9XVKfqDLqheRbYXoS8G03ehXAL3p44dx6wTwkYGzUyweEfQFMR8m0GnlGdqjPohqYeeLAIeT9g8rbL54BveKytDHf2pHhpbNTIBIttwMNFyPchoE51qs6gGxpMoxrzMd8YhS3kh4Bf4M9RzCfhjkebF8ZGjUwwuQVo9TG/1gI7RKqzY+osuqFZAtzhY753AosLuO8s4FAfdf7UJaPmprFRIxNcFgJ3+ZjfXcAC1ak6S8XQgJx66YcXw1wKP2Fzms/lcyBwpktpuWFs1MgEnxuA+T7kMx9n5ympzo6ps+iGpgk4HW/3gGwweTQWcO9eFCe2z624F6zSibFRI1MaNAIn+/AcnVzgc6Q6O7bOohsakCm044B1HuS1zqS9pMD77y1SGQ0G7nMxvUKMzXo1MiXFEuSsEC8anQ0m7SWqU3WWqqEBeBeYiLvTaHNNmu86SGNCEcvpEJfTs2Ns1gNHqZEpOd4BPg984GKaH5g031GdqrPUDU3KMk9Azmlx4o0WM2lMcMES/7eI5TTbgzStGBs1MqXNYlP3Z+DMK6kV+LlJa7HqVJ2lRq6w+M3AtcDvkRha5wDVFtNtAv6OuDC7VUAXAn82lj3kU/kkgdfx7kzwlLF5EejR5rN1yAl6rhqZiy++ODCV75577ukIxqYRCWt0DzAVOBvrZ703IfvNbvWhoVGdHVNn0Q1NunW+EJiCHA52JHIGzBB2HvC1FQkuNwcJi/AM0OCy1mXApHbYEM0BDjIjv6ONcXsOuA74WAcF7Wp0cz7wXeAEM1Idl+U5eh8JbfIs/kfoVZ0dU2fRDU3bHn76XyLL+0Vj/pMbaswPmm4Qu5iP69oYxH+OOqVXQzF0zjr1/Ew6Uz2eo5FoDZ/pnPjEHxqKVKS2ytODDkZ7IxWJ40HVqTo7CqF9Zt6S75phyBTa2Vg/q2W7GfrdhoW1mfmTpmb/8KqrrH4Xz3UyY4ZjnbNOPd+RzolP/MHaWlcWrTamzjwvzw4ydaYoHZ5cI5pKZIPkFKDcZrqdgAuQmGR3Aj9C1ny8IBA6Z516vi86Z516fl6dEyeOKvnyVBSl/ZDN62wo8Kbp0ZY7SL8ccSR40/SQ3UZ1dkydiqKUuKHZH/G0Gu9iPuOBWSZtt1CdHVOnoiglbmiGIR5PfTzIq49J240erursmDoVRSlxQ1MFPAr08jC/XsBjWPcnz4Tq7Jg6FUVpB4ZmGuLf7TVjcRaFWXV2TJ2KopS4oRmKeBn5xRQKm0pRnR1Tp6Io7cDQTAWiPuYbNXnaRXV2TJ2KopS4oalFNuX5zVkmb6uozo6pU1GUdmBojsf6zm836WTytorq7Jg6FUVpB4bm6CLmf7RH16rO9qNTUZR2YGjGFjH/sR5dqzrbj05FUdqBoRlaxPyHenSt6mw/OhVFaQeGpnMR8+/s0bWqs/3oVBSlHRgaRVEURfHU0BTzJLdtHl2rOtuPTkVR2oGhWVrE/Jd6dK3qbD86FUVpB4ZmbhHzn+vRtaqz/ehUFKUdGJqXipj/Sx5dqzrbj05FUdqBoXkWOevdbxpN3lZRnR1Tp6Io7cDQ1AMPFiHvB0zeVlGdHVOnoijtwNAA3ArEfMw3BtxWwH2qs2PqVBSlHRiaJcAdPuZ7J7C4gPtUZ8fUqShKOzA0IKcf+uENNBfnJ0Kqzo6nU1GUdmBomoDTgQ0e5rfB5NHoIA3V2TF1KorSDgwNyFTKccA6D/JaZ9Je4kJaqrNj6lQUpR0YGoB3gYm4O50y16T5rotpqs6OqVNRlHZgaFI93AnA7TjzSoqZNCZ41KNVnR1Tp6IoJURon5m35Ltmb+Aa4Byg2mK6TcDfEVdWS15G8ydNzfzBzEprOT51qTOdJ99tzRvqsObM7191laXbZ516viOdE5/4gzWdM2ZkfPviiy+2Wjc8/93vuecefQKVgp4j38jyHCn2KLNwzWLgQmAKcCJwJDAeGAJ0NddsBZYDc4BXgGeABl+/iRiKC3nqUns6T77bV53GUFw469Tzbemc+MQfGnyuG6XxuyveYLWDZ7UjpqihaVecfHdJyJz4xB9KpUQbkAgCD+rj0mEZCnwPmAz0BdYD/7YzY1EghwJTgdHARuBfyF6srS6lvwdwHXAS0AP4ELgBeEF/cv8NzTDgWnJPofQyfwcBFyFTKPcj8/R+bdBTnRbQ6SrFJieYTkZN2nv9gfNNHf4G8KgH+U5Cgq9Gzf/3Ms/DhcBpwFsO0z8GeDhtdI5J/1/A4cDr+tP7Y2gqgRuB7wLl5r1VSEDE2cBCYLN5vzswAjgYON5UxAtMJbwT+BHg1Zi6ves8AdjTR52KDUa9dmug9GRd6yyM4aYxztYhqjIdoI/MaMBNbkwzMun0A140z+9rBaZ9LPCk0d+WiOkInqS123tDMwx4DBhr/j8LuNkMlxNZ7nkD+CPiyfZFMySdiCwoH4ds2HPbAymfzu7AZaaHAvAf4K4A6gxKeSpKOt8nvyNIOXC9Gd24ybgcn9WYkcfxwEyb6X4BeCKLkUmxj/707pLJvXl/0xCOReZCv2aGsf/K0SimkzDXHmbu3WrSmmXSdot8Oochi9TTkIXsI83rOeazoOgMSnkqweeL5ndvMqPfv5hRuVcca6Pxdpu6PJ93Ms/FUTbSPBJ4yoLx3KRVzVtDMwx4DugDLAIOMEPjQkiaew8w00J9TNrDXBoh5NP5B2BAhnsHmM+CorOQ8lzksk4l+HwbmWb9PDIN2w34OvBfZGrVC/aweF0vD/J+0cI11cA/LBq6wxGvSCuu+s9rdfPO0FQhi3q9zJTMJGCZC3ksM73xJSbtx/IMW/NhRedgk2c2DkPcdIuhM4TsUdnHvM5HCBiFeN6ETRqTXNSpBJ9LgV9lmYHYA++OXggV8Tv/FGixaGyeMqO9XM/7sxaNzFZkel3xyNBMQ+ZF65A1gPUu5rPeVIStyLTPNAdpWdFppZc/tAg6RyELp4uA+UholiE50hgCvI0stH5g/kaZtCabtJ3qVILNd0zDl6vRP6Edfu/FwHlmJG/F2DxpnrO2TLJhZFqBr+JtgNkObWiGIhvzUhV7qYt5VCOLd8uQhXlMXoVM+VjVWWEhrYocIzAvdIaQRcgRadeNRxYzh2ZJYya7rsPsY0ZJITOi+Y5DnUqwuRz4pYWRRXU7/f73I1OGVoxNpTE2x6e9N9EYmU4W7o8jDg16zLiHhmYq4ko4i8LXENrSHXgE2Gb+/o3sHp9l8irED/P7HujMVsHd1jkMcRdtS39TLkPbGJlXybzQu0+aUXGqUwkuVyCu7Famr95qx+XwW+Bii8amwnTmvoSsZT3Lrvt/8hmZR7TaeWdoaoGzzf9vtviDWjEyLwBnIH7pIcSD5QkgFVztbJO3VbzQmY2kyQPgLJd0xnPcMyDN2Aw1r/vneTDa6rRbnkpw+S5y8qkVIxNH9py0Z36H7COz4qVZbkb9z1p8HuKIN+fDWu28NTTHm6HlajPqcMvIZHK9PRBYaf6qkRhaVjnB3OOWznz82+js1GY4XqjOZYhrdT5j8wqZveVSvMeuzg//LrA8Fe/oCQwke3T0XEyxYWSSprf/Ugco0/uQNZu4RWPT2aKR+QYaXskXQ3O0ef2MxR5DoUYmvRKk5kGPtJH2US7qtEIiTefRLuk8A4kGkMvY5DIyq4Azc+g8Uqt0UdkfeBNZTP4EWMPOdTQrXAn83Eb9vIBdXfXbO38GzrVobKwYmW8i0cYVHwxNarf6bB+MzErkMKw3zf/H2UjfLZ12eLNN3k51LgWOyGNschmZI8gcDaCQ8lTcZTQSEuXgtPd6Ix5j+bzGAK4GrMakTxmZ+zpgOf/VjEKcGJu4GR39Tautf4YmtQi9oM1nZWSONVSokakHvowcirXIvLeXDa3ZdBaKlTWeRW3ydkNnIcYmZWSW5tG5l1bponET2b2/voPsg8lmbL6H7Bux2khegIQn8ppkQMv674gbciHGJlV+f9Eq66+hSc1lpkI+9EHcBOuQEPF/IfeimhUjsw3Z95Hyjtli/u1sQ2tbnblYa+EaK/uEvNJpx9iszGNkCtWpuEu+UCjfBu7OYGyuQaJyW20kz/fJyIBM/VmhGPtOHkIcYOycBJtAoj//Saur/4amLY8CJ5veWTkS5uJ5oIsDI3M8/obdnpun8m8E3g9A+Sddvk4JNpcAv04zNlOxvqs/Nd3zZx/1Wg3F8mKRynMJsN3m85bQalgcQ7PNvO6C7DqfmOG6g5G4Wl1cMjLd0j63SrrOfMTIva/kWos9Ia90plyYB1hIbwCyp2Yvl3Uq7vKyxeu+hewNuY6drv5WjMy5+D/dcyv5j6NoYaeLvZ+MN+1PVxv3RBDniXO1uvpvaFJTMiPIvYM23dg4Hcnsbf61E0stXacV7jOjsfTpqVXmPauLqHu3ydsNnanNmANspJkyNkPz6FymVbpoXA80Wrz2ImC6DSPzf8giuN8sRDYyZhs1NCFrJR/4rGucaX96FHBvythcoFXWX0Mz17w+BJlOWm3B2DidLjvU/DvXhtZ0nVb5GzDINPojzGs7niZu6xxG9h3/VozNK1mMTSE6FXeZj+yhanQxzdQ+j/uL+L2eMKOHe5H1wphpI+4z7z/qs56xpv3p6SCNkPk+F2m19c/QpDZ7ncjOoHKNeYyNEyOT2iRqZ7oB08imdFrdCNcJ8fi5xfx9B2txj9rqfMklnY/kMTIryb/P5mGXylNxn1fNb+GGsYmb0XcQ9nksQTaGDkTWbVNHOS/yWce+yHqQG8cShJApzG9rtfXH0DxrhsZ7IpGL/2MayUIeFisL/8eaBrMR2dRolWfMPSmd+egPvAP8Ajlj/DTz+h2LI4p0nc+6oHMv0wPMZWRSB7TlMjb7s+t6TaHlqXjDfxAPy+0O0oibDt8DAflOIeTMl5+ZGYGfI5GS/TxGYLTpSFkxMklgh8Xv9SvsbapVCjQ09ewMwXBdWq/c7jSAVe+y682/D5i8rVKf9uBdZ+H635N5nWSE+QyfdUZy3LPKGJilpveYz9hEXNCpeMdMY2waCjQyZyPuu0FgD2M8XwCuMgZwCnK65evYW2sslFE2jcwUJLCmlfYrhETIvkKrrbeGBsS7JIZ4nH0tbRrAqrGxamS+avKIUdhhTZl0ZhvN5Br1fDHPA+KFziXI4momI3MEuzocLCH7PpuF7IwO4FSn4h2vmWfCjrFpNUYmKFGEOyGx9CZl+fwQYwC83L+1j8mjt8XrrzQzFy/YNDZ3mnsVDw3NEiSQH0i4jCE2jI1VIzPEDFMxP+riAvRm05kpr3wM8llnEpm++yjtuneR0/8yebUtRY6fndPGyJxm0trLBZ2K98ZmssWRZixgRgYkivSYPNcMQyIbeMEAY2T62DAyd6b9/2XTflmdxpyB7HVSPDI0IKc0zkX80p9P60HkMjapHf/5jExv0zPqavKY5kBzNp3prLSQzuoi6JyPzDUPN9MBnwOW50hjGbImsy8y5TfKpOGmTsVbZplnZJsFI/NowLSfbfG6r3iQdwiZ0u9r8fqr0zp36byKvWnMu9CYgZ4amibgdGRH/TAkKOS+aT/W8ey62z517PEbefLYFwn6uLe5/3SceeXk0pniY9ObzPXwLy+SzqQZfXyEtR3/SeQo50XIruYxJq1hLulUvOd18/xkCku0wzTojwVQt9VTW4d4kPcX2Om2n49ryB2Q1M7IMoIcXKh4ZGhSUz7HAetM5XkDWQcAWRAchoSnOdZ8ni+S8tdMGnuZNI8jc/Rhu+TSmeK8LCObley+M7iYOu3wNdNoDXFZp+KPsZmA7EupM9M5LyDrH48FVPMmi9dt8SDvYy1eNxVrAUlnmefFSqzEL2h19dbQgKwbTDRTMrWIO2O6F83T5gFpzJHmZHPPX00ac02a77qoPZfOsGmA90OmlV41f9PMe0sCpNPKb+SHTsV7UmtsXZEjho8F/hdgvcWMdWZlQ+Z12HOCecOisemiVdVdynL0xCcgR8ROMb2uScAKJDLAG2b6J9Xj6Y6sOxxiGsWB5v0YMm/6I/LHTCp0xJBP5wvsdN/ujuwRCqLOTOV5qNE5wCedipLOrchR5pU5rvEq1tlHeT6/Aeux4tKZDRxjjGjXLNdohA2XCe0zM+9vtTcyB3oO2c/baEsTsqP5Nix6Q82flCUG5sxKq9/FF50clqV9v+qqYOmcMUNrt1I4O5+7U81IulOWevkN0p0YDnPY/9n5HPVAYqi1dQZIkH9NxgrjgKfY3fs0DpxEapO2PkeejmjSWYyc4TDFjAaORHa4D0nrEWxFFtfnIJs9n6GwzWpOUJ2K4j6pWGffQ6ad+iKOQM+bjo9XYWg2Ia7/M8wz0oJMH9+GO6fsvo8451yBeNX2Mc/mT7EXckqxYWgms/Ps8fORXb9nmh+5GtkA9QQyBfVgEfWqTkXxn1SsM79ZbEYXXtGARNGerj+xt6Smzj5FQk2AnKrXD9jMznNOUryKrDO86rYQi1NnRddpceqs+Dp1yK+UItanoP1BnyNXDU3b/Rwhcu/xmGkaSMfRgrMamMzGpmg6Lc0973xIiqdTHwxFUQJGuMD7DkPmMV9DPDiCiupUFEUpUUOTYiKyKPg6slAYVFSnoihKiRqaFIciC96z2XkIVxBRnYqiKCVqaFJMAP4J/Bdx3Q0F9HurTkVRlBI1NCkOBP6BhNc4KcANpOpUFEUpUUOT4gBk9+07wCkBbiBVp6IoSokamhT7IRsU30PC2tcEtDxUp6IoSokamhTjkLhI64BLA1wuqlNRFMUHQxP3MN9qJAKxG6hOd3UqiqL4Zmi8DOIYY9ezvZ2gOt3VqSiK4iplPuc3F7gdOSNmfYDLRXUqiqKUmKF5Azmk6J/kjvlVbFSnoihKiRma55BT+v4T8HJQnYqiKCVkaBLA48jxru8F+LurTkVRlBIzNC3A3/D21D3VqSiK0gENzXbg98jpkSsD/F1Vp6IoSokZmi3A3cixxBsD/B1Vp6IoSokZmrXAz4HfAvUB/m6qU1EUJeCGZivQJe3/y4CfAn8CmgP0HVSnoihKgMkVGeAyZI2gHnGpHWF63UFrFFWnoihKiY5o/mH+go7qVBRFKdERjaIoiqKooVEURVHU0CiKoihqaBRFURRFDY2iKIqihkZRFEVRdiWU/E8Fo0LTPgX2MO+tnZ+ctofvSg7Lsp1kZmX6/3bRmfY6WDqfunRXnSffHRydiqIoRRrRXGAa7tXA+QHWqzoVRVFKcUTjwEg9D4SAY5BzU7we0ahOHdEEkilXrPUzu0OQI7yHAzOBKXf8ou+qYuls2B5mwIAYx03eSjwO8Xgo9VE34FFgLHLc+LkTJ47a4YXObdsijB7dxJFHb6OxMUzS3rmzruls2RGiulOCE760lepOCVp2hNws6oJ1Fhsn0ZvPAI42r78MPBTQ76g6lfZEGXAHMMH8/xRgA/DtYgmKhGFHc4jWVohEIB7/7KOngEnm9dmmE3V2AMtUdXqME2eAi7O8DhqqU2lP7JVmZFKGp6iNTUV5gk2byti4sYyqqs8G4kPTGsUUpwWwPFVngA1NH+DwtP8fZt4LGqpTaW/0zvBe16I2ImXQ3BxmyeJKQjtblJ4ZLo0HsDxVZ4ANzalABJgPLDCvTw3g91OdSqnRBTgPuBQYk+HzUIC0HgGcQhKqq+OsXFHBpo0RKisTIEeRt6XVSzGhUB6dmfFdZ97yDL5O3wzNmebfR4CHzesvB/D7qU6llKgBbgamAz8BbkMW/NNJBkTrr4FXgCeAuRUVyZ5btkRYtqySikr/JaYW/8Ph3DqzjAwCV54B1umboRmITO2AeEA8Yl4fDgwI0HdTnUqpMQlZ1O+LeBhNBs4NoM7jgEvS/j8GmBEOw7o1UVpjoVyjC08oiyTZVh8mFttlZJNRZ6mUZ0c3NNciUztzgA/N33vmvakB+m5tdX5QAjo/CLBOxXsOyfDeoQHUeUSG9yaEw5BIiNeZ34amsirBmk/LWbMmSk1NPDXCyaizVMqzIxuak4Bvmdc/Ar5o/m40733LXFNsMumkBHQSUJ2Ku0SyvF9u49piEsvw3g6QqatQEVaRysqguSnM4oVVhMPJlIasOkulPDuiobkQmdYJA38GnjY97qmIf/efzGePmGuLRTadlIBOAqhTcdfA7Ad8BTgggxHJtLhRrDWZPoj77OAMn8UtvuebzmSSwTU1cZYvq2Dt2ijV1Ymi6QyF5C9ZmuVZFENTARwPvAzca3pczyD7PA5B1hEON68vNp+Vm2tfNvdW+PA9rOhMEVSdbSmmTsUbJpvf9PfIsd4nBlTnocBi4DHz7wmloLO8InnCtvoIixdWEo0W32ciVHrl6d2I01T+84D+QNS838181jdtOB8DbjXTOnF2XT+4FnHLO8VMAU0FjjR/LUjcr1ZgS1paq4A/As/aeEid6sToCaJOfNapeDNiCZtRSCbX0+lAP/O6CvEqeyZgvdcw8CBQm9ZGPAp0B5qCrDOZ5NFoWbL7+g3RpuYdIVJrRr5WgDLYvj3M9u0hunZN0LIjUirl6bmheRhxq8zGZuBxxAtigXlvFPCltGtOMu/NB34I/B24ygwVuyOeVZk4Lu0HyEchOke30Zk+LA2Szmx4qVNxl1rgeuBgYDnwY/Nvih5IjKp0RiBurOt81noVEu5oBXA5u+7R6Mfu3o6VwEjESSXQOiPh5MhkkvcS8RChUBKfth19pjMSSV5eXx9p+eTjCgYMaAlaeRbV0PwWuNr8f7lp2NaZXtla4CPT4NUi88rDgYva/IIh4G4zxbPI/F2ILGbvY3ryIWSe8sfAEHPfvTa02tH5OaPzwjw1bUERddrBC52Ku0xBNlnWABOR3fqnszM4aqcs91X6rPNaM5JOsTc7Y+xBZoeE1Ggt8DqTEPHZIWE3nRXlyaM/Xl7JmLFNRKPJ8lgsFITyLLqhuQbxcLjONFiXmQdklRkRPG96XnvmSesIdnXTWw0sND2RF41Vv8nkkUQ2pv3AhlYrOkemTU3YIc5O12IvdTrFTZ2Ku1ycNpKNINOeg9JGNdmaPr8XE65r8/+jzEhrblody1b3VKcFndHy5NimpvDchoYwvXu3xrMYmnhHejhS88k3INGD64GDgHeRRfQPjZHYs4C09wReMmkcArxj0q43ed1g8yGzorOfw/LwWqdbuKFTcZd+ed4Lym9TleG9/gEsz5LVmUzSPxIRF+ukPpGfGZoUjyObhBYAvUzDvR9wCzCtgLSnmV7255CzE3qZEc4Ek1ehuK0zhV86neK2TsWf5ysoZNqf0aI63dcZCukDkO1B+Mj0lucA1ciZKFWIZ9R0G+nebO6pBh5A5qffRxZKP3JBdyad1QXoTO+V/N3onOODTie9Jy90Kt6QLBFNqrP96wxcj2srspN+PbIAd5l5/wbgLgtp/grxvsHcO8ykdaxJ2y3a6vyOTZ3pXG7SWG/S9ENnIXipU1EUxdeh/Xp2hkH5Ttp1cyyk+V5a2pea1zeaNN3GiU4CoJOA6VQURfHN0AD8BdlQNAA40Ly3j4U0U9ccaO5tMml5RaE6CYBOAqhTURTFN0PTAMw2rw8y/46ykOaoNvfMNml5RaE6CYBOAqhTURTFN0MD8LH5d2CGBnwJslP9NPO6raEZ2CYNL7GiMxupe5YXQacd/NSpKIrim6HZbv6NIJ5Og4CNyCL/aOQ0uCfM68vMZ4PMtZG0nrzXWNGZjUibNPzSaRc/dSqKovhmaIaaf9eYxvs2xOvpV+zq095i3tsbuN30vteYz/by4XtY1ZmJlM5hPuu0i586FUVRXKMsx2flyNGyAP9FAmZ+HwmzcQayZtDHfL7OXPMcO6Ml9zb/TkSiGMc8+g6F6mxIuweThp86U9QgwTCDolNRFMU3Q/N50wjWAW8gmwW/j+zl6JLlnjrgl8gu/TfM/7sYY/OKR99BdSqKopSooUkdzvM8srj+ADvdhj9FwqCkFqaHAMcgsZ1+YEYSZ5l7v2zS8qphVJ1KUAlleY2F93HpekUpCUPTF3GprUQW2K8G/sbu0UcjwNeAn5kG9C12TvecwM7Q+V414KpTCRrpoUiyRetNtPnN8z2jTsObRPO8V2bhvvJsn6fF94rabG981Zknn/aos6hkcwYYhITcB1kTqDQ96PHI+fbZzrj+s7nmFXPPYeazkSZNt1GdSlCoy/DehrTX29oYlZTRSPfKzHQA2uY2/88UEWKrDZ2ZjFlDG52ZSH8/li3dROKziMV1DhtGT3Xm+d3ao87ijmhmhd/d7c2Jif3T96G0IscJ3zor/K6Vg1FXT0zs/wVk/WFaWmGMmhV+95MMeTnRn1Fnhgc6o04go07gE5fLuVR0lhyzZs13dP/EiaPckvIAcEHa7/MWsLRNw/I0cDI7p7+eZedx3CDHaqxjp1PIduDJNvksM2lPSKtPD9jQ+ZAZKadYC/yvjXF8AZm6TfEBu54G+whyoF86fw2FksQTIRKJEKFQciGE5rLrqaIvBkFnm/8vRM64ae86AzmiWWJ6Uq8Ch84Kv3uzRSMjD3/43cSs8LvTgUNNGpvZdVOnW+yiE4kabeeU8AQS7Vl1Kk6ZbozCemAWcKUxAulch6yzrTdG5Zo2n8811yw0HYzfAfe3uaYVOc1zlknnSVOfrHIBsq9ss8nvKHYPdf8Vo3OzyWdym88/AM5BNiBvRE7XvSUUgkQilH4Gy5dMo7sZ+HebBrloOjPk1RF0FndEk8VQLEbOOP+MjRsX1SBrA0ea6Zwh7PSWqkMWsueYaZ5/9uw5vGFW+N3/mesd8+TmBzO9vYvOUChEMpm0pdMMc/PqPKX7Wa7pNNjSGQ6HGxKJhHs6n3wy62emHAmHwyQSiULKMy+nnHKKqxW5kPrp8rO0CnHUyMVHiCt7rg7FfebPK3aQO1IGZpT1RQsjuAcAGraHGTAgxtlf3UQ8DmknStabv4RpHLd7pXPbtgijRzdx5NHbaGwM09IS2k1nDlzT2bIjRHWnBCd8aSvVnRI0NYVtl6cXOp2O/G1yCLKfcjgwE5hSZuEBHgZcC6Gzy8urO0WjnYhGKwmHo4RCMiBKJhO9E4lY71iseUIstv3ilpbG7Rs3LnoAuK1nz+F+9byHAddWVFSe06NH7+q+ffegS5daKisriETCvPnmgow6IfkAssHTV53ZyvOQQ0YSjyd6Nzfv6F1XVz9h/fp1F69fv6axtTX2oOnl+Knz+2Vl0bN69uxd3bt3b7p160KnTtU0NcVYtmwd9fXbfSnPjz7aeeROeXk54XCY1tZWamtr2bhx0bBIJPL9aLT8rJ49U797Z6qrqygrk/rZ2pro3djY1LuubtuEtWvXXLxx4/rGLVuWPhiPx29Zu7b7kvr6esrKykgkErS07Nzfu88++xBAyoA70qbOTjHTM98ulqBIGHY0h2hthUgE4jtXHJ9i596xs82U4dkBLFPV6XH9LMthYCqBaaFQeEpVVbfyysquhMORLD3gCOFwhLKySqqqupJIxDs1N2+9oKlpyzc2blx0J/Cjnj2HN2e8+bDm3LJTn2fvgVcC02pqaq8cOHCv6MCB/ams3NVBI5lMEgqFcupMJhN3ImsnnurMV56RSJiysggVFVG6dKlh4MA9iMX2rV6x4tPzPv54ydfr67fd4UhnfiqBH1dVVX934MDB0UGD+lNdvetZbS0tccLhEOGwg/J0yIcfflgJTKuu7nTlgAGDo4MGDaCyspxQKLzbyYbl5WHKy2vp0qWWAQP2oLm5pfqTT1aet3Llx1+fPXv2HcCPxo0b10xpsFfaQ5x6sM8upqGpKE+waVMZGzeWMXhwC7FYBCQKxqQ2l54WwPJUnT7Uz7IsRmYo8GhFRe34Tp16EQ7bc24IhyNUV/egsrJL+fbtG67ZsaP+2I0bF33Zg9HN0HA4/NigQUPHDR8+jKqqCsc6zfTHEg8qScHlGY2WMXToQAYO7BddtGjpNR9/vGRyLBY7zQud4XD48X79BowdOXI4NTWdAlme77///tBQKPTYnnsOHDdy5AiqqysJh/Mf8RMKQSgUprq6khEjhjJgwJ7RBQsWXrN69Yovvv/++2eMGTOmFNa9emd4r2sxBYXLoHlbmCWLKxmy12cjwp4ZLo0HsDxVpw/1M5zByOwPvF5T03t8be0ethvFXRueMmpr96Cmpvd4YJZJ2y32j0ajb4wf/7lx48aNtm1kcukEXNXpVnlGo2WMHj2C/fc/aExlZeUbbuuMRqNvjho1Zuz48WNsGxm/ynPevHn7R6PRN0ePHjduzJjR1NRUWzIyu2sMU1NTzZgxoxk9ety4aDT6xrx58/YPwIPaBTgPOeRuTCZ7GaBG5QjgFJJQXR1n5YoKNm2MUFmZgMwxBlu9FBMK5dGZGd915i3PYOssqH6G2xiZYcBztbV79KmsdK+TVFnZldraPfoAz5k8nDIsGo3+e7/9Duo9cGA/T3TiTvBKT8pzjz16cdBBh/SqrKx83i2d0Wj0hX33HddryJBBlJWVBbI8Fy5cOCwajT6/777jew0e3J+KinLn0z4V5Qwe3J999x3fKxqNPr9w4cJiBi2tQTzIpgM/Qda6hre5Jijn0f8acax4AphbUZHsuWVLhGXLKqmo9F9iytMtQ59jF51ZRgaBK8+A6iy4fobTjEwV8GhNTe9eFRW1riusqKilpqZ3L+Axk1ehVIXD4cf23Xe/nv369fJUJxKPrGCdXpZn9+5dOOCAg3qUlZU94VRnOBx+bMSIUd3799+DSCQcyPJcuHBhFfDoyJH79thzzz6uGUOAsrIy9tyzLyNH7tsDeMzkVQwmIWstfYFuiBvsuQFscI4DLkn7/xhgRjgM69ZEaY2Fco0uPKEskmRbfZhYbJeRTUadpVKeAdRZcP1Mb1WmVVTUjnOz552ph1tRUTsW2XhYKNMGDRo6duDAPQKv0+vy7NWrO3vvPXLfcDj848KnG0I37rnnwLEDB/YnEokEsjzLy8sBpvXvP2jcgAH9XDUyO41NhAED+tG//6CxwDSTp98ckuG9QwPY4ByR4b0J4bBEBojH8d3QVFYlWPNpOWvWRKmpiadGOBl1lkp5BlBnwfUzbEYzQ0Oh8JROnXp5rrRTp96EQuEpBU6hDa2pqb1y+PBhhDyuySmdBU75+Faew4btRW1t5+8WqrOysmrKiBF7U14eDWx5zps3b2hVVdWVw4cP91RneXmU4cOHU1VVfeW8efO8nELLZtHLbVxbTDKFTNkBMnUVKsIqUlkZNDeFWbywinA4mdKQVWeplGeRcL1+pkY0U6uqukWdLFRbJRyOUFXVLcrOc2vs9L6nDhy4V5mThX8/dPpZnpFImOHD9ymLRCLX2f+O4esHDBhUVlVVGfTf/bqBA/cqq6mp9lxnTU01AwcOKQuFQtd59ADvh+wUPyDDQ5ppfrtYazJ9EPfZwRk+i1t8zzedySSDa2riLF9Wwdq1UaqrE0XTKd6Nu/1wpVCentXP8MaNi2ohdLaXUzyZplIgdJbkbZna8vKKcwYO3NN3nYAtnX6X5x579Ka8vOIrdnVGImVfGTx4oGdTZm6U55NPPlkbiZSdNXjwQMJh77vK4XAIKZOyrzz55JNuL65NBp4Bfg/8AziRYHIoEs3iMfPvCaWgs7wiecK2+giLF1YSjRbfZyJUeuXpWf0MA8eXl1d3yrYZ06vebXl5dSfgeBu3Hd+zZ+/qysrywOv0vzxD9OvXv9quzl69eldXVlYEvjx79epT7ccodqdBrKBXrz52yzPVI4ySParudOSMoSpgD8RrJ2hTY2HgwbTOQBnwKM4cTnzRmUzyaLQsWbV+Q5TmHSHCYf9FRcpg+/Yw27eHqChPBK08i1Y/w8DR0Wgn37+xyfNoG7cc3afPHiWhsxjl2atXb9s6e/fu7flalxvl2bdvX397oiEwedrRWWse1BeQYJhD2nzeg10j7wKMoDhurFchkaN/y+7z7v2AAW1tLzuPuQi0zkg4OTKZhEQ8RCiU9F1nJJIsb2wM88nHFYTDySCVZ1HrZxkwtqyswvcaZPIca+OWsZ0715aEzmKUZ21tp3Zbnl27dvFdp8nTjs4pyCa2GuSo7a7A6eyM0p2t91Hp81e7FjmiIsXebQxqeY7ecOB1JiHis0PCbjorypNHf7y8kjFjm4hGk+VpQUaLWZ5FrZ9hYGgk4r8rp8lzqI1bhlZXV5SEzmKUp9m8aLM8q30f0RRSnlVV/s8ymDzt6LzYPMSpRuQUdj2cLltB+72Y0NbJ4ag2BjXbInRcdVrTGS1Pjm1qCtPQECYaTQZFZ1HrZxjoHC7CZKbJs7ONWzqHw2GSyaTtv0Qi6bvOUijPaLRwr7iUgZJgpdb/jOOBLZ2pKMz+jrxsl2e/PO8FZUd/Jqvdn+BRsjqTSfpHIuJinUwGRmdR62fJHAUKMHv2AoIV6ik4JBIJ3/KqqalizJjCTpKOx+M888yijvKzhAOoaQe7nz/fojrd1xkKaf1Mz2ibn41Um4Zxm41bVGcOWlpitnXGYoXH5LM7kkn9tbbGbetsbfW/PE2e2xwmkwxg45JUnR1SZ1HrZxhYGo/731EweS61cYvqzEF9faNtnY2NjSR9HNsnk0kaG+3rbGpq8r08TZ5LURTFFUMzt7XV/2gH8fgOkCilVlGdOdi8eYttndu21fuu0+RpS+fWrXW+6zR5ztUmQlHcMTQvxWLbfc+4pWU7wEs2blGdWUgkkqxZ86ltnevXr/d9RLN+/XrbOteuXevromoyCWvXrrWrU1GUHIbm2ZaWxu2JhH/edolEnJaWxkZkk5NVVGcW1q/fSkPDVts6N2xY39jc7N/oq7l5Bxs2rG+yr3NdEXSus6tTUZRshqZnz+H1kHywuXmrjw/yViD5gORtmaLplLyDqTMeT7Bs2XISibhtnfF468OffLKSeDzug844klfrQ3Z0nnLKKfXxeOtDH3+8wpGbup3R4ccfryAeb33wlFNOqdcmQlHcGdEA3NrUtCXmRy88kYjT1LQlhsTRsYvqbMOKFevZuHF1QToTicT0FSs+bm1qavZcZ1NTMytXftyaSCRutntvMpm8ecWK5a0NDY2e69y+vZEVK5a3JpPJW7R5UBQXDU3PnsOXJJOJO7ZvX+/Dg7yeZDJxZ8+ewxcXcLvvOpFoq4HUuWlTPYsXLyCRiBess7m56Y6FCxen3KM9oaUlxsKFi2lsbLyjEJ1jxoxZ0tTU+PNFixb5orOpqfGOMWPGLNbmQVHcHdEATNuxo36ul1M+zc1b2bGjfi4OT65UnbB163bmz19IY+NWRzqTyeSPVq9eMW/FilWeTKHF43FWrFjF6tUr5hWqs6WlBWDaqlWfzF258tPUXhxXaW1tZeXKT1m9+pN5wDSTp6Iobhqanj2HNwGnNzSs37Bjh/tT0zt21NPQsH4DcHrPnsOdzIH4phMIpM716+v44IOFbNq0yhWdiUTitIUL529etWoN8bh7myPj8QSrVq1h4cL5mxOJxGlOdI4YMaIJOH3Bgg82rV691lVj09oaZ/XqdSxY8MGmZDJ52ogRIxq1aVAUb0Y09Ow5fAlwXH39mnVu9sSbm7dSX79mHXCcycMpnus0eQRKZyzWytKla5g/fwEbN65wVWcsFjvmgw/e37h8+Se0trY6TrC1tZXlyz/hgw/e3xiLxY5xQ+eIESOWxGKxYz/4YM6Gjz9eyY4dzkcdO3a08PHHK/nggzkbYrHYsSNGjFji4vMVyvIaC+/j0vWKUvT6uVusm549h78LTGxoWD+3vn4NiUThjU4iEae+fg0NDevnAhNN2m7hmU6TdmB0xmJxVqzYwJw5y1i0aD5bt67xRGcsFjtk/vx5H8yZM4+GhsL3AjU0bGfOnHnMnz/vg1gsdoibOseMGfNuLBY7dP78ufPmzfuQhobGguK8JRIJGhoamTfvQ+bPnzsvFosdOmbMmHddfpDT3eSyDcHSxWcKHV+WI81CiOZ5r8zCfeXZPk+L7xW18F2KpjNPPu1RZ1HrZ8agambUMWHHjvrbt2z5ONbYuAk7HlSJRJzGxk1s2bI8tmNH/e3ABJdGMplGDK7qdGmEULDOeDxJS0sr27Y18umnm5k/fyVvv72QhQsX8umnCzzXmUgkDly9esXPXn/99daPPlqUChljicbGRj76aBGvv/566+rVK36WSCQO9ELnuHHjliQSiYNWrfrk9jfeeL114cKlNDY2k0gkcm7sTCbFwDQ2NrNw4VLeeOP11lWrPrk9kUgcNG7cOKc6M4Uv2JD2elubhzb1UDak/X9dhjQ2t/l/Jg8TO8PlTI1FQxudmUh/P5Yt3UTis4jFdQ4bRk915vnd2qPOotbPrEJ79hzeDFy7ceOi3zc2brqmsXHzOeXl1dXRaCei0UrC4WgqND2JRIJEIkYs1kwstp2WlsYmSP4duK1A7zJbM17AtclkwpFOCvPacl3n7NkfBUHn95qaGu9dvHjB1KVLF5/ds2fvqt69e9OtWxeqq6soKyv7bHqssbGJLVvqWL9+PRs3rm9OJOIPJBKJW0KhkKc6R48e3VxbW3vt7Nmzf79kyYKpy5aJzr59+9K1axeqqqooK4sYnXGamprYurWOtWvXfqYzHo/fcvDBBy+ur3dlDe0B4IK0h/8tdo2Vtg14Gjg5bXrhWWBL2jUvmYe5j/n/duDJNvksM2lPSM1Smryt8hDwtbT/rwX+16bxeQE4Ju29D4AFaf9/BPhhm3T/GgoliSdCJBIhQqHkQgjNZdczZF4Mgs42/1+IhBpq7zqLWj9Dr732oSWVGzcuqgFOBI4ExiNHgXZN61EtB+YArwDP9Ow5vMFKuo890p07fpH9qN4pV6wF4PAjZ1stUFs621js7K1vUwVnnT056+cPPvAvACqrdpS8zlAoRDKZJBwOk0gkbOkMh8MNiUTiszSc6sxH/wGDHNXPVSs/yZtHLp1p9bQ/cAdwGLAIOXnxjTaX7WOu2Q+YB1wOzG8zw/BN4BpTPx4Brmd3J4pDgNuB4cBMYModv+i7ykp5TblibYVpdA4HVgFnAR+1uawbcs7954y+s8216ZwN3Gx0PgR8Z/v2MHv2j3Hc5K0kEhCPhwYCjyIHyP0POGfixFGbvdS5vSG8qv/AFo6bXEc8DvF4aDedGbJzVWcsFvooGk0y+YSt9OjRSlNTuKDydFPnrFnzi1o/Q9+9fE034H7gWKwdL9oCPAycf/qXN7cYY1GJnEP9lSxziW1pNVb+bKDOiqExlaognUDLhIPfAzmWtGCdFhtGRzrNe6rTBZ39BwxqMcbEM52KouQnDPwCmIz1M6zLzVDx+sce6c5jj3QH+IF5L2oxjTKT5502tBasM+091dmBdK5a+UlqxOKHTkVRchiaQrtr6fcd50Iabl6rOlWn3zoVRclhaHoWeG+ftNdupJEP1ak6g6xTUZQchkZRlCzo+oyiqKFRFEVR1NAoiqIoamgURVEURQ2NoiiKooZGURRFUdTQKIqiKGpoFEVRlHZlaOoKvDc9mJsbaeRDdarOIOtUFCWHoXm0wHsfS3vtRhr5UJ2qM8g6FUXJQhlwFVALfAFrx3a2mgfw9rT3bgX6IefXWwl+mEDOUvieDa2qU3UGWaeiKDkMTR0SPt0JLcC3zJ9XqE7VGWSdiqLkMDQdgrdm7+c4jbPO9jZ9t/BDpznfR1EUxZKh6QLci/WpiTgyNXE5Ow/AKgfuAk6zODWRRA6WuhjrC7WqU3UGWaeiKDkMzQzgTJv3XYwcRXqT+f9U4CKbaXwFOafa6n2qU3UGWaeiKFkIA2cUeO/paa/dSCMfqlN1Blmnoig5DE2XAu/t3mZ6w2ka+VCdqjPIOhVFyWFoFEVRFEUNjaIoiqKGRlEURVHU0CiKoihqaBRFURQ1NIqiKIqihkZRFEVRQ6MoiqJ0BEOzscB716W9diONfKhO1RlknYqi5DA0/yrw3mfTXj/nQhr5UJ2qM8g6FUXJYWguNw9zq8V7WoC/Ajenvfdj4G/sjJabj1bzEE+xoVV1qs4g61QUJQv/PwAlukJhy2ScjQAAAABJRU5ErkJggg==\";\r\n\r\nconst iconfontObjects = {\r\n border:{\r\n 'border-top': ' iconfont luckysheet-iconfont-shangbiankuang',\r\n 'border-bottom': ' iconfont luckysheet-iconfont-xiabiankuang',\r\n 'border-left': ' iconfont luckysheet-iconfont-zuobiankuang',\r\n 'border-right': ' iconfont luckysheet-iconfont-youbiankuang',\r\n 'border-none': ' iconfont luckysheet-iconfont-wubiankuang',\r\n 'border-all': ' iconfont luckysheet-iconfont-quanjiabiankuang',\r\n 'border-outside': ' iconfont luckysheet-iconfont-sizhoujiabiankuang',\r\n 'border-inside': ' iconfont luckysheet-iconfont-neikuangxian',\r\n 'border-horizontal': ' iconfont luckysheet-iconfont-neikuanghengxian',\r\n 'border-vertical': ' iconfont luckysheet-iconfont-neikuangshuxian',\r\n },\r\n align:{\r\n 'left': ' iconfont luckysheet-iconfont-wenbenzuoduiqi',\r\n 'center': ' iconfont luckysheet-iconfont-wenbenjuzhongduiqi',\r\n 'right': ' iconfont luckysheet-iconfont-wenbenyouduiqi',\r\n 'top': ' iconfont luckysheet-iconfont-dingbuduiqi',\r\n 'middle': ' iconfont luckysheet-iconfont-shuipingduiqi',\r\n 'bottom': ' iconfont luckysheet-iconfont-dibuduiqi',\r\n },\r\n textWrap:{\r\n 'overflow': ' iconfont luckysheet-iconfont-yichu1',\r\n 'wrap': ' iconfont luckysheet-iconfont-zidonghuanhang',\r\n 'clip': ' iconfont luckysheet-iconfont-jieduan',\r\n },\r\n rotation:{\r\n 'none': ' iconfont luckysheet-iconfont-wuxuanzhuang',\r\n 'angleup': ' iconfont luckysheet-iconfont-xiangshangqingxie',\r\n 'angledown': ' iconfont luckysheet-iconfont-xiangxiaqingxie',\r\n 'vertical': ' iconfont luckysheet-iconfont-shupaiwenzi',\r\n 'rotation-up': ' iconfont luckysheet-iconfont-wenbenxiangshang',\r\n 'rotation-down': ' iconfont luckysheet-iconfont-xiangxia90',\r\n }\r\n}\r\n\r\n/**\r\n *单元格右击菜单配置\r\n *\r\n */\r\nfunction customCellRightClickConfig() {\r\n const config = {\r\n\t\tcopy: true, // copy\r\n\t\tcopyAs: true, // copy as\r\n\t\tpaste: true, // paste\r\n\t\tinsertRow: true, // insert row\r\n\t\tinsertColumn: true, // insert column\r\n\t\tdeleteRow: true, // delete the selected row\r\n\t\tdeleteColumn: true, // delete the selected column\r\n\t\tdeleteCell: true, // delete cell\r\n\t\thideRow: true, // hide the selected row and display the selected row\r\n\t\thideColumn: true, // hide the selected column and display the selected column\r\n\t\trowHeight: true, // row height\r\n\t\tcolumnWidth: true, // column width\r\n\t\tclear: true, // clear content\r\n\t\tmatrix: true, // matrix operation selection\r\n\t\tsort: true, // sort selection\r\n\t\tfilter: true, // filter selection\r\n\t\tchart: true, // chart generation\r\n\t\timage: true, // insert picture\r\n\t\tlink: true, // insert link\r\n\t\tdata: true, // data verification\r\n\t\tcellFormat: true // Set cell format\r\n\t}\r\n\r\n // cellRightClickConfig determines the final result\r\n if(JSON.stringify(luckysheetConfigsetting.cellRightClickConfig) !== '{}'){\r\n Object.assign(config,luckysheetConfigsetting.cellRightClickConfig);\r\n }\r\n luckysheetConfigsetting.cellRightClickConfig = config;\r\n return config;\r\n}\r\n\r\n/**\r\n *sheet页右击菜单配置\r\n *\r\n */\r\nfunction customSheetRightClickConfig() {\r\n const config = {\r\n delete: true, //Delete\r\n copy: true, //Copy\r\n rename: true, //Rename\r\n color: true, //Change color\r\n hide: true, //Hide, unhide\r\n move: true, //Move to the left, move to the right\r\n\t}\r\n\r\n // sheetRightClickConfig determines the final result\r\n if(JSON.stringify(luckysheetConfigsetting.sheetRightClickConfig) !== '{}'){\r\n Object.assign(config,luckysheetConfigsetting.sheetRightClickConfig);\r\n }\r\n luckysheetConfigsetting.sheetRightClickConfig = config;\r\n return config;\r\n}\r\n\r\nexport {\r\n gridHTML,\r\n columeHeader_word,\r\n columeHeader_word_index,\r\n flow,\r\n colsmenuHTML,\r\n rightclickHTML,\r\n pivottableconfigHTML,\r\n pivottablesumHTML,\r\n sheetHTML,\r\n columnHeaderHTML,\r\n sheetselectlistHTML,\r\n sheetselectlistitemHTML,\r\n inputHTML,\r\n modelHTML,\r\n maskHTML,\r\n filtermenuHTML,\r\n filtersubmenuHTML,\r\n sheetconfigHTML,\r\n luckysheetPivotTableHTML,\r\n luckysheetAlternateformatHtml,\r\n luckysheetchartpointconfigHTML,\r\n luckysheetToolHTML,\r\n menuToolBar,\r\n luckysheetlodingHTML,\r\n luckyColor,\r\n keycode,\r\n luckysheetdefaultstyle,\r\n luckysheet_CFiconsImg,\r\n luckysheetdefaultFont,\r\n iconfontObjects\r\n}","var fails = require('../internals/fails');\nvar whitespaces = require('../internals/whitespaces');\n\nvar non = '\\u200B\\u0085\\u180E';\n\n// check that a method works with the correct list\n// of whitespaces and has a correct name\nmodule.exports = function (METHOD_NAME) {\n return fails(function () {\n return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;\n });\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar $trim = require('../internals/string-trim').trim;\nvar forcedStringTrimMethod = require('../internals/string-trim-forced');\n\n// `String.prototype.trim` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.trim\n$({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, {\n trim: function trim() {\n return $trim(this);\n }\n});\n","var $ = require('../internals/export');\nvar toObject = require('../internals/to-object');\nvar nativeKeys = require('../internals/object-keys');\nvar fails = require('../internals/fails');\n\nvar FAILS_ON_PRIMITIVES = fails(function () { nativeKeys(1); });\n\n// `Object.keys` method\n// https://tc39.github.io/ecma262/#sec-object.keys\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n keys: function keys(it) {\n return nativeKeys(toObject(it));\n }\n});\n","var DESCRIPTORS = require('../internals/descriptors');\nvar defineProperty = require('../internals/object-define-property').f;\n\nvar FunctionPrototype = Function.prototype;\nvar FunctionPrototypeToString = FunctionPrototype.toString;\nvar nameRE = /^\\s*function ([^ (]*)/;\nvar NAME = 'name';\n\n// Function instances `.name` property\n// https://tc39.github.io/ecma262/#sec-function-instances-name\nif (DESCRIPTORS && !(NAME in FunctionPrototype)) {\n defineProperty(FunctionPrototype, NAME, {\n configurable: true,\n get: function () {\n try {\n return FunctionPrototypeToString.call(this).match(nameRE)[1];\n } catch (error) {\n return '';\n }\n }\n });\n}\n","var toIndexedObject = require('../internals/to-indexed-object');\nvar nativeGetOwnPropertyNames = require('../internals/object-get-own-property-names').f;\n\nvar toString = {}.toString;\n\nvar windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames\n ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function (it) {\n try {\n return nativeGetOwnPropertyNames(it);\n } catch (error) {\n return windowNames.slice();\n }\n};\n\n// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nmodule.exports.f = function getOwnPropertyNames(it) {\n return windowNames && toString.call(it) == '[object Window]'\n ? getWindowNames(it)\n : nativeGetOwnPropertyNames(toIndexedObject(it));\n};\n","var $ = require('../internals/export');\nvar fails = require('../internals/fails');\nvar nativeGetOwnPropertyNames = require('../internals/object-get-own-property-names-external').f;\n\nvar FAILS_ON_PRIMITIVES = fails(function () { return !Object.getOwnPropertyNames(1); });\n\n// `Object.getOwnPropertyNames` method\n// https://tc39.github.io/ecma262/#sec-object.getownpropertynames\n$({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES }, {\n getOwnPropertyNames: nativeGetOwnPropertyNames\n});\n","'use strict';\nvar getBuiltIn = require('../internals/get-built-in');\nvar definePropertyModule = require('../internals/object-define-property');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar DESCRIPTORS = require('../internals/descriptors');\n\nvar SPECIES = wellKnownSymbol('species');\n\nmodule.exports = function (CONSTRUCTOR_NAME) {\n var Constructor = getBuiltIn(CONSTRUCTOR_NAME);\n var defineProperty = definePropertyModule.f;\n\n if (DESCRIPTORS && Constructor && !Constructor[SPECIES]) {\n defineProperty(Constructor, SPECIES, {\n configurable: true,\n get: function () { return this; }\n });\n }\n};\n","var DESCRIPTORS = require('../internals/descriptors');\nvar global = require('../internals/global');\nvar isForced = require('../internals/is-forced');\nvar inheritIfRequired = require('../internals/inherit-if-required');\nvar defineProperty = require('../internals/object-define-property').f;\nvar getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar isRegExp = require('../internals/is-regexp');\nvar getFlags = require('../internals/regexp-flags');\nvar stickyHelpers = require('../internals/regexp-sticky-helpers');\nvar redefine = require('../internals/redefine');\nvar fails = require('../internals/fails');\nvar setInternalState = require('../internals/internal-state').set;\nvar setSpecies = require('../internals/set-species');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar MATCH = wellKnownSymbol('match');\nvar NativeRegExp = global.RegExp;\nvar RegExpPrototype = NativeRegExp.prototype;\nvar re1 = /a/g;\nvar re2 = /a/g;\n\n// \"new\" should create a new object, old webkit bug\nvar CORRECT_NEW = new NativeRegExp(re1) !== re1;\n\nvar UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y;\n\nvar FORCED = DESCRIPTORS && isForced('RegExp', (!CORRECT_NEW || UNSUPPORTED_Y || fails(function () {\n re2[MATCH] = false;\n // RegExp constructor can alter flags and IsRegExp works correct with @@match\n return NativeRegExp(re1) != re1 || NativeRegExp(re2) == re2 || NativeRegExp(re1, 'i') != '/a/i';\n})));\n\n// `RegExp` constructor\n// https://tc39.github.io/ecma262/#sec-regexp-constructor\nif (FORCED) {\n var RegExpWrapper = function RegExp(pattern, flags) {\n var thisIsRegExp = this instanceof RegExpWrapper;\n var patternIsRegExp = isRegExp(pattern);\n var flagsAreUndefined = flags === undefined;\n var sticky;\n\n if (!thisIsRegExp && patternIsRegExp && pattern.constructor === RegExpWrapper && flagsAreUndefined) {\n return pattern;\n }\n\n if (CORRECT_NEW) {\n if (patternIsRegExp && !flagsAreUndefined) pattern = pattern.source;\n } else if (pattern instanceof RegExpWrapper) {\n if (flagsAreUndefined) flags = getFlags.call(pattern);\n pattern = pattern.source;\n }\n\n if (UNSUPPORTED_Y) {\n sticky = !!flags && flags.indexOf('y') > -1;\n if (sticky) flags = flags.replace(/y/g, '');\n }\n\n var result = inheritIfRequired(\n CORRECT_NEW ? new NativeRegExp(pattern, flags) : NativeRegExp(pattern, flags),\n thisIsRegExp ? this : RegExpPrototype,\n RegExpWrapper\n );\n\n if (UNSUPPORTED_Y && sticky) setInternalState(result, { sticky: sticky });\n\n return result;\n };\n var proxy = function (key) {\n key in RegExpWrapper || defineProperty(RegExpWrapper, key, {\n configurable: true,\n get: function () { return NativeRegExp[key]; },\n set: function (it) { NativeRegExp[key] = it; }\n });\n };\n var keys = getOwnPropertyNames(NativeRegExp);\n var index = 0;\n while (keys.length > index) proxy(keys[index++]);\n RegExpPrototype.constructor = RegExpWrapper;\n RegExpWrapper.prototype = RegExpPrototype;\n redefine(global, 'RegExp', RegExpWrapper);\n}\n\n// https://tc39.github.io/ecma262/#sec-get-regexp-@@species\nsetSpecies('RegExp');\n","var $ = require('../internals/export');\nvar repeat = require('../internals/string-repeat');\n\n// `String.prototype.repeat` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.repeat\n$({ target: 'String', proto: true }, {\n repeat: repeat\n});\n","// `SameValue` abstract operation\n// https://tc39.github.io/ecma262/#sec-samevalue\nmodule.exports = Object.is || function is(x, y) {\n // eslint-disable-next-line no-self-compare\n return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;\n};\n","import { chatatABC } from '../utils/util';\r\nimport Store from '../store';\r\n\r\nfunction getSheetIndex(index) {\r\n for (let i = 0; i < Store.luckysheetfile.length; i++) {\r\n if (Store.luckysheetfile[i][\"index\"] == index) {\r\n return i;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction getRangetxt(sheetIndex, range, currentIndex) {\r\n let sheettxt = \"\";\r\n\r\n if (currentIndex == null) {\r\n currentIndex = Store.currentSheetIndex;\r\n }\r\n\r\n if (sheetIndex != currentIndex) {\r\n //sheet名字包含'的,引用时应该替换为''\r\n sheettxt = Store.luckysheetfile[getSheetIndex(sheetIndex)].name.replace(/'/g,\"''\");\r\n //如果包含除a-z、A-Z、0-9、下划线等以外的字符那么就用单引号包起来\r\n if(/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/.test(sheettxt))\r\n {\r\n sheettxt = sheettxt+\"!\";\r\n }\r\n else\r\n {\r\n sheettxt=\"'\"+sheettxt+\"'!\";\r\n }\r\n }\r\n\r\n let row0 = range[\"row\"][0], row1 = range[\"row\"][1];\r\n let column0 = range[\"column\"][0], column1 = range[\"column\"][1];\r\n\r\n if (row0 == null && row1 == null) {\r\n return sheettxt + chatatABC(column0) + \":\" + chatatABC(column1);\r\n }\r\n else if (column0 == null && column1 == null) {\r\n return sheettxt + (row0 + 1) + \":\" + (row1 + 1);\r\n }\r\n else {\r\n if (column0 == column1 && row0 == row1) {\r\n return sheettxt + chatatABC(column0) + (row0 + 1);\r\n }\r\n else {\r\n return sheettxt + chatatABC(column0) + (row0 + 1) + \":\" + chatatABC(column1) + (row1 + 1);\r\n }\r\n }\r\n}\r\n\r\nfunction getluckysheet_select_save() {\r\n return Store.luckysheet_select_save;\r\n}\r\n\r\nfunction getluckysheet_scroll_status() {\r\n return Store.luckysheet_scroll_status;\r\n}\r\n\r\nfunction getluckysheetfile(plugin) {\r\n // 获取图表数据\r\n if(plugin){\r\n Store.luckysheetfile.forEach(file => {\r\n if(!!file.chart){\r\n file.chart.forEach((chartObj)=>{\r\n const chartJson = Store.getChartJson(chartObj.chart_id);\r\n chartObj.chartOptions = chartJson;\r\n })\r\n }\r\n });\r\n }\r\n \r\n return Store.luckysheetfile;\r\n}\r\n\r\nfunction getconfig() {\r\n return Store.config;\r\n}\r\n\r\nfunction getvisibledatarow() {\r\n return Store.visibledatarow;\r\n}\r\n\r\nfunction getvisibledatacolumn() {\r\n return Store.visibledatacolumn;\r\n}\r\n\r\nexport {\r\n getSheetIndex,\r\n getRangetxt,\r\n getluckysheet_select_save,\r\n getluckysheet_scroll_status,\r\n getluckysheetfile,\r\n getconfig,\r\n getvisibledatarow,\r\n getvisibledatacolumn,\r\n}\r\n","import { getSheetIndex } from '../methods/get';\r\nimport Store from '../store';\r\n\r\nfunction setluckysheet_select_save(v) {\r\n Store.luckysheet_select_save = v;\r\n}\r\n\r\nfunction setluckysheet_scroll_status(v) {\r\n Store.luckysheet_scroll_status = v;\r\n}\r\n\r\nfunction setluckysheetfile(d) {\r\n Store.luckysheetfile = d;\r\n}\r\n\r\nfunction setconfig(v) {\r\n Store.config = v;\r\n\r\n if(Store.luckysheetfile != null){\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = v;\r\n }\r\n}\r\n\r\nfunction setvisibledatarow(v) {\r\n Store.visibledatarow = v;\r\n\r\n if(Store.luckysheetfile != null){\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].visibledatarow = v;\r\n }\r\n}\r\n\r\nfunction setvisibledatacolumn(v) {\r\n Store.visibledatacolumn = v;\r\n\r\n if(Store.luckysheetfile != null){\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].visibledatacolumn = v;\r\n }\r\n}\r\n\r\nexport {\r\n setluckysheet_select_save,\r\n setluckysheet_scroll_status,\r\n setluckysheetfile,\r\n setconfig,\r\n setvisibledatarow,\r\n setvisibledatacolumn,\r\n}","'use strict';\nvar fixRegExpWellKnownSymbolLogic = require('../internals/fix-regexp-well-known-symbol-logic');\nvar anObject = require('../internals/an-object');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\nvar sameValue = require('../internals/same-value');\nvar regExpExec = require('../internals/regexp-exec-abstract');\n\n// @@search logic\nfixRegExpWellKnownSymbolLogic('search', 1, function (SEARCH, nativeSearch, maybeCallNative) {\n return [\n // `String.prototype.search` method\n // https://tc39.github.io/ecma262/#sec-string.prototype.search\n function search(regexp) {\n var O = requireObjectCoercible(this);\n var searcher = regexp == undefined ? undefined : regexp[SEARCH];\n return searcher !== undefined ? searcher.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));\n },\n // `RegExp.prototype[@@search]` method\n // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search\n function (regexp) {\n var res = maybeCallNative(nativeSearch, regexp, this);\n if (res.done) return res.value;\n\n var rx = anObject(regexp);\n var S = String(this);\n\n var previousLastIndex = rx.lastIndex;\n if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0;\n var result = regExpExec(rx, S);\n if (!sameValue(rx.lastIndex, previousLastIndex)) rx.lastIndex = previousLastIndex;\n return result === null ? -1 : result.index;\n }\n ];\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar $includes = require('../internals/array-includes').includes;\nvar addToUnscopables = require('../internals/add-to-unscopables');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar USES_TO_LENGTH = arrayMethodUsesToLength('indexOf', { ACCESSORS: true, 1: 0 });\n\n// `Array.prototype.includes` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.includes\n$({ target: 'Array', proto: true, forced: !USES_TO_LENGTH }, {\n includes: function includes(el /* , fromIndex = 0 */) {\n return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables('includes');\n","'use strict';\nvar $ = require('../internals/export');\nvar $map = require('../internals/array-iteration').map;\nvar arrayMethodHasSpeciesSupport = require('../internals/array-method-has-species-support');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('map');\n// FF49- issue\nvar USES_TO_LENGTH = arrayMethodUsesToLength('map');\n\n// `Array.prototype.map` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.map\n// with adding support of @@species\n$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT || !USES_TO_LENGTH }, {\n map: function map(callbackfn /* , thisArg */) {\n return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n","const browser = {\r\n mobilecheck: function() {\r\n var a = !1;\r\n return function(b) {\r\n (/(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(b) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test(b.substr(0, 4))) && (a = !0);\r\n }(navigator.userAgent || navigator.vendor || window.opera), document.body && document.body.clientWidth && document.body.clientHeight && document.body.clientWidth < 350 && document.body.clientHeight < 500 && (a = !0), a;\r\n },\r\n iphoneCheck: function() {\r\n var a = !1;\r\n return /iPhone/i.test(navigator.userAgent) && (a = !0), !0;\r\n },\r\n isWeixin:function() {\r\n var a = navigator.userAgent.toLowerCase();\r\n return \"micromessenger\" == a.match(/MicroMessenger/i) ? !0 : !1;\r\n },\r\n isAndroid:function() {\r\n var a = navigator.userAgent,\r\n b = (navigator.appVersion, a.indexOf(\"Android\") > -1 || a.indexOf(\"Linux\") > -1);\r\n return b;\r\n },\r\n tabletCheck:function() {\r\n var a = /ipad|android|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(navigator.userAgent.toLowerCase());\r\n return a;\r\n },\r\n BrowserType: function() {\r\n var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串\r\n var isOpera = userAgent.indexOf(\"Opera\") > -1; //判断是否Opera浏览器\r\n var isIE = userAgent.indexOf(\"compatible\") > -1 && userAgent.indexOf(\"MSIE\") > -1 && !isOpera; //判断是否IE浏览器\r\n var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf(\"rv:11.0\") > -1;\r\n var isEdge = userAgent.indexOf(\"Edge\") > -1; //判断是否IE的Edge浏览器\r\n var isFF = userAgent.indexOf(\"Firefox\") > -1; //判断是否Firefox浏览器\r\n var isSafari = userAgent.indexOf(\"Safari\") > -1 && userAgent.indexOf(\"Chrome\") == -1; //判断是否Safari浏览器\r\n var isChrome = userAgent.indexOf(\"Chrome\") > -1 && userAgent.indexOf(\"Safari\") > -1; //判断Chrome浏览器\r\n if (isIE) {\r\n var reIE = new RegExp(\"MSIE (\\\\d+\\\\.\\\\d+);\");\r\n reIE.test(userAgent);\r\n var fIEVersion = parseFloat(RegExp[\"$1\"]);\r\n if (fIEVersion == 7) {\r\n return \"IE7\";\r\n } else if (fIEVersion == 8) {\r\n return \"IE8\";\r\n } else if (fIEVersion == 9) {\r\n return \"IE9\";\r\n } else if (fIEVersion == 10) {\r\n return \"IE10\";\r\n // } else if (fIEVersion == 11) {\r\n // return \"IE11\";\r\n } else {\r\n return \"0\";\r\n } //IE版本过低\r\n } //isIE end\r\n if (isFF) {\r\n return \"FF\";\r\n }\r\n if (isOpera) {\r\n return \"Opera\";\r\n }\r\n if (isSafari) {\r\n return \"Safari\";\r\n }\r\n if (isChrome) {\r\n return \"Chrome\";\r\n }\r\n if (isEdge) {\r\n return \"Edge\";\r\n }\r\n if (isIE11) {\r\n return \"IE11\";\r\n }\r\n }, //myBrowser() end\r\n //判断是否是IE浏览器\r\n isIE: function() {\r\n var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串\r\n var isOpera = userAgent.indexOf(\"Opera\") > -1; //判断是否Opera浏览器\r\n var isIE = userAgent.indexOf(\"compatible\") > -1 && userAgent.indexOf(\"MSIE\") > -1 && !isOpera; //判断是否IE浏览器\r\n var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf(\"rv:11.0\") > -1;\r\n if (isIE || isIE11) {\r\n return \"1\";\r\n } else {\r\n return \"-1\";\r\n }\r\n },\r\n //判断是否是IE浏览器,包括Edge浏览器\r\n IEVersion: function() {\r\n var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串\r\n var isOpera = userAgent.indexOf(\"Opera\") > -1; //判断是否Opera浏览器\r\n var isIE = userAgent.indexOf(\"compatible\") > -1 && userAgent.indexOf(\"MSIE\") > -1 && !isOpera; //判断是否IE浏览器\r\n var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf(\"rv:11.0\") > -1;\r\n var isEdge = userAgent.indexOf(\"Windows NT 6.1; Trident/7.0;\") > -1 && !isIE; //判断是否IE的Edge浏览器\r\n if (isIE) {\r\n var reIE = new RegExp(\"MSIE (\\\\d+\\\\.\\\\d+);\");\r\n reIE.test(userAgent);\r\n var fIEVersion = parseFloat(RegExp[\"$1\"]);\r\n if (fIEVersion == 7) {\r\n return \"IE7\";\r\n } else if (fIEVersion == 8) {\r\n return \"IE8\";\r\n } else if (fIEVersion == 9) {\r\n return \"IE9\";\r\n } else if (fIEVersion == 10) {\r\n return \"IE10\";\r\n // } else if (fIEVersion == 11) {\r\n // return \"IE11\";\r\n } else {\r\n return \"0\";\r\n } //IE版本过低\r\n } else if (isEdge) {\r\n return \"Edge\";\r\n } else if (isIE11) {\r\n return \"IE11\";\r\n } else {\r\n return \"-1\"; //非IE\r\n }\r\n },\r\n luckysheetrefreshfixednum:null,\r\n luckysheetrefreshfixed:function(){\r\n var _this = this;\r\n if(_this.luckysheetrefreshfixednum==null){\r\n if(_this.BrowserType()==\"FF\"){\r\n _this.luckysheetrefreshfixednum = 5;\r\n }\r\n else{\r\n _this.luckysheetrefreshfixednum = 0;\r\n }\r\n }\r\n\r\n return _this.luckysheetrefreshfixednum;\r\n },\r\n detectOS() {\r\n var userAgent = navigator.userAgent;\r\n var isWin = (navigator.platform == \"Win32\") || (navigator.platform == \"Windows\");\r\n var isMac = (navigator.platform == \"Mac68K\") || (navigator.platform == \"MacPPC\") || (navigator.platform == \"Macintosh\") || (navigator.platform == \"MacIntel\");\r\n if (isMac) return \"Mac\";\r\n var isUnix = (navigator.platform == \"X11\") && !isWin && !isMac;\r\n if (isUnix) return \"Unix\";\r\n var isLinux = (String(navigator.platform).indexOf(\"Linux\") > -1);\r\n if (isLinux) return \"Linux\";\r\n if (isWin) {\r\n var isWin2K = userAgent.indexOf(\"Windows NT 5.0\") > -1 || userAgent.indexOf(\"Windows 2000\") > -1;\r\n if (isWin2K) return \"Win2000\";\r\n var isWinXP = userAgent.indexOf(\"Windows NT 5.1\") > -1 || userAgent.indexOf(\"Windows XP\") > -1;\r\n if (isWinXP) return \"WinXP\";\r\n var isWin2003 = userAgent.indexOf(\"Windows NT 5.2\") > -1 || userAgent.indexOf(\"Windows 2003\") > -1;\r\n if (isWin2003) return \"Win2003\";\r\n var isWinVista= userAgent.indexOf(\"Windows NT 6.0\") > -1 || userAgent.indexOf(\"Windows Vista\") > -1;\r\n if (isWinVista) return \"WinVista\";\r\n var isWin7 = userAgent.indexOf(\"Windows NT 6.1\") > -1 || userAgent.indexOf(\"Windows 7\") > -1;\r\n if (isWin7) return \"Win7\";\r\n }\r\n return \"other\";\r\n }\r\n};\r\n\r\nexport default browser;","'use strict';\n\n\nvar TYPED_OK = (typeof Uint8Array !== 'undefined') &&\n (typeof Uint16Array !== 'undefined') &&\n (typeof Int32Array !== 'undefined');\n\nfunction _has(obj, key) {\n return Object.prototype.hasOwnProperty.call(obj, key);\n}\n\nexports.assign = function (obj /*from1, from2, from3, ...*/) {\n var sources = Array.prototype.slice.call(arguments, 1);\n while (sources.length) {\n var source = sources.shift();\n if (!source) { continue; }\n\n if (typeof source !== 'object') {\n throw new TypeError(source + 'must be non-object');\n }\n\n for (var p in source) {\n if (_has(source, p)) {\n obj[p] = source[p];\n }\n }\n }\n\n return obj;\n};\n\n\n// reduce buffer size, avoiding mem copy\nexports.shrinkBuf = function (buf, size) {\n if (buf.length === size) { return buf; }\n if (buf.subarray) { return buf.subarray(0, size); }\n buf.length = size;\n return buf;\n};\n\n\nvar fnTyped = {\n arraySet: function (dest, src, src_offs, len, dest_offs) {\n if (src.subarray && dest.subarray) {\n dest.set(src.subarray(src_offs, src_offs + len), dest_offs);\n return;\n }\n // Fallback to ordinary array\n for (var i = 0; i < len; i++) {\n dest[dest_offs + i] = src[src_offs + i];\n }\n },\n // Join array of chunks to single array.\n flattenChunks: function (chunks) {\n var i, l, len, pos, chunk, result;\n\n // calculate data length\n len = 0;\n for (i = 0, l = chunks.length; i < l; i++) {\n len += chunks[i].length;\n }\n\n // join chunks\n result = new Uint8Array(len);\n pos = 0;\n for (i = 0, l = chunks.length; i < l; i++) {\n chunk = chunks[i];\n result.set(chunk, pos);\n pos += chunk.length;\n }\n\n return result;\n }\n};\n\nvar fnUntyped = {\n arraySet: function (dest, src, src_offs, len, dest_offs) {\n for (var i = 0; i < len; i++) {\n dest[dest_offs + i] = src[src_offs + i];\n }\n },\n // Join array of chunks to single array.\n flattenChunks: function (chunks) {\n return [].concat.apply([], chunks);\n }\n};\n\n\n// Enable/Disable typed arrays use, for testing\n//\nexports.setTyped = function (on) {\n if (on) {\n exports.Buf8 = Uint8Array;\n exports.Buf16 = Uint16Array;\n exports.Buf32 = Int32Array;\n exports.assign(exports, fnTyped);\n } else {\n exports.Buf8 = Array;\n exports.Buf16 = Array;\n exports.Buf32 = Array;\n exports.assign(exports, fnUntyped);\n }\n};\n\nexports.setTyped(TYPED_OK);\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n/* eslint-disable space-unary-ops */\n\nvar utils = require('../utils/common');\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\n\n//var Z_FILTERED = 1;\n//var Z_HUFFMAN_ONLY = 2;\n//var Z_RLE = 3;\nvar Z_FIXED = 4;\n//var Z_DEFAULT_STRATEGY = 0;\n\n/* Possible values of the data_type field (though see inflate()) */\nvar Z_BINARY = 0;\nvar Z_TEXT = 1;\n//var Z_ASCII = 1; // = Z_TEXT\nvar Z_UNKNOWN = 2;\n\n/*============================================================================*/\n\n\nfunction zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }\n\n// From zutil.h\n\nvar STORED_BLOCK = 0;\nvar STATIC_TREES = 1;\nvar DYN_TREES = 2;\n/* The three kinds of block type */\n\nvar MIN_MATCH = 3;\nvar MAX_MATCH = 258;\n/* The minimum and maximum match lengths */\n\n// From deflate.h\n/* ===========================================================================\n * Internal compression state.\n */\n\nvar LENGTH_CODES = 29;\n/* number of length codes, not counting the special END_BLOCK code */\n\nvar LITERALS = 256;\n/* number of literal bytes 0..255 */\n\nvar L_CODES = LITERALS + 1 + LENGTH_CODES;\n/* number of Literal or Length codes, including the END_BLOCK code */\n\nvar D_CODES = 30;\n/* number of distance codes */\n\nvar BL_CODES = 19;\n/* number of codes used to transfer the bit lengths */\n\nvar HEAP_SIZE = 2 * L_CODES + 1;\n/* maximum heap size */\n\nvar MAX_BITS = 15;\n/* All codes must not exceed MAX_BITS bits */\n\nvar Buf_size = 16;\n/* size of bit buffer in bi_buf */\n\n\n/* ===========================================================================\n * Constants\n */\n\nvar MAX_BL_BITS = 7;\n/* Bit length codes must not exceed MAX_BL_BITS bits */\n\nvar END_BLOCK = 256;\n/* end of block literal code */\n\nvar REP_3_6 = 16;\n/* repeat previous bit length 3-6 times (2 bits of repeat count) */\n\nvar REPZ_3_10 = 17;\n/* repeat a zero length 3-10 times (3 bits of repeat count) */\n\nvar REPZ_11_138 = 18;\n/* repeat a zero length 11-138 times (7 bits of repeat count) */\n\n/* eslint-disable comma-spacing,array-bracket-spacing */\nvar extra_lbits = /* extra bits for each length code */\n [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];\n\nvar extra_dbits = /* extra bits for each distance code */\n [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];\n\nvar extra_blbits = /* extra bits for each bit length code */\n [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];\n\nvar bl_order =\n [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];\n/* eslint-enable comma-spacing,array-bracket-spacing */\n\n/* The lengths of the bit length codes are sent in order of decreasing\n * probability, to avoid transmitting the lengths for unused bit length codes.\n */\n\n/* ===========================================================================\n * Local data. These are initialized only once.\n */\n\n// We pre-fill arrays with 0 to avoid uninitialized gaps\n\nvar DIST_CODE_LEN = 512; /* see definition of array dist_code below */\n\n// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1\nvar static_ltree = new Array((L_CODES + 2) * 2);\nzero(static_ltree);\n/* The static literal tree. Since the bit lengths are imposed, there is no\n * need for the L_CODES extra codes used during heap construction. However\n * The codes 286 and 287 are needed to build a canonical tree (see _tr_init\n * below).\n */\n\nvar static_dtree = new Array(D_CODES * 2);\nzero(static_dtree);\n/* The static distance tree. (Actually a trivial tree since all codes use\n * 5 bits.)\n */\n\nvar _dist_code = new Array(DIST_CODE_LEN);\nzero(_dist_code);\n/* Distance codes. The first 256 values correspond to the distances\n * 3 .. 258, the last 256 values correspond to the top 8 bits of\n * the 15 bit distances.\n */\n\nvar _length_code = new Array(MAX_MATCH - MIN_MATCH + 1);\nzero(_length_code);\n/* length code for each normalized match length (0 == MIN_MATCH) */\n\nvar base_length = new Array(LENGTH_CODES);\nzero(base_length);\n/* First normalized length for each code (0 = MIN_MATCH) */\n\nvar base_dist = new Array(D_CODES);\nzero(base_dist);\n/* First normalized distance for each code (0 = distance of 1) */\n\n\nfunction StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {\n\n this.static_tree = static_tree; /* static tree or NULL */\n this.extra_bits = extra_bits; /* extra bits for each code or NULL */\n this.extra_base = extra_base; /* base index for extra_bits */\n this.elems = elems; /* max number of elements in the tree */\n this.max_length = max_length; /* max bit length for the codes */\n\n // show if `static_tree` has data or dummy - needed for monomorphic objects\n this.has_stree = static_tree && static_tree.length;\n}\n\n\nvar static_l_desc;\nvar static_d_desc;\nvar static_bl_desc;\n\n\nfunction TreeDesc(dyn_tree, stat_desc) {\n this.dyn_tree = dyn_tree; /* the dynamic tree */\n this.max_code = 0; /* largest code with non zero frequency */\n this.stat_desc = stat_desc; /* the corresponding static tree */\n}\n\n\n\nfunction d_code(dist) {\n return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];\n}\n\n\n/* ===========================================================================\n * Output a short LSB first on the stream.\n * IN assertion: there is enough room in pendingBuf.\n */\nfunction put_short(s, w) {\n// put_byte(s, (uch)((w) & 0xff));\n// put_byte(s, (uch)((ush)(w) >> 8));\n s.pending_buf[s.pending++] = (w) & 0xff;\n s.pending_buf[s.pending++] = (w >>> 8) & 0xff;\n}\n\n\n/* ===========================================================================\n * Send a value on a given number of bits.\n * IN assertion: length <= 16 and value fits in length bits.\n */\nfunction send_bits(s, value, length) {\n if (s.bi_valid > (Buf_size - length)) {\n s.bi_buf |= (value << s.bi_valid) & 0xffff;\n put_short(s, s.bi_buf);\n s.bi_buf = value >> (Buf_size - s.bi_valid);\n s.bi_valid += length - Buf_size;\n } else {\n s.bi_buf |= (value << s.bi_valid) & 0xffff;\n s.bi_valid += length;\n }\n}\n\n\nfunction send_code(s, c, tree) {\n send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);\n}\n\n\n/* ===========================================================================\n * Reverse the first len bits of a code, using straightforward code (a faster\n * method would use a table)\n * IN assertion: 1 <= len <= 15\n */\nfunction bi_reverse(code, len) {\n var res = 0;\n do {\n res |= code & 1;\n code >>>= 1;\n res <<= 1;\n } while (--len > 0);\n return res >>> 1;\n}\n\n\n/* ===========================================================================\n * Flush the bit buffer, keeping at most 7 bits in it.\n */\nfunction bi_flush(s) {\n if (s.bi_valid === 16) {\n put_short(s, s.bi_buf);\n s.bi_buf = 0;\n s.bi_valid = 0;\n\n } else if (s.bi_valid >= 8) {\n s.pending_buf[s.pending++] = s.bi_buf & 0xff;\n s.bi_buf >>= 8;\n s.bi_valid -= 8;\n }\n}\n\n\n/* ===========================================================================\n * Compute the optimal bit lengths for a tree and update the total bit length\n * for the current block.\n * IN assertion: the fields freq and dad are set, heap[heap_max] and\n * above are the tree nodes sorted by increasing frequency.\n * OUT assertions: the field len is set to the optimal bit length, the\n * array bl_count contains the frequencies for each bit length.\n * The length opt_len is updated; static_len is also updated if stree is\n * not null.\n */\nfunction gen_bitlen(s, desc)\n// deflate_state *s;\n// tree_desc *desc; /* the tree descriptor */\n{\n var tree = desc.dyn_tree;\n var max_code = desc.max_code;\n var stree = desc.stat_desc.static_tree;\n var has_stree = desc.stat_desc.has_stree;\n var extra = desc.stat_desc.extra_bits;\n var base = desc.stat_desc.extra_base;\n var max_length = desc.stat_desc.max_length;\n var h; /* heap index */\n var n, m; /* iterate over the tree elements */\n var bits; /* bit length */\n var xbits; /* extra bits */\n var f; /* frequency */\n var overflow = 0; /* number of elements with bit length too large */\n\n for (bits = 0; bits <= MAX_BITS; bits++) {\n s.bl_count[bits] = 0;\n }\n\n /* In a first pass, compute the optimal bit lengths (which may\n * overflow in the case of the bit length tree).\n */\n tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */\n\n for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {\n n = s.heap[h];\n bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;\n if (bits > max_length) {\n bits = max_length;\n overflow++;\n }\n tree[n * 2 + 1]/*.Len*/ = bits;\n /* We overwrite tree[n].Dad which is no longer needed */\n\n if (n > max_code) { continue; } /* not a leaf node */\n\n s.bl_count[bits]++;\n xbits = 0;\n if (n >= base) {\n xbits = extra[n - base];\n }\n f = tree[n * 2]/*.Freq*/;\n s.opt_len += f * (bits + xbits);\n if (has_stree) {\n s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);\n }\n }\n if (overflow === 0) { return; }\n\n // Trace((stderr,\"\\nbit length overflow\\n\"));\n /* This happens for example on obj2 and pic of the Calgary corpus */\n\n /* Find the first bit length which could increase: */\n do {\n bits = max_length - 1;\n while (s.bl_count[bits] === 0) { bits--; }\n s.bl_count[bits]--; /* move one leaf down the tree */\n s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */\n s.bl_count[max_length]--;\n /* The brother of the overflow item also moves one step up,\n * but this does not affect bl_count[max_length]\n */\n overflow -= 2;\n } while (overflow > 0);\n\n /* Now recompute all bit lengths, scanning in increasing frequency.\n * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all\n * lengths instead of fixing only the wrong ones. This idea is taken\n * from 'ar' written by Haruhiko Okumura.)\n */\n for (bits = max_length; bits !== 0; bits--) {\n n = s.bl_count[bits];\n while (n !== 0) {\n m = s.heap[--h];\n if (m > max_code) { continue; }\n if (tree[m * 2 + 1]/*.Len*/ !== bits) {\n // Trace((stderr,\"code %d bits %d->%d\\n\", m, tree[m].Len, bits));\n s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;\n tree[m * 2 + 1]/*.Len*/ = bits;\n }\n n--;\n }\n }\n}\n\n\n/* ===========================================================================\n * Generate the codes for a given tree and bit counts (which need not be\n * optimal).\n * IN assertion: the array bl_count contains the bit length statistics for\n * the given tree and the field len is set for all tree elements.\n * OUT assertion: the field code is set for all tree elements of non\n * zero code length.\n */\nfunction gen_codes(tree, max_code, bl_count)\n// ct_data *tree; /* the tree to decorate */\n// int max_code; /* largest code with non zero frequency */\n// ushf *bl_count; /* number of codes at each bit length */\n{\n var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */\n var code = 0; /* running code value */\n var bits; /* bit index */\n var n; /* code index */\n\n /* The distribution counts are first used to generate the code values\n * without bit reversal.\n */\n for (bits = 1; bits <= MAX_BITS; bits++) {\n next_code[bits] = code = (code + bl_count[bits - 1]) << 1;\n }\n /* Check that the bit counts in bl_count are consistent. The last code\n * must be all ones.\n */\n //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */\n length = 0;\n for (code = 0; code < LENGTH_CODES - 1; code++) {\n base_length[code] = length;\n for (n = 0; n < (1 << extra_lbits[code]); n++) {\n _length_code[length++] = code;\n }\n }\n //Assert (length == 256, \"tr_static_init: length != 256\");\n /* Note that the length 255 (match length 258) can be represented\n * in two different ways: code 284 + 5 bits or code 285, so we\n * overwrite length_code[255] to use the best encoding:\n */\n _length_code[length - 1] = code;\n\n /* Initialize the mapping dist (0..32K) -> dist code (0..29) */\n dist = 0;\n for (code = 0; code < 16; code++) {\n base_dist[code] = dist;\n for (n = 0; n < (1 << extra_dbits[code]); n++) {\n _dist_code[dist++] = code;\n }\n }\n //Assert (dist == 256, \"tr_static_init: dist != 256\");\n dist >>= 7; /* from now on, all distances are divided by 128 */\n for (; code < D_CODES; code++) {\n base_dist[code] = dist << 7;\n for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {\n _dist_code[256 + dist++] = code;\n }\n }\n //Assert (dist == 256, \"tr_static_init: 256+dist != 512\");\n\n /* Construct the codes of the static literal tree */\n for (bits = 0; bits <= MAX_BITS; bits++) {\n bl_count[bits] = 0;\n }\n\n n = 0;\n while (n <= 143) {\n static_ltree[n * 2 + 1]/*.Len*/ = 8;\n n++;\n bl_count[8]++;\n }\n while (n <= 255) {\n static_ltree[n * 2 + 1]/*.Len*/ = 9;\n n++;\n bl_count[9]++;\n }\n while (n <= 279) {\n static_ltree[n * 2 + 1]/*.Len*/ = 7;\n n++;\n bl_count[7]++;\n }\n while (n <= 287) {\n static_ltree[n * 2 + 1]/*.Len*/ = 8;\n n++;\n bl_count[8]++;\n }\n /* Codes 286 and 287 do not exist, but we must include them in the\n * tree construction to get a canonical Huffman tree (longest code\n * all ones)\n */\n gen_codes(static_ltree, L_CODES + 1, bl_count);\n\n /* The static distance tree is trivial: */\n for (n = 0; n < D_CODES; n++) {\n static_dtree[n * 2 + 1]/*.Len*/ = 5;\n static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);\n }\n\n // Now data ready and we can init static trees\n static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);\n static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS);\n static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS);\n\n //static_init_done = true;\n}\n\n\n/* ===========================================================================\n * Initialize a new block.\n */\nfunction init_block(s) {\n var n; /* iterates over tree elements */\n\n /* Initialize the trees. */\n for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }\n for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }\n for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }\n\n s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;\n s.opt_len = s.static_len = 0;\n s.last_lit = s.matches = 0;\n}\n\n\n/* ===========================================================================\n * Flush the bit buffer and align the output on a byte boundary\n */\nfunction bi_windup(s)\n{\n if (s.bi_valid > 8) {\n put_short(s, s.bi_buf);\n } else if (s.bi_valid > 0) {\n //put_byte(s, (Byte)s->bi_buf);\n s.pending_buf[s.pending++] = s.bi_buf;\n }\n s.bi_buf = 0;\n s.bi_valid = 0;\n}\n\n/* ===========================================================================\n * Copy a stored block, storing first the length and its\n * one's complement if requested.\n */\nfunction copy_block(s, buf, len, header)\n//DeflateState *s;\n//charf *buf; /* the input data */\n//unsigned len; /* its length */\n//int header; /* true if block header must be written */\n{\n bi_windup(s); /* align on byte boundary */\n\n if (header) {\n put_short(s, len);\n put_short(s, ~len);\n }\n// while (len--) {\n// put_byte(s, *buf++);\n// }\n utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);\n s.pending += len;\n}\n\n/* ===========================================================================\n * Compares to subtrees, using the tree depth as tie breaker when\n * the subtrees have equal frequency. This minimizes the worst case length.\n */\nfunction smaller(tree, n, m, depth) {\n var _n2 = n * 2;\n var _m2 = m * 2;\n return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||\n (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));\n}\n\n/* ===========================================================================\n * Restore the heap property by moving down the tree starting at node k,\n * exchanging a node with the smallest of its two sons if necessary, stopping\n * when the heap property is re-established (each father smaller than its\n * two sons).\n */\nfunction pqdownheap(s, tree, k)\n// deflate_state *s;\n// ct_data *tree; /* the tree to restore */\n// int k; /* node to move down */\n{\n var v = s.heap[k];\n var j = k << 1; /* left son of k */\n while (j <= s.heap_len) {\n /* Set j to the smallest of the two sons: */\n if (j < s.heap_len &&\n smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {\n j++;\n }\n /* Exit if v is smaller than both sons */\n if (smaller(tree, v, s.heap[j], s.depth)) { break; }\n\n /* Exchange v with the smallest son */\n s.heap[k] = s.heap[j];\n k = j;\n\n /* And continue down the tree, setting j to the left son of k */\n j <<= 1;\n }\n s.heap[k] = v;\n}\n\n\n// inlined manually\n// var SMALLEST = 1;\n\n/* ===========================================================================\n * Send the block data compressed using the given Huffman trees\n */\nfunction compress_block(s, ltree, dtree)\n// deflate_state *s;\n// const ct_data *ltree; /* literal tree */\n// const ct_data *dtree; /* distance tree */\n{\n var dist; /* distance of matched string */\n var lc; /* match length or unmatched char (if dist == 0) */\n var lx = 0; /* running index in l_buf */\n var code; /* the code to send */\n var extra; /* number of extra bits to send */\n\n if (s.last_lit !== 0) {\n do {\n dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);\n lc = s.pending_buf[s.l_buf + lx];\n lx++;\n\n if (dist === 0) {\n send_code(s, lc, ltree); /* send a literal byte */\n //Tracecv(isgraph(lc), (stderr,\" '%c' \", lc));\n } else {\n /* Here, lc is the match length - MIN_MATCH */\n code = _length_code[lc];\n send_code(s, code + LITERALS + 1, ltree); /* send the length code */\n extra = extra_lbits[code];\n if (extra !== 0) {\n lc -= base_length[code];\n send_bits(s, lc, extra); /* send the extra length bits */\n }\n dist--; /* dist is now the match distance - 1 */\n code = d_code(dist);\n //Assert (code < D_CODES, \"bad d_code\");\n\n send_code(s, code, dtree); /* send the distance code */\n extra = extra_dbits[code];\n if (extra !== 0) {\n dist -= base_dist[code];\n send_bits(s, dist, extra); /* send the extra distance bits */\n }\n } /* literal or match pair ? */\n\n /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */\n //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,\n // \"pendingBuf overflow\");\n\n } while (lx < s.last_lit);\n }\n\n send_code(s, END_BLOCK, ltree);\n}\n\n\n/* ===========================================================================\n * Construct one Huffman tree and assigns the code bit strings and lengths.\n * Update the total bit length for the current block.\n * IN assertion: the field freq is set for all tree elements.\n * OUT assertions: the fields len and code are set to the optimal bit length\n * and corresponding code. The length opt_len is updated; static_len is\n * also updated if stree is not null. The field max_code is set.\n */\nfunction build_tree(s, desc)\n// deflate_state *s;\n// tree_desc *desc; /* the tree descriptor */\n{\n var tree = desc.dyn_tree;\n var stree = desc.stat_desc.static_tree;\n var has_stree = desc.stat_desc.has_stree;\n var elems = desc.stat_desc.elems;\n var n, m; /* iterate over heap elements */\n var max_code = -1; /* largest code with non zero frequency */\n var node; /* new node being created */\n\n /* Construct the initial heap, with least frequent element in\n * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].\n * heap[0] is not used.\n */\n s.heap_len = 0;\n s.heap_max = HEAP_SIZE;\n\n for (n = 0; n < elems; n++) {\n if (tree[n * 2]/*.Freq*/ !== 0) {\n s.heap[++s.heap_len] = max_code = n;\n s.depth[n] = 0;\n\n } else {\n tree[n * 2 + 1]/*.Len*/ = 0;\n }\n }\n\n /* The pkzip format requires that at least one distance code exists,\n * and that at least one bit should be sent even if there is only one\n * possible code. So to avoid special checks later on we force at least\n * two codes of non zero frequency.\n */\n while (s.heap_len < 2) {\n node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);\n tree[node * 2]/*.Freq*/ = 1;\n s.depth[node] = 0;\n s.opt_len--;\n\n if (has_stree) {\n s.static_len -= stree[node * 2 + 1]/*.Len*/;\n }\n /* node is 0 or 1 so it does not have extra bits */\n }\n desc.max_code = max_code;\n\n /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,\n * establish sub-heaps of increasing lengths:\n */\n for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }\n\n /* Construct the Huffman tree by repeatedly combining the least two\n * frequent nodes.\n */\n node = elems; /* next internal node of the tree */\n do {\n //pqremove(s, tree, n); /* n = node of least frequency */\n /*** pqremove ***/\n n = s.heap[1/*SMALLEST*/];\n s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];\n pqdownheap(s, tree, 1/*SMALLEST*/);\n /***/\n\n m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */\n\n s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */\n s.heap[--s.heap_max] = m;\n\n /* Create a new node father of n and m */\n tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;\n s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;\n tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;\n\n /* and insert the new node in the heap */\n s.heap[1/*SMALLEST*/] = node++;\n pqdownheap(s, tree, 1/*SMALLEST*/);\n\n } while (s.heap_len >= 2);\n\n s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];\n\n /* At this point, the fields freq and dad are set. We can now\n * generate the bit lengths.\n */\n gen_bitlen(s, desc);\n\n /* The field len is now set, we can generate the bit codes */\n gen_codes(tree, max_code, s.bl_count);\n}\n\n\n/* ===========================================================================\n * Scan a literal or distance tree to determine the frequencies of the codes\n * in the bit length tree.\n */\nfunction scan_tree(s, tree, max_code)\n// deflate_state *s;\n// ct_data *tree; /* the tree to be scanned */\n// int max_code; /* and its largest code of non zero frequency */\n{\n var n; /* iterates over all tree elements */\n var prevlen = -1; /* last emitted length */\n var curlen; /* length of current code */\n\n var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */\n\n var count = 0; /* repeat count of the current code */\n var max_count = 7; /* max repeat count */\n var min_count = 4; /* min repeat count */\n\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n }\n tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */\n\n for (n = 0; n <= max_code; n++) {\n curlen = nextlen;\n nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;\n\n if (++count < max_count && curlen === nextlen) {\n continue;\n\n } else if (count < min_count) {\n s.bl_tree[curlen * 2]/*.Freq*/ += count;\n\n } else if (curlen !== 0) {\n\n if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }\n s.bl_tree[REP_3_6 * 2]/*.Freq*/++;\n\n } else if (count <= 10) {\n s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;\n\n } else {\n s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;\n }\n\n count = 0;\n prevlen = curlen;\n\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n\n } else if (curlen === nextlen) {\n max_count = 6;\n min_count = 3;\n\n } else {\n max_count = 7;\n min_count = 4;\n }\n }\n}\n\n\n/* ===========================================================================\n * Send a literal or distance tree in compressed form, using the codes in\n * bl_tree.\n */\nfunction send_tree(s, tree, max_code)\n// deflate_state *s;\n// ct_data *tree; /* the tree to be scanned */\n// int max_code; /* and its largest code of non zero frequency */\n{\n var n; /* iterates over all tree elements */\n var prevlen = -1; /* last emitted length */\n var curlen; /* length of current code */\n\n var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */\n\n var count = 0; /* repeat count of the current code */\n var max_count = 7; /* max repeat count */\n var min_count = 4; /* min repeat count */\n\n /* tree[max_code+1].Len = -1; */ /* guard already set */\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n }\n\n for (n = 0; n <= max_code; n++) {\n curlen = nextlen;\n nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;\n\n if (++count < max_count && curlen === nextlen) {\n continue;\n\n } else if (count < min_count) {\n do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);\n\n } else if (curlen !== 0) {\n if (curlen !== prevlen) {\n send_code(s, curlen, s.bl_tree);\n count--;\n }\n //Assert(count >= 3 && count <= 6, \" 3_6?\");\n send_code(s, REP_3_6, s.bl_tree);\n send_bits(s, count - 3, 2);\n\n } else if (count <= 10) {\n send_code(s, REPZ_3_10, s.bl_tree);\n send_bits(s, count - 3, 3);\n\n } else {\n send_code(s, REPZ_11_138, s.bl_tree);\n send_bits(s, count - 11, 7);\n }\n\n count = 0;\n prevlen = curlen;\n if (nextlen === 0) {\n max_count = 138;\n min_count = 3;\n\n } else if (curlen === nextlen) {\n max_count = 6;\n min_count = 3;\n\n } else {\n max_count = 7;\n min_count = 4;\n }\n }\n}\n\n\n/* ===========================================================================\n * Construct the Huffman tree for the bit lengths and return the index in\n * bl_order of the last bit length code to send.\n */\nfunction build_bl_tree(s) {\n var max_blindex; /* index of last bit length code of non zero freq */\n\n /* Determine the bit length frequencies for literal and distance trees */\n scan_tree(s, s.dyn_ltree, s.l_desc.max_code);\n scan_tree(s, s.dyn_dtree, s.d_desc.max_code);\n\n /* Build the bit length tree: */\n build_tree(s, s.bl_desc);\n /* opt_len now includes the length of the tree representations, except\n * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.\n */\n\n /* Determine the number of bit length codes to send. The pkzip format\n * requires that at least 4 bit length codes be sent. (appnote.txt says\n * 3 but the actual value used is 4.)\n */\n for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {\n if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {\n break;\n }\n }\n /* Update opt_len to include the bit length tree and counts */\n s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;\n //Tracev((stderr, \"\\ndyn trees: dyn %ld, stat %ld\",\n // s->opt_len, s->static_len));\n\n return max_blindex;\n}\n\n\n/* ===========================================================================\n * Send the header for a block using dynamic Huffman trees: the counts, the\n * lengths of the bit length codes, the literal tree and the distance tree.\n * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.\n */\nfunction send_all_trees(s, lcodes, dcodes, blcodes)\n// deflate_state *s;\n// int lcodes, dcodes, blcodes; /* number of codes for each tree */\n{\n var rank; /* index in bl_order */\n\n //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, \"not enough codes\");\n //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,\n // \"too many codes\");\n //Tracev((stderr, \"\\nbl counts: \"));\n send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */\n send_bits(s, dcodes - 1, 5);\n send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */\n for (rank = 0; rank < blcodes; rank++) {\n //Tracev((stderr, \"\\nbl code %2d \", bl_order[rank]));\n send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);\n }\n //Tracev((stderr, \"\\nbl tree: sent %ld\", s->bits_sent));\n\n send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */\n //Tracev((stderr, \"\\nlit tree: sent %ld\", s->bits_sent));\n\n send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */\n //Tracev((stderr, \"\\ndist tree: sent %ld\", s->bits_sent));\n}\n\n\n/* ===========================================================================\n * Check if the data type is TEXT or BINARY, using the following algorithm:\n * - TEXT if the two conditions below are satisfied:\n * a) There are no non-portable control characters belonging to the\n * \"black list\" (0..6, 14..25, 28..31).\n * b) There is at least one printable character belonging to the\n * \"white list\" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).\n * - BINARY otherwise.\n * - The following partially-portable control characters form a\n * \"gray list\" that is ignored in this detection algorithm:\n * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).\n * IN assertion: the fields Freq of dyn_ltree are set.\n */\nfunction detect_data_type(s) {\n /* black_mask is the bit mask of black-listed bytes\n * set bits 0..6, 14..25, and 28..31\n * 0xf3ffc07f = binary 11110011111111111100000001111111\n */\n var black_mask = 0xf3ffc07f;\n var n;\n\n /* Check for non-textual (\"black-listed\") bytes. */\n for (n = 0; n <= 31; n++, black_mask >>>= 1) {\n if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {\n return Z_BINARY;\n }\n }\n\n /* Check for textual (\"white-listed\") bytes. */\n if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||\n s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {\n return Z_TEXT;\n }\n for (n = 32; n < LITERALS; n++) {\n if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {\n return Z_TEXT;\n }\n }\n\n /* There are no \"black-listed\" or \"white-listed\" bytes:\n * this stream either is empty or has tolerated (\"gray-listed\") bytes only.\n */\n return Z_BINARY;\n}\n\n\nvar static_init_done = false;\n\n/* ===========================================================================\n * Initialize the tree data structures for a new zlib stream.\n */\nfunction _tr_init(s)\n{\n\n if (!static_init_done) {\n tr_static_init();\n static_init_done = true;\n }\n\n s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);\n s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);\n s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);\n\n s.bi_buf = 0;\n s.bi_valid = 0;\n\n /* Initialize the first block of the first file: */\n init_block(s);\n}\n\n\n/* ===========================================================================\n * Send a stored block\n */\nfunction _tr_stored_block(s, buf, stored_len, last)\n//DeflateState *s;\n//charf *buf; /* input block */\n//ulg stored_len; /* length of input block */\n//int last; /* one if this is the last block for a file */\n{\n send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */\n copy_block(s, buf, stored_len, true); /* with header */\n}\n\n\n/* ===========================================================================\n * Send one empty static block to give enough lookahead for inflate.\n * This takes 10 bits, of which 7 may remain in the bit buffer.\n */\nfunction _tr_align(s) {\n send_bits(s, STATIC_TREES << 1, 3);\n send_code(s, END_BLOCK, static_ltree);\n bi_flush(s);\n}\n\n\n/* ===========================================================================\n * Determine the best encoding for the current block: dynamic trees, static\n * trees or store, and output the encoded block to the zip file.\n */\nfunction _tr_flush_block(s, buf, stored_len, last)\n//DeflateState *s;\n//charf *buf; /* input block, or NULL if too old */\n//ulg stored_len; /* length of input block */\n//int last; /* one if this is the last block for a file */\n{\n var opt_lenb, static_lenb; /* opt_len and static_len in bytes */\n var max_blindex = 0; /* index of last bit length code of non zero freq */\n\n /* Build the Huffman trees unless a stored block is forced */\n if (s.level > 0) {\n\n /* Check if the file is binary or text */\n if (s.strm.data_type === Z_UNKNOWN) {\n s.strm.data_type = detect_data_type(s);\n }\n\n /* Construct the literal and distance trees */\n build_tree(s, s.l_desc);\n // Tracev((stderr, \"\\nlit data: dyn %ld, stat %ld\", s->opt_len,\n // s->static_len));\n\n build_tree(s, s.d_desc);\n // Tracev((stderr, \"\\ndist data: dyn %ld, stat %ld\", s->opt_len,\n // s->static_len));\n /* At this point, opt_len and static_len are the total bit lengths of\n * the compressed block data, excluding the tree representations.\n */\n\n /* Build the bit length tree for the above two trees, and get the index\n * in bl_order of the last bit length code to send.\n */\n max_blindex = build_bl_tree(s);\n\n /* Determine the best encoding. Compute the block lengths in bytes. */\n opt_lenb = (s.opt_len + 3 + 7) >>> 3;\n static_lenb = (s.static_len + 3 + 7) >>> 3;\n\n // Tracev((stderr, \"\\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u \",\n // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,\n // s->last_lit));\n\n if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }\n\n } else {\n // Assert(buf != (char*)0, \"lost buf\");\n opt_lenb = static_lenb = stored_len + 5; /* force a stored block */\n }\n\n if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {\n /* 4: two words for the lengths */\n\n /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.\n * Otherwise we can't have processed more than WSIZE input bytes since\n * the last block flush, because compression would have been\n * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to\n * transform a block into a stored block.\n */\n _tr_stored_block(s, buf, stored_len, last);\n\n } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {\n\n send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);\n compress_block(s, static_ltree, static_dtree);\n\n } else {\n send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);\n send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);\n compress_block(s, s.dyn_ltree, s.dyn_dtree);\n }\n // Assert (s->compressed_len == s->bits_sent, \"bad compressed size\");\n /* The above check is made mod 2^32, for files larger than 512 MB\n * and uLong implemented on 32 bits.\n */\n init_block(s);\n\n if (last) {\n bi_windup(s);\n }\n // Tracev((stderr,\"\\ncomprlen %lu(%lu) \", s->compressed_len>>3,\n // s->compressed_len-7*last));\n}\n\n/* ===========================================================================\n * Save the match info and tally the frequency counts. Return true if\n * the current block must be flushed.\n */\nfunction _tr_tally(s, dist, lc)\n// deflate_state *s;\n// unsigned dist; /* distance of matched string */\n// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */\n{\n //var out_length, in_length, dcode;\n\n s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff;\n s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;\n\n s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;\n s.last_lit++;\n\n if (dist === 0) {\n /* lc is the unmatched char */\n s.dyn_ltree[lc * 2]/*.Freq*/++;\n } else {\n s.matches++;\n /* Here, lc is the match length - MIN_MATCH */\n dist--; /* dist = match distance - 1 */\n //Assert((ush)dist < (ush)MAX_DIST(s) &&\n // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&\n // (ush)d_code(dist) < (ush)D_CODES, \"_tr_tally: bad match\");\n\n s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;\n s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;\n }\n\n// (!) This block is disabled in zlib defaults,\n// don't enable it for binary compatibility\n\n//#ifdef TRUNCATE_BLOCK\n// /* Try to guess if it is profitable to stop the current block here */\n// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {\n// /* Compute an upper bound for the compressed length */\n// out_length = s.last_lit*8;\n// in_length = s.strstart - s.block_start;\n//\n// for (dcode = 0; dcode < D_CODES; dcode++) {\n// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);\n// }\n// out_length >>>= 3;\n// //Tracev((stderr,\"\\nlast_lit %u, in %ld, out ~%ld(%ld%%) \",\n// // s->last_lit, in_length, out_length,\n// // 100L - out_length*100L/in_length));\n// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {\n// return true;\n// }\n// }\n//#endif\n\n return (s.last_lit === s.lit_bufsize - 1);\n /* We avoid equality with lit_bufsize because of wraparound at 64K\n * on 16 bit machines and because stored blocks are restricted to\n * 64K-1 bytes.\n */\n}\n\nexports._tr_init = _tr_init;\nexports._tr_stored_block = _tr_stored_block;\nexports._tr_flush_block = _tr_flush_block;\nexports._tr_tally = _tr_tally;\nexports._tr_align = _tr_align;\n","'use strict';\n\n// Note: adler32 takes 12% for level 0 and 2% for level 6.\n// It isn't worth it to make additional optimizations as in original.\n// Small size is preferable.\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nfunction adler32(adler, buf, len, pos) {\n var s1 = (adler & 0xffff) |0,\n s2 = ((adler >>> 16) & 0xffff) |0,\n n = 0;\n\n while (len !== 0) {\n // Set limit ~ twice less than 5552, to keep\n // s2 in 31-bits, because we force signed ints.\n // in other case %= will fail.\n n = len > 2000 ? 2000 : len;\n len -= n;\n\n do {\n s1 = (s1 + buf[pos++]) |0;\n s2 = (s2 + s1) |0;\n } while (--n);\n\n s1 %= 65521;\n s2 %= 65521;\n }\n\n return (s1 | (s2 << 16)) |0;\n}\n\n\nmodule.exports = adler32;\n","'use strict';\n\n// Note: we can't get significant speed boost here.\n// So write code to minimize size - no pregenerated tables\n// and array tools dependencies.\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n// Use ordinary array, since untyped makes no boost here\nfunction makeTable() {\n var c, table = [];\n\n for (var n = 0; n < 256; n++) {\n c = n;\n for (var k = 0; k < 8; k++) {\n c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));\n }\n table[n] = c;\n }\n\n return table;\n}\n\n// Create table on load. Just 255 signed longs. Not a problem.\nvar crcTable = makeTable();\n\n\nfunction crc32(crc, buf, len, pos) {\n var t = crcTable,\n end = pos + len;\n\n crc ^= -1;\n\n for (var i = pos; i < end; i++) {\n crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];\n }\n\n return (crc ^ (-1)); // >>> 0;\n}\n\n\nmodule.exports = crc32;\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nvar utils = require('../utils/common');\nvar trees = require('./trees');\nvar adler32 = require('./adler32');\nvar crc32 = require('./crc32');\nvar msg = require('./messages');\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\n\n/* Allowed flush values; see deflate() and inflate() below for details */\nvar Z_NO_FLUSH = 0;\nvar Z_PARTIAL_FLUSH = 1;\n//var Z_SYNC_FLUSH = 2;\nvar Z_FULL_FLUSH = 3;\nvar Z_FINISH = 4;\nvar Z_BLOCK = 5;\n//var Z_TREES = 6;\n\n\n/* Return codes for the compression/decompression functions. Negative values\n * are errors, positive values are used for special but normal events.\n */\nvar Z_OK = 0;\nvar Z_STREAM_END = 1;\n//var Z_NEED_DICT = 2;\n//var Z_ERRNO = -1;\nvar Z_STREAM_ERROR = -2;\nvar Z_DATA_ERROR = -3;\n//var Z_MEM_ERROR = -4;\nvar Z_BUF_ERROR = -5;\n//var Z_VERSION_ERROR = -6;\n\n\n/* compression levels */\n//var Z_NO_COMPRESSION = 0;\n//var Z_BEST_SPEED = 1;\n//var Z_BEST_COMPRESSION = 9;\nvar Z_DEFAULT_COMPRESSION = -1;\n\n\nvar Z_FILTERED = 1;\nvar Z_HUFFMAN_ONLY = 2;\nvar Z_RLE = 3;\nvar Z_FIXED = 4;\nvar Z_DEFAULT_STRATEGY = 0;\n\n/* Possible values of the data_type field (though see inflate()) */\n//var Z_BINARY = 0;\n//var Z_TEXT = 1;\n//var Z_ASCII = 1; // = Z_TEXT\nvar Z_UNKNOWN = 2;\n\n\n/* The deflate compression method */\nvar Z_DEFLATED = 8;\n\n/*============================================================================*/\n\n\nvar MAX_MEM_LEVEL = 9;\n/* Maximum value for memLevel in deflateInit2 */\nvar MAX_WBITS = 15;\n/* 32K LZ77 window */\nvar DEF_MEM_LEVEL = 8;\n\n\nvar LENGTH_CODES = 29;\n/* number of length codes, not counting the special END_BLOCK code */\nvar LITERALS = 256;\n/* number of literal bytes 0..255 */\nvar L_CODES = LITERALS + 1 + LENGTH_CODES;\n/* number of Literal or Length codes, including the END_BLOCK code */\nvar D_CODES = 30;\n/* number of distance codes */\nvar BL_CODES = 19;\n/* number of codes used to transfer the bit lengths */\nvar HEAP_SIZE = 2 * L_CODES + 1;\n/* maximum heap size */\nvar MAX_BITS = 15;\n/* All codes must not exceed MAX_BITS bits */\n\nvar MIN_MATCH = 3;\nvar MAX_MATCH = 258;\nvar MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);\n\nvar PRESET_DICT = 0x20;\n\nvar INIT_STATE = 42;\nvar EXTRA_STATE = 69;\nvar NAME_STATE = 73;\nvar COMMENT_STATE = 91;\nvar HCRC_STATE = 103;\nvar BUSY_STATE = 113;\nvar FINISH_STATE = 666;\n\nvar BS_NEED_MORE = 1; /* block not completed, need more input or more output */\nvar BS_BLOCK_DONE = 2; /* block flush performed */\nvar BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */\nvar BS_FINISH_DONE = 4; /* finish done, accept no more input or output */\n\nvar OS_CODE = 0x03; // Unix :) . Don't detect, use this default.\n\nfunction err(strm, errorCode) {\n strm.msg = msg[errorCode];\n return errorCode;\n}\n\nfunction rank(f) {\n return ((f) << 1) - ((f) > 4 ? 9 : 0);\n}\n\nfunction zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }\n\n\n/* =========================================================================\n * Flush as much pending output as possible. All deflate() output goes\n * through this function so some applications may wish to modify it\n * to avoid allocating a large strm->output buffer and copying into it.\n * (See also read_buf()).\n */\nfunction flush_pending(strm) {\n var s = strm.state;\n\n //_tr_flush_bits(s);\n var len = s.pending;\n if (len > strm.avail_out) {\n len = strm.avail_out;\n }\n if (len === 0) { return; }\n\n utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);\n strm.next_out += len;\n s.pending_out += len;\n strm.total_out += len;\n strm.avail_out -= len;\n s.pending -= len;\n if (s.pending === 0) {\n s.pending_out = 0;\n }\n}\n\n\nfunction flush_block_only(s, last) {\n trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);\n s.block_start = s.strstart;\n flush_pending(s.strm);\n}\n\n\nfunction put_byte(s, b) {\n s.pending_buf[s.pending++] = b;\n}\n\n\n/* =========================================================================\n * Put a short in the pending buffer. The 16-bit value is put in MSB order.\n * IN assertion: the stream state is correct and there is enough room in\n * pending_buf.\n */\nfunction putShortMSB(s, b) {\n// put_byte(s, (Byte)(b >> 8));\n// put_byte(s, (Byte)(b & 0xff));\n s.pending_buf[s.pending++] = (b >>> 8) & 0xff;\n s.pending_buf[s.pending++] = b & 0xff;\n}\n\n\n/* ===========================================================================\n * Read a new buffer from the current input stream, update the adler32\n * and total number of bytes read. All deflate() input goes through\n * this function so some applications may wish to modify it to avoid\n * allocating a large strm->input buffer and copying from it.\n * (See also flush_pending()).\n */\nfunction read_buf(strm, buf, start, size) {\n var len = strm.avail_in;\n\n if (len > size) { len = size; }\n if (len === 0) { return 0; }\n\n strm.avail_in -= len;\n\n // zmemcpy(buf, strm->next_in, len);\n utils.arraySet(buf, strm.input, strm.next_in, len, start);\n if (strm.state.wrap === 1) {\n strm.adler = adler32(strm.adler, buf, len, start);\n }\n\n else if (strm.state.wrap === 2) {\n strm.adler = crc32(strm.adler, buf, len, start);\n }\n\n strm.next_in += len;\n strm.total_in += len;\n\n return len;\n}\n\n\n/* ===========================================================================\n * Set match_start to the longest match starting at the given string and\n * return its length. Matches shorter or equal to prev_length are discarded,\n * in which case the result is equal to prev_length and match_start is\n * garbage.\n * IN assertions: cur_match is the head of the hash chain for the current\n * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1\n * OUT assertion: the match length is not greater than s->lookahead.\n */\nfunction longest_match(s, cur_match) {\n var chain_length = s.max_chain_length; /* max hash chain length */\n var scan = s.strstart; /* current string */\n var match; /* matched string */\n var len; /* length of current match */\n var best_len = s.prev_length; /* best match length so far */\n var nice_match = s.nice_match; /* stop if match long enough */\n var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?\n s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;\n\n var _win = s.window; // shortcut\n\n var wmask = s.w_mask;\n var prev = s.prev;\n\n /* Stop when cur_match becomes <= limit. To simplify the code,\n * we prevent matches with the string of window index 0.\n */\n\n var strend = s.strstart + MAX_MATCH;\n var scan_end1 = _win[scan + best_len - 1];\n var scan_end = _win[scan + best_len];\n\n /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.\n * It is easy to get rid of this optimization if necessary.\n */\n // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, \"Code too clever\");\n\n /* Do not waste too much time if we already have a good match: */\n if (s.prev_length >= s.good_match) {\n chain_length >>= 2;\n }\n /* Do not look for matches beyond the end of the input. This is necessary\n * to make deflate deterministic.\n */\n if (nice_match > s.lookahead) { nice_match = s.lookahead; }\n\n // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, \"need lookahead\");\n\n do {\n // Assert(cur_match < s->strstart, \"no future\");\n match = cur_match;\n\n /* Skip to next match if the match length cannot increase\n * or if the match length is less than 2. Note that the checks below\n * for insufficient lookahead only occur occasionally for performance\n * reasons. Therefore uninitialized memory will be accessed, and\n * conditional jumps will be made that depend on those values.\n * However the length of the match is limited to the lookahead, so\n * the output of deflate is not affected by the uninitialized values.\n */\n\n if (_win[match + best_len] !== scan_end ||\n _win[match + best_len - 1] !== scan_end1 ||\n _win[match] !== _win[scan] ||\n _win[++match] !== _win[scan + 1]) {\n continue;\n }\n\n /* The check at best_len-1 can be removed because it will be made\n * again later. (This heuristic is not always a win.)\n * It is not necessary to compare scan[2] and match[2] since they\n * are always equal when the other bytes match, given that\n * the hash keys are equal and that HASH_BITS >= 8.\n */\n scan += 2;\n match++;\n // Assert(*scan == *match, \"match[2]?\");\n\n /* We check for insufficient lookahead only every 8th comparison;\n * the 256th check will be made at strstart+258.\n */\n do {\n /*jshint noempty:false*/\n } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&\n scan < strend);\n\n // Assert(scan <= s->window+(unsigned)(s->window_size-1), \"wild scan\");\n\n len = MAX_MATCH - (strend - scan);\n scan = strend - MAX_MATCH;\n\n if (len > best_len) {\n s.match_start = cur_match;\n best_len = len;\n if (len >= nice_match) {\n break;\n }\n scan_end1 = _win[scan + best_len - 1];\n scan_end = _win[scan + best_len];\n }\n } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);\n\n if (best_len <= s.lookahead) {\n return best_len;\n }\n return s.lookahead;\n}\n\n\n/* ===========================================================================\n * Fill the window when the lookahead becomes insufficient.\n * Updates strstart and lookahead.\n *\n * IN assertion: lookahead < MIN_LOOKAHEAD\n * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD\n * At least one byte has been read, or avail_in == 0; reads are\n * performed for at least two bytes (required for the zip translate_eol\n * option -- not supported here).\n */\nfunction fill_window(s) {\n var _w_size = s.w_size;\n var p, n, m, more, str;\n\n //Assert(s->lookahead < MIN_LOOKAHEAD, \"already enough lookahead\");\n\n do {\n more = s.window_size - s.lookahead - s.strstart;\n\n // JS ints have 32 bit, block below not needed\n /* Deal with !@#$% 64K limit: */\n //if (sizeof(int) <= 2) {\n // if (more == 0 && s->strstart == 0 && s->lookahead == 0) {\n // more = wsize;\n //\n // } else if (more == (unsigned)(-1)) {\n // /* Very unlikely, but possible on 16 bit machine if\n // * strstart == 0 && lookahead == 1 (input done a byte at time)\n // */\n // more--;\n // }\n //}\n\n\n /* If the window is almost full and there is insufficient lookahead,\n * move the upper half to the lower one to make room in the upper half.\n */\n if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {\n\n utils.arraySet(s.window, s.window, _w_size, _w_size, 0);\n s.match_start -= _w_size;\n s.strstart -= _w_size;\n /* we now have strstart >= MAX_DIST */\n s.block_start -= _w_size;\n\n /* Slide the hash table (could be avoided with 32 bit values\n at the expense of memory usage). We slide even when level == 0\n to keep the hash table consistent if we switch back to level > 0\n later. (Using level 0 permanently is not an optimal usage of\n zlib, so we don't care about this pathological case.)\n */\n\n n = s.hash_size;\n p = n;\n do {\n m = s.head[--p];\n s.head[p] = (m >= _w_size ? m - _w_size : 0);\n } while (--n);\n\n n = _w_size;\n p = n;\n do {\n m = s.prev[--p];\n s.prev[p] = (m >= _w_size ? m - _w_size : 0);\n /* If n is not on any hash chain, prev[n] is garbage but\n * its value will never be used.\n */\n } while (--n);\n\n more += _w_size;\n }\n if (s.strm.avail_in === 0) {\n break;\n }\n\n /* If there was no sliding:\n * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&\n * more == window_size - lookahead - strstart\n * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)\n * => more >= window_size - 2*WSIZE + 2\n * In the BIG_MEM or MMAP case (not yet supported),\n * window_size == input_size + MIN_LOOKAHEAD &&\n * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.\n * Otherwise, window_size == 2*WSIZE so more >= 2.\n * If there was sliding, more >= WSIZE. So in all cases, more >= 2.\n */\n //Assert(more >= 2, \"more < 2\");\n n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);\n s.lookahead += n;\n\n /* Initialize the hash value now that we have some input: */\n if (s.lookahead + s.insert >= MIN_MATCH) {\n str = s.strstart - s.insert;\n s.ins_h = s.window[str];\n\n /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;\n//#if MIN_MATCH != 3\n// Call update_hash() MIN_MATCH-3 more times\n//#endif\n while (s.insert) {\n /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;\n\n s.prev[str & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = str;\n str++;\n s.insert--;\n if (s.lookahead + s.insert < MIN_MATCH) {\n break;\n }\n }\n }\n /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,\n * but this is not important since only literal bytes will be emitted.\n */\n\n } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);\n\n /* If the WIN_INIT bytes after the end of the current data have never been\n * written, then zero those bytes in order to avoid memory check reports of\n * the use of uninitialized (or uninitialised as Julian writes) bytes by\n * the longest match routines. Update the high water mark for the next\n * time through here. WIN_INIT is set to MAX_MATCH since the longest match\n * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.\n */\n// if (s.high_water < s.window_size) {\n// var curr = s.strstart + s.lookahead;\n// var init = 0;\n//\n// if (s.high_water < curr) {\n// /* Previous high water mark below current data -- zero WIN_INIT\n// * bytes or up to end of window, whichever is less.\n// */\n// init = s.window_size - curr;\n// if (init > WIN_INIT)\n// init = WIN_INIT;\n// zmemzero(s->window + curr, (unsigned)init);\n// s->high_water = curr + init;\n// }\n// else if (s->high_water < (ulg)curr + WIN_INIT) {\n// /* High water mark at or above current data, but below current data\n// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up\n// * to end of window, whichever is less.\n// */\n// init = (ulg)curr + WIN_INIT - s->high_water;\n// if (init > s->window_size - s->high_water)\n// init = s->window_size - s->high_water;\n// zmemzero(s->window + s->high_water, (unsigned)init);\n// s->high_water += init;\n// }\n// }\n//\n// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,\n// \"not enough room for search\");\n}\n\n/* ===========================================================================\n * Copy without compression as much as possible from the input stream, return\n * the current block state.\n * This function does not insert new strings in the dictionary since\n * uncompressible data is probably not useful. This function is used\n * only for the level=0 compression option.\n * NOTE: this function should be optimized to avoid extra copying from\n * window to pending_buf.\n */\nfunction deflate_stored(s, flush) {\n /* Stored blocks are limited to 0xffff bytes, pending_buf is limited\n * to pending_buf_size, and each stored block has a 5 byte header:\n */\n var max_block_size = 0xffff;\n\n if (max_block_size > s.pending_buf_size - 5) {\n max_block_size = s.pending_buf_size - 5;\n }\n\n /* Copy as much as possible from input to output: */\n for (;;) {\n /* Fill the window as much as possible: */\n if (s.lookahead <= 1) {\n\n //Assert(s->strstart < s->w_size+MAX_DIST(s) ||\n // s->block_start >= (long)s->w_size, \"slide too late\");\n// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||\n// s.block_start >= s.w_size)) {\n// throw new Error(\"slide too late\");\n// }\n\n fill_window(s);\n if (s.lookahead === 0 && flush === Z_NO_FLUSH) {\n return BS_NEED_MORE;\n }\n\n if (s.lookahead === 0) {\n break;\n }\n /* flush the current block */\n }\n //Assert(s->block_start >= 0L, \"block gone\");\n// if (s.block_start < 0) throw new Error(\"block gone\");\n\n s.strstart += s.lookahead;\n s.lookahead = 0;\n\n /* Emit a stored block if pending_buf will be full: */\n var max_start = s.block_start + max_block_size;\n\n if (s.strstart === 0 || s.strstart >= max_start) {\n /* strstart == 0 is possible when wraparound on 16-bit machine */\n s.lookahead = s.strstart - max_start;\n s.strstart = max_start;\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n\n\n }\n /* Flush if we may have to slide, otherwise block_start may become\n * negative and the data will be gone:\n */\n if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n\n s.insert = 0;\n\n if (flush === Z_FINISH) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n\n if (s.strstart > s.block_start) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n\n return BS_NEED_MORE;\n}\n\n/* ===========================================================================\n * Compress as much as possible from the input stream, return the current\n * block state.\n * This function does not perform lazy evaluation of matches and inserts\n * new strings in the dictionary only for unmatched strings or for short\n * matches. It is used only for the fast compression options.\n */\nfunction deflate_fast(s, flush) {\n var hash_head; /* head of the hash chain */\n var bflush; /* set if current block must be flushed */\n\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the next match, plus MIN_MATCH bytes to insert the\n * string following the next match.\n */\n if (s.lookahead < MIN_LOOKAHEAD) {\n fill_window(s);\n if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) {\n break; /* flush the current block */\n }\n }\n\n /* Insert the string window[strstart .. strstart+2] in the\n * dictionary, and set hash_head to the head of the hash chain:\n */\n hash_head = 0/*NIL*/;\n if (s.lookahead >= MIN_MATCH) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n\n /* Find the longest match, discarding those <= prev_length.\n * At this point we have always match_length < MIN_MATCH\n */\n if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {\n /* To simplify the code, we prevent matches with the string\n * of window index 0 (in particular we have to avoid a match\n * of the string with itself at the start of the input file).\n */\n s.match_length = longest_match(s, hash_head);\n /* longest_match() sets match_start */\n }\n if (s.match_length >= MIN_MATCH) {\n // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only\n\n /*** _tr_tally_dist(s, s.strstart - s.match_start,\n s.match_length - MIN_MATCH, bflush); ***/\n bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);\n\n s.lookahead -= s.match_length;\n\n /* Insert new strings in the hash table only if the match length\n * is not too large. This saves time but degrades compression.\n */\n if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {\n s.match_length--; /* string at strstart already in table */\n do {\n s.strstart++;\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n /* strstart never exceeds WSIZE-MAX_MATCH, so there are\n * always MIN_MATCH bytes ahead.\n */\n } while (--s.match_length !== 0);\n s.strstart++;\n } else\n {\n s.strstart += s.match_length;\n s.match_length = 0;\n s.ins_h = s.window[s.strstart];\n /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;\n\n//#if MIN_MATCH != 3\n// Call UPDATE_HASH() MIN_MATCH-3 more times\n//#endif\n /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not\n * matter since it will be recomputed at next deflate call.\n */\n }\n } else {\n /* No match, output a literal byte */\n //Tracevv((stderr,\"%c\", s.window[s.strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = trees._tr_tally(s, 0, s.window[s.strstart]);\n\n s.lookahead--;\n s.strstart++;\n }\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);\n if (flush === Z_FINISH) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.last_lit) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n}\n\n/* ===========================================================================\n * Same as above, but achieves better compression. We use a lazy\n * evaluation for matches: a match is finally adopted only if there is\n * no better match at the next window position.\n */\nfunction deflate_slow(s, flush) {\n var hash_head; /* head of hash chain */\n var bflush; /* set if current block must be flushed */\n\n var max_insert;\n\n /* Process the input block. */\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the next match, plus MIN_MATCH bytes to insert the\n * string following the next match.\n */\n if (s.lookahead < MIN_LOOKAHEAD) {\n fill_window(s);\n if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) { break; } /* flush the current block */\n }\n\n /* Insert the string window[strstart .. strstart+2] in the\n * dictionary, and set hash_head to the head of the hash chain:\n */\n hash_head = 0/*NIL*/;\n if (s.lookahead >= MIN_MATCH) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n\n /* Find the longest match, discarding those <= prev_length.\n */\n s.prev_length = s.match_length;\n s.prev_match = s.match_start;\n s.match_length = MIN_MATCH - 1;\n\n if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&\n s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {\n /* To simplify the code, we prevent matches with the string\n * of window index 0 (in particular we have to avoid a match\n * of the string with itself at the start of the input file).\n */\n s.match_length = longest_match(s, hash_head);\n /* longest_match() sets match_start */\n\n if (s.match_length <= 5 &&\n (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {\n\n /* If prev_match is also MIN_MATCH, match_start is garbage\n * but we will ignore the current match anyway.\n */\n s.match_length = MIN_MATCH - 1;\n }\n }\n /* If there was a match at the previous step and the current\n * match is not better, output the previous match:\n */\n if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {\n max_insert = s.strstart + s.lookahead - MIN_MATCH;\n /* Do not insert strings in hash table beyond this. */\n\n //check_match(s, s.strstart-1, s.prev_match, s.prev_length);\n\n /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,\n s.prev_length - MIN_MATCH, bflush);***/\n bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);\n /* Insert in hash table all strings up to the end of the match.\n * strstart-1 and strstart are already inserted. If there is not\n * enough lookahead, the last two strings are not inserted in\n * the hash table.\n */\n s.lookahead -= s.prev_length - 1;\n s.prev_length -= 2;\n do {\n if (++s.strstart <= max_insert) {\n /*** INSERT_STRING(s, s.strstart, hash_head); ***/\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;\n hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];\n s.head[s.ins_h] = s.strstart;\n /***/\n }\n } while (--s.prev_length !== 0);\n s.match_available = 0;\n s.match_length = MIN_MATCH - 1;\n s.strstart++;\n\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n\n } else if (s.match_available) {\n /* If there was no match at the previous position, output a\n * single literal. If there was a match but the current match\n * is longer, truncate the previous match to a single literal.\n */\n //Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/\n bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);\n\n if (bflush) {\n /*** FLUSH_BLOCK_ONLY(s, 0) ***/\n flush_block_only(s, false);\n /***/\n }\n s.strstart++;\n s.lookahead--;\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n } else {\n /* There is no previous match to compare with, wait for\n * the next step to decide.\n */\n s.match_available = 1;\n s.strstart++;\n s.lookahead--;\n }\n }\n //Assert (flush != Z_NO_FLUSH, \"no flush?\");\n if (s.match_available) {\n //Tracevv((stderr,\"%c\", s->window[s->strstart-1]));\n /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/\n bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);\n\n s.match_available = 0;\n }\n s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;\n if (flush === Z_FINISH) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.last_lit) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n\n return BS_BLOCK_DONE;\n}\n\n\n/* ===========================================================================\n * For Z_RLE, simply look for runs of bytes, generate matches only of distance\n * one. Do not maintain a hash table. (It will be regenerated if this run of\n * deflate switches away from Z_RLE.)\n */\nfunction deflate_rle(s, flush) {\n var bflush; /* set if current block must be flushed */\n var prev; /* byte at distance one to match */\n var scan, strend; /* scan goes up to strend for length of run */\n\n var _win = s.window;\n\n for (;;) {\n /* Make sure that we always have enough lookahead, except\n * at the end of the input file. We need MAX_MATCH bytes\n * for the longest run, plus one for the unrolled loop.\n */\n if (s.lookahead <= MAX_MATCH) {\n fill_window(s);\n if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {\n return BS_NEED_MORE;\n }\n if (s.lookahead === 0) { break; } /* flush the current block */\n }\n\n /* See how many times the previous byte repeats */\n s.match_length = 0;\n if (s.lookahead >= MIN_MATCH && s.strstart > 0) {\n scan = s.strstart - 1;\n prev = _win[scan];\n if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {\n strend = s.strstart + MAX_MATCH;\n do {\n /*jshint noempty:false*/\n } while (prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n prev === _win[++scan] && prev === _win[++scan] &&\n scan < strend);\n s.match_length = MAX_MATCH - (strend - scan);\n if (s.match_length > s.lookahead) {\n s.match_length = s.lookahead;\n }\n }\n //Assert(scan <= s->window+(uInt)(s->window_size-1), \"wild scan\");\n }\n\n /* Emit match if have run of MIN_MATCH or longer, else emit literal */\n if (s.match_length >= MIN_MATCH) {\n //check_match(s, s.strstart, s.strstart - 1, s.match_length);\n\n /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/\n bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);\n\n s.lookahead -= s.match_length;\n s.strstart += s.match_length;\n s.match_length = 0;\n } else {\n /* No match, output a literal byte */\n //Tracevv((stderr,\"%c\", s->window[s->strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = trees._tr_tally(s, 0, s.window[s.strstart]);\n\n s.lookahead--;\n s.strstart++;\n }\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = 0;\n if (flush === Z_FINISH) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.last_lit) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n}\n\n/* ===========================================================================\n * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.\n * (It will be regenerated if this run of deflate switches away from Huffman.)\n */\nfunction deflate_huff(s, flush) {\n var bflush; /* set if current block must be flushed */\n\n for (;;) {\n /* Make sure that we have a literal to write. */\n if (s.lookahead === 0) {\n fill_window(s);\n if (s.lookahead === 0) {\n if (flush === Z_NO_FLUSH) {\n return BS_NEED_MORE;\n }\n break; /* flush the current block */\n }\n }\n\n /* Output a literal byte */\n s.match_length = 0;\n //Tracevv((stderr,\"%c\", s->window[s->strstart]));\n /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/\n bflush = trees._tr_tally(s, 0, s.window[s.strstart]);\n s.lookahead--;\n s.strstart++;\n if (bflush) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n }\n s.insert = 0;\n if (flush === Z_FINISH) {\n /*** FLUSH_BLOCK(s, 1); ***/\n flush_block_only(s, true);\n if (s.strm.avail_out === 0) {\n return BS_FINISH_STARTED;\n }\n /***/\n return BS_FINISH_DONE;\n }\n if (s.last_lit) {\n /*** FLUSH_BLOCK(s, 0); ***/\n flush_block_only(s, false);\n if (s.strm.avail_out === 0) {\n return BS_NEED_MORE;\n }\n /***/\n }\n return BS_BLOCK_DONE;\n}\n\n/* Values for max_lazy_match, good_match and max_chain_length, depending on\n * the desired pack level (0..9). The values given below have been tuned to\n * exclude worst case performance for pathological files. Better values may be\n * found for specific files.\n */\nfunction Config(good_length, max_lazy, nice_length, max_chain, func) {\n this.good_length = good_length;\n this.max_lazy = max_lazy;\n this.nice_length = nice_length;\n this.max_chain = max_chain;\n this.func = func;\n}\n\nvar configuration_table;\n\nconfiguration_table = [\n /* good lazy nice chain */\n new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */\n new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */\n new Config(4, 5, 16, 8, deflate_fast), /* 2 */\n new Config(4, 6, 32, 32, deflate_fast), /* 3 */\n\n new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */\n new Config(8, 16, 32, 32, deflate_slow), /* 5 */\n new Config(8, 16, 128, 128, deflate_slow), /* 6 */\n new Config(8, 32, 128, 256, deflate_slow), /* 7 */\n new Config(32, 128, 258, 1024, deflate_slow), /* 8 */\n new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */\n];\n\n\n/* ===========================================================================\n * Initialize the \"longest match\" routines for a new zlib stream\n */\nfunction lm_init(s) {\n s.window_size = 2 * s.w_size;\n\n /*** CLEAR_HASH(s); ***/\n zero(s.head); // Fill with NIL (= 0);\n\n /* Set the default configuration parameters:\n */\n s.max_lazy_match = configuration_table[s.level].max_lazy;\n s.good_match = configuration_table[s.level].good_length;\n s.nice_match = configuration_table[s.level].nice_length;\n s.max_chain_length = configuration_table[s.level].max_chain;\n\n s.strstart = 0;\n s.block_start = 0;\n s.lookahead = 0;\n s.insert = 0;\n s.match_length = s.prev_length = MIN_MATCH - 1;\n s.match_available = 0;\n s.ins_h = 0;\n}\n\n\nfunction DeflateState() {\n this.strm = null; /* pointer back to this zlib stream */\n this.status = 0; /* as the name implies */\n this.pending_buf = null; /* output still pending */\n this.pending_buf_size = 0; /* size of pending_buf */\n this.pending_out = 0; /* next pending byte to output to the stream */\n this.pending = 0; /* nb of bytes in the pending buffer */\n this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */\n this.gzhead = null; /* gzip header information to write */\n this.gzindex = 0; /* where in extra, name, or comment */\n this.method = Z_DEFLATED; /* can only be DEFLATED */\n this.last_flush = -1; /* value of flush param for previous deflate call */\n\n this.w_size = 0; /* LZ77 window size (32K by default) */\n this.w_bits = 0; /* log2(w_size) (8..16) */\n this.w_mask = 0; /* w_size - 1 */\n\n this.window = null;\n /* Sliding window. Input bytes are read into the second half of the window,\n * and move to the first half later to keep a dictionary of at least wSize\n * bytes. With this organization, matches are limited to a distance of\n * wSize-MAX_MATCH bytes, but this ensures that IO is always\n * performed with a length multiple of the block size.\n */\n\n this.window_size = 0;\n /* Actual size of window: 2*wSize, except when the user input buffer\n * is directly used as sliding window.\n */\n\n this.prev = null;\n /* Link to older string with same hash index. To limit the size of this\n * array to 64K, this link is maintained only for the last 32K strings.\n * An index in this array is thus a window index modulo 32K.\n */\n\n this.head = null; /* Heads of the hash chains or NIL. */\n\n this.ins_h = 0; /* hash index of string to be inserted */\n this.hash_size = 0; /* number of elements in hash table */\n this.hash_bits = 0; /* log2(hash_size) */\n this.hash_mask = 0; /* hash_size-1 */\n\n this.hash_shift = 0;\n /* Number of bits by which ins_h must be shifted at each input\n * step. It must be such that after MIN_MATCH steps, the oldest\n * byte no longer takes part in the hash key, that is:\n * hash_shift * MIN_MATCH >= hash_bits\n */\n\n this.block_start = 0;\n /* Window position at the beginning of the current output block. Gets\n * negative when the window is moved backwards.\n */\n\n this.match_length = 0; /* length of best match */\n this.prev_match = 0; /* previous match */\n this.match_available = 0; /* set if previous match exists */\n this.strstart = 0; /* start of string to insert */\n this.match_start = 0; /* start of matching string */\n this.lookahead = 0; /* number of valid bytes ahead in window */\n\n this.prev_length = 0;\n /* Length of the best match at previous step. Matches not greater than this\n * are discarded. This is used in the lazy match evaluation.\n */\n\n this.max_chain_length = 0;\n /* To speed up deflation, hash chains are never searched beyond this\n * length. A higher limit improves compression ratio but degrades the\n * speed.\n */\n\n this.max_lazy_match = 0;\n /* Attempt to find a better match only when the current match is strictly\n * smaller than this value. This mechanism is used only for compression\n * levels >= 4.\n */\n // That's alias to max_lazy_match, don't use directly\n //this.max_insert_length = 0;\n /* Insert new strings in the hash table only if the match length is not\n * greater than this length. This saves time but degrades compression.\n * max_insert_length is used only for compression levels <= 3.\n */\n\n this.level = 0; /* compression level (1..9) */\n this.strategy = 0; /* favor or force Huffman coding*/\n\n this.good_match = 0;\n /* Use a faster search when the previous match is longer than this */\n\n this.nice_match = 0; /* Stop searching when current match exceeds this */\n\n /* used by trees.c: */\n\n /* Didn't use ct_data typedef below to suppress compiler warning */\n\n // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */\n // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */\n // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */\n\n // Use flat array of DOUBLE size, with interleaved fata,\n // because JS does not support effective\n this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2);\n this.dyn_dtree = new utils.Buf16((2 * D_CODES + 1) * 2);\n this.bl_tree = new utils.Buf16((2 * BL_CODES + 1) * 2);\n zero(this.dyn_ltree);\n zero(this.dyn_dtree);\n zero(this.bl_tree);\n\n this.l_desc = null; /* desc. for literal tree */\n this.d_desc = null; /* desc. for distance tree */\n this.bl_desc = null; /* desc. for bit length tree */\n\n //ush bl_count[MAX_BITS+1];\n this.bl_count = new utils.Buf16(MAX_BITS + 1);\n /* number of codes at each bit length for an optimal tree */\n\n //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */\n this.heap = new utils.Buf16(2 * L_CODES + 1); /* heap used to build the Huffman trees */\n zero(this.heap);\n\n this.heap_len = 0; /* number of elements in the heap */\n this.heap_max = 0; /* element of largest frequency */\n /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.\n * The same heap array is used to build all trees.\n */\n\n this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];\n zero(this.depth);\n /* Depth of each subtree used as tie breaker for trees of equal frequency\n */\n\n this.l_buf = 0; /* buffer index for literals or lengths */\n\n this.lit_bufsize = 0;\n /* Size of match buffer for literals/lengths. There are 4 reasons for\n * limiting lit_bufsize to 64K:\n * - frequencies can be kept in 16 bit counters\n * - if compression is not successful for the first block, all input\n * data is still in the window so we can still emit a stored block even\n * when input comes from standard input. (This can also be done for\n * all blocks if lit_bufsize is not greater than 32K.)\n * - if compression is not successful for a file smaller than 64K, we can\n * even emit a stored file instead of a stored block (saving 5 bytes).\n * This is applicable only for zip (not gzip or zlib).\n * - creating new Huffman trees less frequently may not provide fast\n * adaptation to changes in the input data statistics. (Take for\n * example a binary file with poorly compressible code followed by\n * a highly compressible string table.) Smaller buffer sizes give\n * fast adaptation but have of course the overhead of transmitting\n * trees more frequently.\n * - I can't count above 4\n */\n\n this.last_lit = 0; /* running index in l_buf */\n\n this.d_buf = 0;\n /* Buffer index for distances. To simplify the code, d_buf and l_buf have\n * the same number of elements. To use different lengths, an extra flag\n * array would be necessary.\n */\n\n this.opt_len = 0; /* bit length of current block with optimal trees */\n this.static_len = 0; /* bit length of current block with static trees */\n this.matches = 0; /* number of string matches in current block */\n this.insert = 0; /* bytes at end of window left to insert */\n\n\n this.bi_buf = 0;\n /* Output buffer. bits are inserted starting at the bottom (least\n * significant bits).\n */\n this.bi_valid = 0;\n /* Number of valid bits in bi_buf. All bits above the last valid bit\n * are always zero.\n */\n\n // Used for window memory init. We safely ignore it for JS. That makes\n // sense only for pointers and memory check tools.\n //this.high_water = 0;\n /* High water mark offset in window for initialized bytes -- bytes above\n * this are set to zero in order to avoid memory check warnings when\n * longest match routines access bytes past the input. This is then\n * updated to the new high water mark.\n */\n}\n\n\nfunction deflateResetKeep(strm) {\n var s;\n\n if (!strm || !strm.state) {\n return err(strm, Z_STREAM_ERROR);\n }\n\n strm.total_in = strm.total_out = 0;\n strm.data_type = Z_UNKNOWN;\n\n s = strm.state;\n s.pending = 0;\n s.pending_out = 0;\n\n if (s.wrap < 0) {\n s.wrap = -s.wrap;\n /* was made negative by deflate(..., Z_FINISH); */\n }\n s.status = (s.wrap ? INIT_STATE : BUSY_STATE);\n strm.adler = (s.wrap === 2) ?\n 0 // crc32(0, Z_NULL, 0)\n :\n 1; // adler32(0, Z_NULL, 0)\n s.last_flush = Z_NO_FLUSH;\n trees._tr_init(s);\n return Z_OK;\n}\n\n\nfunction deflateReset(strm) {\n var ret = deflateResetKeep(strm);\n if (ret === Z_OK) {\n lm_init(strm.state);\n }\n return ret;\n}\n\n\nfunction deflateSetHeader(strm, head) {\n if (!strm || !strm.state) { return Z_STREAM_ERROR; }\n if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }\n strm.state.gzhead = head;\n return Z_OK;\n}\n\n\nfunction deflateInit2(strm, level, method, windowBits, memLevel, strategy) {\n if (!strm) { // === Z_NULL\n return Z_STREAM_ERROR;\n }\n var wrap = 1;\n\n if (level === Z_DEFAULT_COMPRESSION) {\n level = 6;\n }\n\n if (windowBits < 0) { /* suppress zlib wrapper */\n wrap = 0;\n windowBits = -windowBits;\n }\n\n else if (windowBits > 15) {\n wrap = 2; /* write gzip wrapper instead */\n windowBits -= 16;\n }\n\n\n if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||\n windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||\n strategy < 0 || strategy > Z_FIXED) {\n return err(strm, Z_STREAM_ERROR);\n }\n\n\n if (windowBits === 8) {\n windowBits = 9;\n }\n /* until 256-byte window bug fixed */\n\n var s = new DeflateState();\n\n strm.state = s;\n s.strm = strm;\n\n s.wrap = wrap;\n s.gzhead = null;\n s.w_bits = windowBits;\n s.w_size = 1 << s.w_bits;\n s.w_mask = s.w_size - 1;\n\n s.hash_bits = memLevel + 7;\n s.hash_size = 1 << s.hash_bits;\n s.hash_mask = s.hash_size - 1;\n s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);\n\n s.window = new utils.Buf8(s.w_size * 2);\n s.head = new utils.Buf16(s.hash_size);\n s.prev = new utils.Buf16(s.w_size);\n\n // Don't need mem init magic for JS.\n //s.high_water = 0; /* nothing written to s->window yet */\n\n s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */\n\n s.pending_buf_size = s.lit_bufsize * 4;\n\n //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);\n //s->pending_buf = (uchf *) overlay;\n s.pending_buf = new utils.Buf8(s.pending_buf_size);\n\n // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)\n //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);\n s.d_buf = 1 * s.lit_bufsize;\n\n //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;\n s.l_buf = (1 + 2) * s.lit_bufsize;\n\n s.level = level;\n s.strategy = strategy;\n s.method = method;\n\n return deflateReset(strm);\n}\n\nfunction deflateInit(strm, level) {\n return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);\n}\n\n\nfunction deflate(strm, flush) {\n var old_flush, s;\n var beg, val; // for gzip header write only\n\n if (!strm || !strm.state ||\n flush > Z_BLOCK || flush < 0) {\n return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;\n }\n\n s = strm.state;\n\n if (!strm.output ||\n (!strm.input && strm.avail_in !== 0) ||\n (s.status === FINISH_STATE && flush !== Z_FINISH)) {\n return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);\n }\n\n s.strm = strm; /* just in case */\n old_flush = s.last_flush;\n s.last_flush = flush;\n\n /* Write the header */\n if (s.status === INIT_STATE) {\n\n if (s.wrap === 2) { // GZIP header\n strm.adler = 0; //crc32(0L, Z_NULL, 0);\n put_byte(s, 31);\n put_byte(s, 139);\n put_byte(s, 8);\n if (!s.gzhead) { // s->gzhead == Z_NULL\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, 0);\n put_byte(s, s.level === 9 ? 2 :\n (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?\n 4 : 0));\n put_byte(s, OS_CODE);\n s.status = BUSY_STATE;\n }\n else {\n put_byte(s, (s.gzhead.text ? 1 : 0) +\n (s.gzhead.hcrc ? 2 : 0) +\n (!s.gzhead.extra ? 0 : 4) +\n (!s.gzhead.name ? 0 : 8) +\n (!s.gzhead.comment ? 0 : 16)\n );\n put_byte(s, s.gzhead.time & 0xff);\n put_byte(s, (s.gzhead.time >> 8) & 0xff);\n put_byte(s, (s.gzhead.time >> 16) & 0xff);\n put_byte(s, (s.gzhead.time >> 24) & 0xff);\n put_byte(s, s.level === 9 ? 2 :\n (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?\n 4 : 0));\n put_byte(s, s.gzhead.os & 0xff);\n if (s.gzhead.extra && s.gzhead.extra.length) {\n put_byte(s, s.gzhead.extra.length & 0xff);\n put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);\n }\n if (s.gzhead.hcrc) {\n strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);\n }\n s.gzindex = 0;\n s.status = EXTRA_STATE;\n }\n }\n else // DEFLATE header\n {\n var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;\n var level_flags = -1;\n\n if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {\n level_flags = 0;\n } else if (s.level < 6) {\n level_flags = 1;\n } else if (s.level === 6) {\n level_flags = 2;\n } else {\n level_flags = 3;\n }\n header |= (level_flags << 6);\n if (s.strstart !== 0) { header |= PRESET_DICT; }\n header += 31 - (header % 31);\n\n s.status = BUSY_STATE;\n putShortMSB(s, header);\n\n /* Save the adler32 of the preset dictionary: */\n if (s.strstart !== 0) {\n putShortMSB(s, strm.adler >>> 16);\n putShortMSB(s, strm.adler & 0xffff);\n }\n strm.adler = 1; // adler32(0L, Z_NULL, 0);\n }\n }\n\n//#ifdef GZIP\n if (s.status === EXTRA_STATE) {\n if (s.gzhead.extra/* != Z_NULL*/) {\n beg = s.pending; /* start of bytes to update crc */\n\n while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {\n if (s.pending === s.pending_buf_size) {\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n flush_pending(strm);\n beg = s.pending;\n if (s.pending === s.pending_buf_size) {\n break;\n }\n }\n put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);\n s.gzindex++;\n }\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n if (s.gzindex === s.gzhead.extra.length) {\n s.gzindex = 0;\n s.status = NAME_STATE;\n }\n }\n else {\n s.status = NAME_STATE;\n }\n }\n if (s.status === NAME_STATE) {\n if (s.gzhead.name/* != Z_NULL*/) {\n beg = s.pending; /* start of bytes to update crc */\n //int val;\n\n do {\n if (s.pending === s.pending_buf_size) {\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n flush_pending(strm);\n beg = s.pending;\n if (s.pending === s.pending_buf_size) {\n val = 1;\n break;\n }\n }\n // JS specific: little magic to add zero terminator to end of string\n if (s.gzindex < s.gzhead.name.length) {\n val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;\n } else {\n val = 0;\n }\n put_byte(s, val);\n } while (val !== 0);\n\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n if (val === 0) {\n s.gzindex = 0;\n s.status = COMMENT_STATE;\n }\n }\n else {\n s.status = COMMENT_STATE;\n }\n }\n if (s.status === COMMENT_STATE) {\n if (s.gzhead.comment/* != Z_NULL*/) {\n beg = s.pending; /* start of bytes to update crc */\n //int val;\n\n do {\n if (s.pending === s.pending_buf_size) {\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n flush_pending(strm);\n beg = s.pending;\n if (s.pending === s.pending_buf_size) {\n val = 1;\n break;\n }\n }\n // JS specific: little magic to add zero terminator to end of string\n if (s.gzindex < s.gzhead.comment.length) {\n val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;\n } else {\n val = 0;\n }\n put_byte(s, val);\n } while (val !== 0);\n\n if (s.gzhead.hcrc && s.pending > beg) {\n strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);\n }\n if (val === 0) {\n s.status = HCRC_STATE;\n }\n }\n else {\n s.status = HCRC_STATE;\n }\n }\n if (s.status === HCRC_STATE) {\n if (s.gzhead.hcrc) {\n if (s.pending + 2 > s.pending_buf_size) {\n flush_pending(strm);\n }\n if (s.pending + 2 <= s.pending_buf_size) {\n put_byte(s, strm.adler & 0xff);\n put_byte(s, (strm.adler >> 8) & 0xff);\n strm.adler = 0; //crc32(0L, Z_NULL, 0);\n s.status = BUSY_STATE;\n }\n }\n else {\n s.status = BUSY_STATE;\n }\n }\n//#endif\n\n /* Flush as much pending output as possible */\n if (s.pending !== 0) {\n flush_pending(strm);\n if (strm.avail_out === 0) {\n /* Since avail_out is 0, deflate will be called again with\n * more output space, but possibly with both pending and\n * avail_in equal to zero. There won't be anything to do,\n * but this is not an error situation so make sure we\n * return OK instead of BUF_ERROR at next call of deflate:\n */\n s.last_flush = -1;\n return Z_OK;\n }\n\n /* Make sure there is something to do and avoid duplicate consecutive\n * flushes. For repeated and useless calls with Z_FINISH, we keep\n * returning Z_STREAM_END instead of Z_BUF_ERROR.\n */\n } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&\n flush !== Z_FINISH) {\n return err(strm, Z_BUF_ERROR);\n }\n\n /* User must not provide more input after the first FINISH: */\n if (s.status === FINISH_STATE && strm.avail_in !== 0) {\n return err(strm, Z_BUF_ERROR);\n }\n\n /* Start a new block or continue the current one.\n */\n if (strm.avail_in !== 0 || s.lookahead !== 0 ||\n (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {\n var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :\n (s.strategy === Z_RLE ? deflate_rle(s, flush) :\n configuration_table[s.level].func(s, flush));\n\n if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {\n s.status = FINISH_STATE;\n }\n if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {\n if (strm.avail_out === 0) {\n s.last_flush = -1;\n /* avoid BUF_ERROR next call, see above */\n }\n return Z_OK;\n /* If flush != Z_NO_FLUSH && avail_out == 0, the next call\n * of deflate should use the same flush parameter to make sure\n * that the flush is complete. So we don't have to output an\n * empty block here, this will be done at next call. This also\n * ensures that for a very small output buffer, we emit at most\n * one empty block.\n */\n }\n if (bstate === BS_BLOCK_DONE) {\n if (flush === Z_PARTIAL_FLUSH) {\n trees._tr_align(s);\n }\n else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */\n\n trees._tr_stored_block(s, 0, 0, false);\n /* For a full flush, this empty block will be recognized\n * as a special marker by inflate_sync().\n */\n if (flush === Z_FULL_FLUSH) {\n /*** CLEAR_HASH(s); ***/ /* forget history */\n zero(s.head); // Fill with NIL (= 0);\n\n if (s.lookahead === 0) {\n s.strstart = 0;\n s.block_start = 0;\n s.insert = 0;\n }\n }\n }\n flush_pending(strm);\n if (strm.avail_out === 0) {\n s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */\n return Z_OK;\n }\n }\n }\n //Assert(strm->avail_out > 0, \"bug2\");\n //if (strm.avail_out <= 0) { throw new Error(\"bug2\");}\n\n if (flush !== Z_FINISH) { return Z_OK; }\n if (s.wrap <= 0) { return Z_STREAM_END; }\n\n /* Write the trailer */\n if (s.wrap === 2) {\n put_byte(s, strm.adler & 0xff);\n put_byte(s, (strm.adler >> 8) & 0xff);\n put_byte(s, (strm.adler >> 16) & 0xff);\n put_byte(s, (strm.adler >> 24) & 0xff);\n put_byte(s, strm.total_in & 0xff);\n put_byte(s, (strm.total_in >> 8) & 0xff);\n put_byte(s, (strm.total_in >> 16) & 0xff);\n put_byte(s, (strm.total_in >> 24) & 0xff);\n }\n else\n {\n putShortMSB(s, strm.adler >>> 16);\n putShortMSB(s, strm.adler & 0xffff);\n }\n\n flush_pending(strm);\n /* If avail_out is zero, the application will call deflate again\n * to flush the rest.\n */\n if (s.wrap > 0) { s.wrap = -s.wrap; }\n /* write the trailer only once! */\n return s.pending !== 0 ? Z_OK : Z_STREAM_END;\n}\n\nfunction deflateEnd(strm) {\n var status;\n\n if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {\n return Z_STREAM_ERROR;\n }\n\n status = strm.state.status;\n if (status !== INIT_STATE &&\n status !== EXTRA_STATE &&\n status !== NAME_STATE &&\n status !== COMMENT_STATE &&\n status !== HCRC_STATE &&\n status !== BUSY_STATE &&\n status !== FINISH_STATE\n ) {\n return err(strm, Z_STREAM_ERROR);\n }\n\n strm.state = null;\n\n return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;\n}\n\n\n/* =========================================================================\n * Initializes the compression dictionary from the given byte\n * sequence without producing any compressed output.\n */\nfunction deflateSetDictionary(strm, dictionary) {\n var dictLength = dictionary.length;\n\n var s;\n var str, n;\n var wrap;\n var avail;\n var next;\n var input;\n var tmpDict;\n\n if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {\n return Z_STREAM_ERROR;\n }\n\n s = strm.state;\n wrap = s.wrap;\n\n if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {\n return Z_STREAM_ERROR;\n }\n\n /* when using zlib wrappers, compute Adler-32 for provided dictionary */\n if (wrap === 1) {\n /* adler32(strm->adler, dictionary, dictLength); */\n strm.adler = adler32(strm.adler, dictionary, dictLength, 0);\n }\n\n s.wrap = 0; /* avoid computing Adler-32 in read_buf */\n\n /* if dictionary would fill window, just replace the history */\n if (dictLength >= s.w_size) {\n if (wrap === 0) { /* already empty otherwise */\n /*** CLEAR_HASH(s); ***/\n zero(s.head); // Fill with NIL (= 0);\n s.strstart = 0;\n s.block_start = 0;\n s.insert = 0;\n }\n /* use the tail */\n // dictionary = dictionary.slice(dictLength - s.w_size);\n tmpDict = new utils.Buf8(s.w_size);\n utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);\n dictionary = tmpDict;\n dictLength = s.w_size;\n }\n /* insert dictionary into window and hash */\n avail = strm.avail_in;\n next = strm.next_in;\n input = strm.input;\n strm.avail_in = dictLength;\n strm.next_in = 0;\n strm.input = dictionary;\n fill_window(s);\n while (s.lookahead >= MIN_MATCH) {\n str = s.strstart;\n n = s.lookahead - (MIN_MATCH - 1);\n do {\n /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */\n s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;\n\n s.prev[str & s.w_mask] = s.head[s.ins_h];\n\n s.head[s.ins_h] = str;\n str++;\n } while (--n);\n s.strstart = str;\n s.lookahead = MIN_MATCH - 1;\n fill_window(s);\n }\n s.strstart += s.lookahead;\n s.block_start = s.strstart;\n s.insert = s.lookahead;\n s.lookahead = 0;\n s.match_length = s.prev_length = MIN_MATCH - 1;\n s.match_available = 0;\n strm.next_in = next;\n strm.input = input;\n strm.avail_in = avail;\n s.wrap = wrap;\n return Z_OK;\n}\n\n\nexports.deflateInit = deflateInit;\nexports.deflateInit2 = deflateInit2;\nexports.deflateReset = deflateReset;\nexports.deflateResetKeep = deflateResetKeep;\nexports.deflateSetHeader = deflateSetHeader;\nexports.deflate = deflate;\nexports.deflateEnd = deflateEnd;\nexports.deflateSetDictionary = deflateSetDictionary;\nexports.deflateInfo = 'pako deflate (from Nodeca project)';\n\n/* Not implemented\nexports.deflateBound = deflateBound;\nexports.deflateCopy = deflateCopy;\nexports.deflateParams = deflateParams;\nexports.deflatePending = deflatePending;\nexports.deflatePrime = deflatePrime;\nexports.deflateTune = deflateTune;\n*/\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nmodule.exports = {\n 2: 'need dictionary', /* Z_NEED_DICT 2 */\n 1: 'stream end', /* Z_STREAM_END 1 */\n 0: '', /* Z_OK 0 */\n '-1': 'file error', /* Z_ERRNO (-1) */\n '-2': 'stream error', /* Z_STREAM_ERROR (-2) */\n '-3': 'data error', /* Z_DATA_ERROR (-3) */\n '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */\n '-5': 'buffer error', /* Z_BUF_ERROR (-5) */\n '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */\n};\n","// String encode/decode helpers\n'use strict';\n\n\nvar utils = require('./common');\n\n\n// Quick check if we can use fast array to bin string conversion\n//\n// - apply(Array) can fail on Android 2.2\n// - apply(Uint8Array) can fail on iOS 5.1 Safari\n//\nvar STR_APPLY_OK = true;\nvar STR_APPLY_UIA_OK = true;\n\ntry { String.fromCharCode.apply(null, [ 0 ]); } catch (__) { STR_APPLY_OK = false; }\ntry { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; }\n\n\n// Table with utf8 lengths (calculated by first byte of sequence)\n// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,\n// because max possible codepoint is 0x10ffff\nvar _utf8len = new utils.Buf8(256);\nfor (var q = 0; q < 256; q++) {\n _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);\n}\n_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start\n\n\n// convert string to array (typed, when possible)\nexports.string2buf = function (str) {\n var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;\n\n // count binary size\n for (m_pos = 0; m_pos < str_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 0xfc00) === 0xdc00) {\n c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n m_pos++;\n }\n }\n buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;\n }\n\n // allocate buffer\n buf = new utils.Buf8(buf_len);\n\n // convert\n for (i = 0, m_pos = 0; i < buf_len; m_pos++) {\n c = str.charCodeAt(m_pos);\n if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {\n c2 = str.charCodeAt(m_pos + 1);\n if ((c2 & 0xfc00) === 0xdc00) {\n c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);\n m_pos++;\n }\n }\n if (c < 0x80) {\n /* one byte */\n buf[i++] = c;\n } else if (c < 0x800) {\n /* two bytes */\n buf[i++] = 0xC0 | (c >>> 6);\n buf[i++] = 0x80 | (c & 0x3f);\n } else if (c < 0x10000) {\n /* three bytes */\n buf[i++] = 0xE0 | (c >>> 12);\n buf[i++] = 0x80 | (c >>> 6 & 0x3f);\n buf[i++] = 0x80 | (c & 0x3f);\n } else {\n /* four bytes */\n buf[i++] = 0xf0 | (c >>> 18);\n buf[i++] = 0x80 | (c >>> 12 & 0x3f);\n buf[i++] = 0x80 | (c >>> 6 & 0x3f);\n buf[i++] = 0x80 | (c & 0x3f);\n }\n }\n\n return buf;\n};\n\n// Helper (used in 2 places)\nfunction buf2binstring(buf, len) {\n // On Chrome, the arguments in a function call that are allowed is `65534`.\n // If the length of the buffer is smaller than that, we can use this optimization,\n // otherwise we will take a slower path.\n if (len < 65534) {\n if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) {\n return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len));\n }\n }\n\n var result = '';\n for (var i = 0; i < len; i++) {\n result += String.fromCharCode(buf[i]);\n }\n return result;\n}\n\n\n// Convert byte array to binary string\nexports.buf2binstring = function (buf) {\n return buf2binstring(buf, buf.length);\n};\n\n\n// Convert binary string (typed, when possible)\nexports.binstring2buf = function (str) {\n var buf = new utils.Buf8(str.length);\n for (var i = 0, len = buf.length; i < len; i++) {\n buf[i] = str.charCodeAt(i);\n }\n return buf;\n};\n\n\n// convert array to string\nexports.buf2string = function (buf, max) {\n var i, out, c, c_len;\n var len = max || buf.length;\n\n // Reserve max possible length (2 words per char)\n // NB: by unknown reasons, Array is significantly faster for\n // String.fromCharCode.apply than Uint16Array.\n var utf16buf = new Array(len * 2);\n\n for (out = 0, i = 0; i < len;) {\n c = buf[i++];\n // quick process ascii\n if (c < 0x80) { utf16buf[out++] = c; continue; }\n\n c_len = _utf8len[c];\n // skip 5 & 6 byte codes\n if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }\n\n // apply mask on first byte\n c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;\n // join the rest\n while (c_len > 1 && i < len) {\n c = (c << 6) | (buf[i++] & 0x3f);\n c_len--;\n }\n\n // terminated by end of string?\n if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }\n\n if (c < 0x10000) {\n utf16buf[out++] = c;\n } else {\n c -= 0x10000;\n utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);\n utf16buf[out++] = 0xdc00 | (c & 0x3ff);\n }\n }\n\n return buf2binstring(utf16buf, out);\n};\n\n\n// Calculate max possible position in utf8 buffer,\n// that will not break sequence. If that's not possible\n// - (very small limits) return max size as is.\n//\n// buf[] - utf8 bytes array\n// max - length limit (mandatory);\nexports.utf8border = function (buf, max) {\n var pos;\n\n max = max || buf.length;\n if (max > buf.length) { max = buf.length; }\n\n // go back from last position, until start of sequence found\n pos = max - 1;\n while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }\n\n // Very small and broken sequence,\n // return max, because we should return something anyway.\n if (pos < 0) { return max; }\n\n // If we came to start of buffer - that means buffer is too small,\n // return max too.\n if (pos === 0) { return max; }\n\n return (pos + _utf8len[buf[pos]] > max) ? pos : max;\n};\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nfunction ZStream() {\n /* next input byte */\n this.input = null; // JS specific, because we have no pointers\n this.next_in = 0;\n /* number of bytes available at input */\n this.avail_in = 0;\n /* total number of input bytes read so far */\n this.total_in = 0;\n /* next output byte should be put there */\n this.output = null; // JS specific, because we have no pointers\n this.next_out = 0;\n /* remaining free space at output */\n this.avail_out = 0;\n /* total number of bytes output so far */\n this.total_out = 0;\n /* last error message, NULL if no error */\n this.msg = ''/*Z_NULL*/;\n /* not visible by applications */\n this.state = null;\n /* best guess about the data type: binary or text */\n this.data_type = 2/*Z_UNKNOWN*/;\n /* adler32 value of the uncompressed data */\n this.adler = 0;\n}\n\nmodule.exports = ZStream;\n","'use strict';\n\n\nvar zlib_deflate = require('./zlib/deflate');\nvar utils = require('./utils/common');\nvar strings = require('./utils/strings');\nvar msg = require('./zlib/messages');\nvar ZStream = require('./zlib/zstream');\n\nvar toString = Object.prototype.toString;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\nvar Z_NO_FLUSH = 0;\nvar Z_FINISH = 4;\n\nvar Z_OK = 0;\nvar Z_STREAM_END = 1;\nvar Z_SYNC_FLUSH = 2;\n\nvar Z_DEFAULT_COMPRESSION = -1;\n\nvar Z_DEFAULT_STRATEGY = 0;\n\nvar Z_DEFLATED = 8;\n\n/* ===========================================================================*/\n\n\n/**\n * class Deflate\n *\n * Generic JS-style wrapper for zlib calls. If you don't need\n * streaming behaviour - use more simple functions: [[deflate]],\n * [[deflateRaw]] and [[gzip]].\n **/\n\n/* internal\n * Deflate.chunks -> Array\n *\n * Chunks of output data, if [[Deflate#onData]] not overridden.\n **/\n\n/**\n * Deflate.result -> Uint8Array|Array\n *\n * Compressed result, generated by default [[Deflate#onData]]\n * and [[Deflate#onEnd]] handlers. Filled after you push last chunk\n * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you\n * push a chunk with explicit flush (call [[Deflate#push]] with\n * `Z_SYNC_FLUSH` param).\n **/\n\n/**\n * Deflate.err -> Number\n *\n * Error code after deflate finished. 0 (Z_OK) on success.\n * You will not need it in real life, because deflate errors\n * are possible only on wrong options or bad `onData` / `onEnd`\n * custom handlers.\n **/\n\n/**\n * Deflate.msg -> String\n *\n * Error message, if [[Deflate.err]] != 0\n **/\n\n\n/**\n * new Deflate(options)\n * - options (Object): zlib deflate options.\n *\n * Creates new deflator instance with specified params. Throws exception\n * on bad params. Supported options:\n *\n * - `level`\n * - `windowBits`\n * - `memLevel`\n * - `strategy`\n * - `dictionary`\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Additional options, for internal needs:\n *\n * - `chunkSize` - size of generated data chunks (16K by default)\n * - `raw` (Boolean) - do raw deflate\n * - `gzip` (Boolean) - create gzip wrapper\n * - `to` (String) - if equal to 'string', then result will be \"binary string\"\n * (each char code [0..255])\n * - `header` (Object) - custom header for gzip\n * - `text` (Boolean) - true if compressed data believed to be text\n * - `time` (Number) - modification time, unix timestamp\n * - `os` (Number) - operation system code\n * - `extra` (Array) - array of bytes with extra data (max 65536)\n * - `name` (String) - file name (binary string)\n * - `comment` (String) - comment (binary string)\n * - `hcrc` (Boolean) - true if header crc should be added\n *\n * ##### Example:\n *\n * ```javascript\n * var pako = require('pako')\n * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])\n * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);\n *\n * var deflate = new pako.Deflate({ level: 3});\n *\n * deflate.push(chunk1, false);\n * deflate.push(chunk2, true); // true -> last chunk\n *\n * if (deflate.err) { throw new Error(deflate.err); }\n *\n * console.log(deflate.result);\n * ```\n **/\nfunction Deflate(options) {\n if (!(this instanceof Deflate)) return new Deflate(options);\n\n this.options = utils.assign({\n level: Z_DEFAULT_COMPRESSION,\n method: Z_DEFLATED,\n chunkSize: 16384,\n windowBits: 15,\n memLevel: 8,\n strategy: Z_DEFAULT_STRATEGY,\n to: ''\n }, options || {});\n\n var opt = this.options;\n\n if (opt.raw && (opt.windowBits > 0)) {\n opt.windowBits = -opt.windowBits;\n }\n\n else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {\n opt.windowBits += 16;\n }\n\n this.err = 0; // error code, if happens (0 = Z_OK)\n this.msg = ''; // error message\n this.ended = false; // used to avoid multiple onEnd() calls\n this.chunks = []; // chunks of compressed data\n\n this.strm = new ZStream();\n this.strm.avail_out = 0;\n\n var status = zlib_deflate.deflateInit2(\n this.strm,\n opt.level,\n opt.method,\n opt.windowBits,\n opt.memLevel,\n opt.strategy\n );\n\n if (status !== Z_OK) {\n throw new Error(msg[status]);\n }\n\n if (opt.header) {\n zlib_deflate.deflateSetHeader(this.strm, opt.header);\n }\n\n if (opt.dictionary) {\n var dict;\n // Convert data if needed\n if (typeof opt.dictionary === 'string') {\n // If we need to compress text, change encoding to utf8.\n dict = strings.string2buf(opt.dictionary);\n } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {\n dict = new Uint8Array(opt.dictionary);\n } else {\n dict = opt.dictionary;\n }\n\n status = zlib_deflate.deflateSetDictionary(this.strm, dict);\n\n if (status !== Z_OK) {\n throw new Error(msg[status]);\n }\n\n this._dict_set = true;\n }\n}\n\n/**\n * Deflate#push(data[, mode]) -> Boolean\n * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be\n * converted to utf8 byte sequence.\n * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.\n * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.\n *\n * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with\n * new compressed chunks. Returns `true` on success. The last data block must have\n * mode Z_FINISH (or `true`). That will flush internal pending buffers and call\n * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you\n * can use mode Z_SYNC_FLUSH, keeping the compression context.\n *\n * On fail call [[Deflate#onEnd]] with error code and return false.\n *\n * We strongly recommend to use `Uint8Array` on input for best speed (output\n * array format is detected automatically). Also, don't skip last param and always\n * use the same type in your code (boolean or number). That will improve JS speed.\n *\n * For regular `Array`-s make sure all elements are [0..255].\n *\n * ##### Example\n *\n * ```javascript\n * push(chunk, false); // push one of data chunks\n * ...\n * push(chunk, true); // push last chunk\n * ```\n **/\nDeflate.prototype.push = function (data, mode) {\n var strm = this.strm;\n var chunkSize = this.options.chunkSize;\n var status, _mode;\n\n if (this.ended) { return false; }\n\n _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);\n\n // Convert data if needed\n if (typeof data === 'string') {\n // If we need to compress text, change encoding to utf8.\n strm.input = strings.string2buf(data);\n } else if (toString.call(data) === '[object ArrayBuffer]') {\n strm.input = new Uint8Array(data);\n } else {\n strm.input = data;\n }\n\n strm.next_in = 0;\n strm.avail_in = strm.input.length;\n\n do {\n if (strm.avail_out === 0) {\n strm.output = new utils.Buf8(chunkSize);\n strm.next_out = 0;\n strm.avail_out = chunkSize;\n }\n status = zlib_deflate.deflate(strm, _mode); /* no bad return value */\n\n if (status !== Z_STREAM_END && status !== Z_OK) {\n this.onEnd(status);\n this.ended = true;\n return false;\n }\n if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {\n if (this.options.to === 'string') {\n this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));\n } else {\n this.onData(utils.shrinkBuf(strm.output, strm.next_out));\n }\n }\n } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);\n\n // Finalize on the last chunk.\n if (_mode === Z_FINISH) {\n status = zlib_deflate.deflateEnd(this.strm);\n this.onEnd(status);\n this.ended = true;\n return status === Z_OK;\n }\n\n // callback interim results if Z_SYNC_FLUSH.\n if (_mode === Z_SYNC_FLUSH) {\n this.onEnd(Z_OK);\n strm.avail_out = 0;\n return true;\n }\n\n return true;\n};\n\n\n/**\n * Deflate#onData(chunk) -> Void\n * - chunk (Uint8Array|Array|String): output data. Type of array depends\n * on js engine support. When string output requested, each chunk\n * will be string.\n *\n * By default, stores data blocks in `chunks[]` property and glue\n * those in `onEnd`. Override this handler, if you need another behaviour.\n **/\nDeflate.prototype.onData = function (chunk) {\n this.chunks.push(chunk);\n};\n\n\n/**\n * Deflate#onEnd(status) -> Void\n * - status (Number): deflate status. 0 (Z_OK) on success,\n * other if not.\n *\n * Called once after you tell deflate that the input stream is\n * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)\n * or if an error happened. By default - join collected chunks,\n * free memory and fill `results` / `err` properties.\n **/\nDeflate.prototype.onEnd = function (status) {\n // On success - join\n if (status === Z_OK) {\n if (this.options.to === 'string') {\n this.result = this.chunks.join('');\n } else {\n this.result = utils.flattenChunks(this.chunks);\n }\n }\n this.chunks = [];\n this.err = status;\n this.msg = this.strm.msg;\n};\n\n\n/**\n * deflate(data[, options]) -> Uint8Array|Array|String\n * - data (Uint8Array|Array|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * Compress `data` with deflate algorithm and `options`.\n *\n * Supported options are:\n *\n * - level\n * - windowBits\n * - memLevel\n * - strategy\n * - dictionary\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Sugar (options):\n *\n * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify\n * negative windowBits implicitly.\n * - `to` (String) - if equal to 'string', then result will be \"binary string\"\n * (each char code [0..255])\n *\n * ##### Example:\n *\n * ```javascript\n * var pako = require('pako')\n * , data = Uint8Array([1,2,3,4,5,6,7,8,9]);\n *\n * console.log(pako.deflate(data));\n * ```\n **/\nfunction deflate(input, options) {\n var deflator = new Deflate(options);\n\n deflator.push(input, true);\n\n // That will never happens, if you don't cheat with options :)\n if (deflator.err) { throw deflator.msg || msg[deflator.err]; }\n\n return deflator.result;\n}\n\n\n/**\n * deflateRaw(data[, options]) -> Uint8Array|Array|String\n * - data (Uint8Array|Array|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * The same as [[deflate]], but creates raw data, without wrapper\n * (header and adler32 crc).\n **/\nfunction deflateRaw(input, options) {\n options = options || {};\n options.raw = true;\n return deflate(input, options);\n}\n\n\n/**\n * gzip(data[, options]) -> Uint8Array|Array|String\n * - data (Uint8Array|Array|String): input data to compress.\n * - options (Object): zlib deflate options.\n *\n * The same as [[deflate]], but create gzip wrapper instead of\n * deflate one.\n **/\nfunction gzip(input, options) {\n options = options || {};\n options.gzip = true;\n return deflate(input, options);\n}\n\n\nexports.Deflate = Deflate;\nexports.deflate = deflate;\nexports.deflateRaw = deflateRaw;\nexports.gzip = gzip;\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\n// See state defs from inflate.js\nvar BAD = 30; /* got a data error -- remain here until reset */\nvar TYPE = 12; /* i: waiting for type bits, including last-flag bit */\n\n/*\n Decode literal, length, and distance codes and write out the resulting\n literal and match bytes until either not enough input or output is\n available, an end-of-block is encountered, or a data error is encountered.\n When large enough input and output buffers are supplied to inflate(), for\n example, a 16K input buffer and a 64K output buffer, more than 95% of the\n inflate execution time is spent in this routine.\n\n Entry assumptions:\n\n state.mode === LEN\n strm.avail_in >= 6\n strm.avail_out >= 258\n start >= strm.avail_out\n state.bits < 8\n\n On return, state.mode is one of:\n\n LEN -- ran out of enough output space or enough available input\n TYPE -- reached end of block code, inflate() to interpret next block\n BAD -- error in block data\n\n Notes:\n\n - The maximum input bits used by a length/distance pair is 15 bits for the\n length code, 5 bits for the length extra, 15 bits for the distance code,\n and 13 bits for the distance extra. This totals 48 bits, or six bytes.\n Therefore if strm.avail_in >= 6, then there is enough input to avoid\n checking for available input while decoding.\n\n - The maximum bytes that a single length/distance pair can output is 258\n bytes, which is the maximum length that can be coded. inflate_fast()\n requires strm.avail_out >= 258 for each loop to avoid checking for\n output space.\n */\nmodule.exports = function inflate_fast(strm, start) {\n var state;\n var _in; /* local strm.input */\n var last; /* have enough input while in < last */\n var _out; /* local strm.output */\n var beg; /* inflate()'s initial strm.output */\n var end; /* while out < end, enough space available */\n//#ifdef INFLATE_STRICT\n var dmax; /* maximum distance from zlib header */\n//#endif\n var wsize; /* window size or zero if not using window */\n var whave; /* valid bytes in the window */\n var wnext; /* window write index */\n // Use `s_window` instead `window`, avoid conflict with instrumentation tools\n var s_window; /* allocated sliding window, if wsize != 0 */\n var hold; /* local strm.hold */\n var bits; /* local strm.bits */\n var lcode; /* local strm.lencode */\n var dcode; /* local strm.distcode */\n var lmask; /* mask for first level of length codes */\n var dmask; /* mask for first level of distance codes */\n var here; /* retrieved table entry */\n var op; /* code bits, operation, extra bits, or */\n /* window position, window bytes to copy */\n var len; /* match length, unused bytes */\n var dist; /* match distance */\n var from; /* where to copy match from */\n var from_source;\n\n\n var input, output; // JS specific, because we have no pointers\n\n /* copy state to local variables */\n state = strm.state;\n //here = state.here;\n _in = strm.next_in;\n input = strm.input;\n last = _in + (strm.avail_in - 5);\n _out = strm.next_out;\n output = strm.output;\n beg = _out - (start - strm.avail_out);\n end = _out + (strm.avail_out - 257);\n//#ifdef INFLATE_STRICT\n dmax = state.dmax;\n//#endif\n wsize = state.wsize;\n whave = state.whave;\n wnext = state.wnext;\n s_window = state.window;\n hold = state.hold;\n bits = state.bits;\n lcode = state.lencode;\n dcode = state.distcode;\n lmask = (1 << state.lenbits) - 1;\n dmask = (1 << state.distbits) - 1;\n\n\n /* decode literals and length/distances until end-of-block or not enough\n input data or output space */\n\n top:\n do {\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n\n here = lcode[hold & lmask];\n\n dolen:\n for (;;) { // Goto emulation\n op = here >>> 24/*here.bits*/;\n hold >>>= op;\n bits -= op;\n op = (here >>> 16) & 0xff/*here.op*/;\n if (op === 0) { /* literal */\n //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n // \"inflate: literal '%c'\\n\" :\n // \"inflate: literal 0x%02x\\n\", here.val));\n output[_out++] = here & 0xffff/*here.val*/;\n }\n else if (op & 16) { /* length base */\n len = here & 0xffff/*here.val*/;\n op &= 15; /* number of extra bits */\n if (op) {\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n len += hold & ((1 << op) - 1);\n hold >>>= op;\n bits -= op;\n }\n //Tracevv((stderr, \"inflate: length %u\\n\", len));\n if (bits < 15) {\n hold += input[_in++] << bits;\n bits += 8;\n hold += input[_in++] << bits;\n bits += 8;\n }\n here = dcode[hold & dmask];\n\n dodist:\n for (;;) { // goto emulation\n op = here >>> 24/*here.bits*/;\n hold >>>= op;\n bits -= op;\n op = (here >>> 16) & 0xff/*here.op*/;\n\n if (op & 16) { /* distance base */\n dist = here & 0xffff/*here.val*/;\n op &= 15; /* number of extra bits */\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n if (bits < op) {\n hold += input[_in++] << bits;\n bits += 8;\n }\n }\n dist += hold & ((1 << op) - 1);\n//#ifdef INFLATE_STRICT\n if (dist > dmax) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD;\n break top;\n }\n//#endif\n hold >>>= op;\n bits -= op;\n //Tracevv((stderr, \"inflate: distance %u\\n\", dist));\n op = _out - beg; /* max distance in output */\n if (dist > op) { /* see if copy from window */\n op = dist - op; /* distance back in window */\n if (op > whave) {\n if (state.sane) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD;\n break top;\n }\n\n// (!) This block is disabled in zlib defaults,\n// don't enable it for binary compatibility\n//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n// if (len <= op - whave) {\n// do {\n// output[_out++] = 0;\n// } while (--len);\n// continue top;\n// }\n// len -= op - whave;\n// do {\n// output[_out++] = 0;\n// } while (--op > whave);\n// if (op === 0) {\n// from = _out - dist;\n// do {\n// output[_out++] = output[from++];\n// } while (--len);\n// continue top;\n// }\n//#endif\n }\n from = 0; // window index\n from_source = s_window;\n if (wnext === 0) { /* very common case */\n from += wsize - op;\n if (op < len) { /* some from window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n else if (wnext < op) { /* wrap around window */\n from += wsize + wnext - op;\n op -= wnext;\n if (op < len) { /* some from end of window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = 0;\n if (wnext < len) { /* some from start of window */\n op = wnext;\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n }\n else { /* contiguous in window */\n from += wnext - op;\n if (op < len) { /* some from window */\n len -= op;\n do {\n output[_out++] = s_window[from++];\n } while (--op);\n from = _out - dist; /* rest from output */\n from_source = output;\n }\n }\n while (len > 2) {\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n output[_out++] = from_source[from++];\n len -= 3;\n }\n if (len) {\n output[_out++] = from_source[from++];\n if (len > 1) {\n output[_out++] = from_source[from++];\n }\n }\n }\n else {\n from = _out - dist; /* copy direct from output */\n do { /* minimum length is three */\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n output[_out++] = output[from++];\n len -= 3;\n } while (len > 2);\n if (len) {\n output[_out++] = output[from++];\n if (len > 1) {\n output[_out++] = output[from++];\n }\n }\n }\n }\n else if ((op & 64) === 0) { /* 2nd level distance code */\n here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];\n continue dodist;\n }\n else {\n strm.msg = 'invalid distance code';\n state.mode = BAD;\n break top;\n }\n\n break; // need to emulate goto via \"continue\"\n }\n }\n else if ((op & 64) === 0) { /* 2nd level length code */\n here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];\n continue dolen;\n }\n else if (op & 32) { /* end-of-block */\n //Tracevv((stderr, \"inflate: end of block\\n\"));\n state.mode = TYPE;\n break top;\n }\n else {\n strm.msg = 'invalid literal/length code';\n state.mode = BAD;\n break top;\n }\n\n break; // need to emulate goto via \"continue\"\n }\n } while (_in < last && _out < end);\n\n /* return unused bytes (on entry, bits < 8, so in won't go too far back) */\n len = bits >> 3;\n _in -= len;\n bits -= len << 3;\n hold &= (1 << bits) - 1;\n\n /* update state and return */\n strm.next_in = _in;\n strm.next_out = _out;\n strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));\n strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));\n state.hold = hold;\n state.bits = bits;\n return;\n};\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nvar utils = require('../utils/common');\n\nvar MAXBITS = 15;\nvar ENOUGH_LENS = 852;\nvar ENOUGH_DISTS = 592;\n//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);\n\nvar CODES = 0;\nvar LENS = 1;\nvar DISTS = 2;\n\nvar lbase = [ /* Length codes 257..285 base */\n 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,\n 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0\n];\n\nvar lext = [ /* Length codes 257..285 extra */\n 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,\n 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78\n];\n\nvar dbase = [ /* Distance codes 0..29 base */\n 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,\n 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,\n 8193, 12289, 16385, 24577, 0, 0\n];\n\nvar dext = [ /* Distance codes 0..29 extra */\n 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,\n 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,\n 28, 28, 29, 29, 64, 64\n];\n\nmodule.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)\n{\n var bits = opts.bits;\n //here = opts.here; /* table entry for duplication */\n\n var len = 0; /* a code's length in bits */\n var sym = 0; /* index of code symbols */\n var min = 0, max = 0; /* minimum and maximum code lengths */\n var root = 0; /* number of index bits for root table */\n var curr = 0; /* number of index bits for current table */\n var drop = 0; /* code bits to drop for sub-table */\n var left = 0; /* number of prefix codes available */\n var used = 0; /* code entries in table used */\n var huff = 0; /* Huffman code */\n var incr; /* for incrementing code, index */\n var fill; /* index for replicating entries */\n var low; /* low bits for current root entry */\n var mask; /* mask for low root bits */\n var next; /* next available space in table */\n var base = null; /* base value table to use */\n var base_index = 0;\n// var shoextra; /* extra bits table to use */\n var end; /* use base and extra for symbol > end */\n var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */\n var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */\n var extra = null;\n var extra_index = 0;\n\n var here_bits, here_op, here_val;\n\n /*\n Process a set of code lengths to create a canonical Huffman code. The\n code lengths are lens[0..codes-1]. Each length corresponds to the\n symbols 0..codes-1. The Huffman code is generated by first sorting the\n symbols by length from short to long, and retaining the symbol order\n for codes with equal lengths. Then the code starts with all zero bits\n for the first code of the shortest length, and the codes are integer\n increments for the same length, and zeros are appended as the length\n increases. For the deflate format, these bits are stored backwards\n from their more natural integer increment ordering, and so when the\n decoding tables are built in the large loop below, the integer codes\n are incremented backwards.\n\n This routine assumes, but does not check, that all of the entries in\n lens[] are in the range 0..MAXBITS. The caller must assure this.\n 1..MAXBITS is interpreted as that code length. zero means that that\n symbol does not occur in this code.\n\n The codes are sorted by computing a count of codes for each length,\n creating from that a table of starting indices for each length in the\n sorted table, and then entering the symbols in order in the sorted\n table. The sorted table is work[], with that space being provided by\n the caller.\n\n The length counts are used for other purposes as well, i.e. finding\n the minimum and maximum length codes, determining if there are any\n codes at all, checking for a valid set of lengths, and looking ahead\n at length counts to determine sub-table sizes when building the\n decoding tables.\n */\n\n /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */\n for (len = 0; len <= MAXBITS; len++) {\n count[len] = 0;\n }\n for (sym = 0; sym < codes; sym++) {\n count[lens[lens_index + sym]]++;\n }\n\n /* bound code lengths, force root to be within code lengths */\n root = bits;\n for (max = MAXBITS; max >= 1; max--) {\n if (count[max] !== 0) { break; }\n }\n if (root > max) {\n root = max;\n }\n if (max === 0) { /* no symbols to code at all */\n //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */\n //table.bits[opts.table_index] = 1; //here.bits = (var char)1;\n //table.val[opts.table_index++] = 0; //here.val = (var short)0;\n table[table_index++] = (1 << 24) | (64 << 16) | 0;\n\n\n //table.op[opts.table_index] = 64;\n //table.bits[opts.table_index] = 1;\n //table.val[opts.table_index++] = 0;\n table[table_index++] = (1 << 24) | (64 << 16) | 0;\n\n opts.bits = 1;\n return 0; /* no symbols, but wait for decoding to report error */\n }\n for (min = 1; min < max; min++) {\n if (count[min] !== 0) { break; }\n }\n if (root < min) {\n root = min;\n }\n\n /* check for an over-subscribed or incomplete set of lengths */\n left = 1;\n for (len = 1; len <= MAXBITS; len++) {\n left <<= 1;\n left -= count[len];\n if (left < 0) {\n return -1;\n } /* over-subscribed */\n }\n if (left > 0 && (type === CODES || max !== 1)) {\n return -1; /* incomplete set */\n }\n\n /* generate offsets into symbol table for each length for sorting */\n offs[1] = 0;\n for (len = 1; len < MAXBITS; len++) {\n offs[len + 1] = offs[len] + count[len];\n }\n\n /* sort symbols by length, by symbol order within each length */\n for (sym = 0; sym < codes; sym++) {\n if (lens[lens_index + sym] !== 0) {\n work[offs[lens[lens_index + sym]]++] = sym;\n }\n }\n\n /*\n Create and fill in decoding tables. In this loop, the table being\n filled is at next and has curr index bits. The code being used is huff\n with length len. That code is converted to an index by dropping drop\n bits off of the bottom. For codes where len is less than drop + curr,\n those top drop + curr - len bits are incremented through all values to\n fill the table with replicated entries.\n\n root is the number of index bits for the root table. When len exceeds\n root, sub-tables are created pointed to by the root entry with an index\n of the low root bits of huff. This is saved in low to check for when a\n new sub-table should be started. drop is zero when the root table is\n being filled, and drop is root when sub-tables are being filled.\n\n When a new sub-table is needed, it is necessary to look ahead in the\n code lengths to determine what size sub-table is needed. The length\n counts are used for this, and so count[] is decremented as codes are\n entered in the tables.\n\n used keeps track of how many table entries have been allocated from the\n provided *table space. It is checked for LENS and DIST tables against\n the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in\n the initial root table size constants. See the comments in inftrees.h\n for more information.\n\n sym increments through all symbols, and the loop terminates when\n all codes of length max, i.e. all codes, have been processed. This\n routine permits incomplete codes, so another loop after this one fills\n in the rest of the decoding tables with invalid code markers.\n */\n\n /* set up for code type */\n // poor man optimization - use if-else instead of switch,\n // to avoid deopts in old v8\n if (type === CODES) {\n base = extra = work; /* dummy value--not used */\n end = 19;\n\n } else if (type === LENS) {\n base = lbase;\n base_index -= 257;\n extra = lext;\n extra_index -= 257;\n end = 256;\n\n } else { /* DISTS */\n base = dbase;\n extra = dext;\n end = -1;\n }\n\n /* initialize opts for loop */\n huff = 0; /* starting code */\n sym = 0; /* starting code symbol */\n len = min; /* starting code length */\n next = table_index; /* current table to fill in */\n curr = root; /* current table index bits */\n drop = 0; /* current bits to drop from code for index */\n low = -1; /* trigger new sub-table when len > root */\n used = 1 << root; /* use root table entries */\n mask = used - 1; /* mask for comparing low */\n\n /* check available table space */\n if ((type === LENS && used > ENOUGH_LENS) ||\n (type === DISTS && used > ENOUGH_DISTS)) {\n return 1;\n }\n\n /* process all codes and make table entries */\n for (;;) {\n /* create table entry */\n here_bits = len - drop;\n if (work[sym] < end) {\n here_op = 0;\n here_val = work[sym];\n }\n else if (work[sym] > end) {\n here_op = extra[extra_index + work[sym]];\n here_val = base[base_index + work[sym]];\n }\n else {\n here_op = 32 + 64; /* end of block */\n here_val = 0;\n }\n\n /* replicate for those indices with low len bits equal to huff */\n incr = 1 << (len - drop);\n fill = 1 << curr;\n min = fill; /* save offset to next table */\n do {\n fill -= incr;\n table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;\n } while (fill !== 0);\n\n /* backwards increment the len-bit code huff */\n incr = 1 << (len - 1);\n while (huff & incr) {\n incr >>= 1;\n }\n if (incr !== 0) {\n huff &= incr - 1;\n huff += incr;\n } else {\n huff = 0;\n }\n\n /* go to next symbol, update count, len */\n sym++;\n if (--count[len] === 0) {\n if (len === max) { break; }\n len = lens[lens_index + work[sym]];\n }\n\n /* create new sub-table if needed */\n if (len > root && (huff & mask) !== low) {\n /* if first time, transition to sub-tables */\n if (drop === 0) {\n drop = root;\n }\n\n /* increment past last table */\n next += min; /* here min is 1 << curr */\n\n /* determine length of next table */\n curr = len - drop;\n left = 1 << curr;\n while (curr + drop < max) {\n left -= count[curr + drop];\n if (left <= 0) { break; }\n curr++;\n left <<= 1;\n }\n\n /* check for enough space */\n used += 1 << curr;\n if ((type === LENS && used > ENOUGH_LENS) ||\n (type === DISTS && used > ENOUGH_DISTS)) {\n return 1;\n }\n\n /* point entry in root table to sub-table */\n low = huff & mask;\n /*table.op[low] = curr;\n table.bits[low] = root;\n table.val[low] = next - opts.table_index;*/\n table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;\n }\n }\n\n /* fill in remaining table entry if code is incomplete (guaranteed to have\n at most one remaining entry, since if the code is incomplete, the\n maximum code length that was allowed to get this far is one bit) */\n if (huff !== 0) {\n //table.op[next + huff] = 64; /* invalid code marker */\n //table.bits[next + huff] = len - drop;\n //table.val[next + huff] = 0;\n table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;\n }\n\n /* set return parameters */\n //opts.table_index += used;\n opts.bits = root;\n return 0;\n};\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nvar utils = require('../utils/common');\nvar adler32 = require('./adler32');\nvar crc32 = require('./crc32');\nvar inflate_fast = require('./inffast');\nvar inflate_table = require('./inftrees');\n\nvar CODES = 0;\nvar LENS = 1;\nvar DISTS = 2;\n\n/* Public constants ==========================================================*/\n/* ===========================================================================*/\n\n\n/* Allowed flush values; see deflate() and inflate() below for details */\n//var Z_NO_FLUSH = 0;\n//var Z_PARTIAL_FLUSH = 1;\n//var Z_SYNC_FLUSH = 2;\n//var Z_FULL_FLUSH = 3;\nvar Z_FINISH = 4;\nvar Z_BLOCK = 5;\nvar Z_TREES = 6;\n\n\n/* Return codes for the compression/decompression functions. Negative values\n * are errors, positive values are used for special but normal events.\n */\nvar Z_OK = 0;\nvar Z_STREAM_END = 1;\nvar Z_NEED_DICT = 2;\n//var Z_ERRNO = -1;\nvar Z_STREAM_ERROR = -2;\nvar Z_DATA_ERROR = -3;\nvar Z_MEM_ERROR = -4;\nvar Z_BUF_ERROR = -5;\n//var Z_VERSION_ERROR = -6;\n\n/* The deflate compression method */\nvar Z_DEFLATED = 8;\n\n\n/* STATES ====================================================================*/\n/* ===========================================================================*/\n\n\nvar HEAD = 1; /* i: waiting for magic header */\nvar FLAGS = 2; /* i: waiting for method and flags (gzip) */\nvar TIME = 3; /* i: waiting for modification time (gzip) */\nvar OS = 4; /* i: waiting for extra flags and operating system (gzip) */\nvar EXLEN = 5; /* i: waiting for extra length (gzip) */\nvar EXTRA = 6; /* i: waiting for extra bytes (gzip) */\nvar NAME = 7; /* i: waiting for end of file name (gzip) */\nvar COMMENT = 8; /* i: waiting for end of comment (gzip) */\nvar HCRC = 9; /* i: waiting for header crc (gzip) */\nvar DICTID = 10; /* i: waiting for dictionary check value */\nvar DICT = 11; /* waiting for inflateSetDictionary() call */\nvar TYPE = 12; /* i: waiting for type bits, including last-flag bit */\nvar TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */\nvar STORED = 14; /* i: waiting for stored size (length and complement) */\nvar COPY_ = 15; /* i/o: same as COPY below, but only first time in */\nvar COPY = 16; /* i/o: waiting for input or output to copy stored block */\nvar TABLE = 17; /* i: waiting for dynamic block table lengths */\nvar LENLENS = 18; /* i: waiting for code length code lengths */\nvar CODELENS = 19; /* i: waiting for length/lit and distance code lengths */\nvar LEN_ = 20; /* i: same as LEN below, but only first time in */\nvar LEN = 21; /* i: waiting for length/lit/eob code */\nvar LENEXT = 22; /* i: waiting for length extra bits */\nvar DIST = 23; /* i: waiting for distance code */\nvar DISTEXT = 24; /* i: waiting for distance extra bits */\nvar MATCH = 25; /* o: waiting for output space to copy string */\nvar LIT = 26; /* o: waiting for output space to write literal */\nvar CHECK = 27; /* i: waiting for 32-bit check value */\nvar LENGTH = 28; /* i: waiting for 32-bit length (gzip) */\nvar DONE = 29; /* finished check, done -- remain here until reset */\nvar BAD = 30; /* got a data error -- remain here until reset */\nvar MEM = 31; /* got an inflate() memory error -- remain here until reset */\nvar SYNC = 32; /* looking for synchronization bytes to restart inflate() */\n\n/* ===========================================================================*/\n\n\n\nvar ENOUGH_LENS = 852;\nvar ENOUGH_DISTS = 592;\n//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);\n\nvar MAX_WBITS = 15;\n/* 32K LZ77 window */\nvar DEF_WBITS = MAX_WBITS;\n\n\nfunction zswap32(q) {\n return (((q >>> 24) & 0xff) +\n ((q >>> 8) & 0xff00) +\n ((q & 0xff00) << 8) +\n ((q & 0xff) << 24));\n}\n\n\nfunction InflateState() {\n this.mode = 0; /* current inflate mode */\n this.last = false; /* true if processing last block */\n this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */\n this.havedict = false; /* true if dictionary provided */\n this.flags = 0; /* gzip header method and flags (0 if zlib) */\n this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */\n this.check = 0; /* protected copy of check value */\n this.total = 0; /* protected copy of output count */\n // TODO: may be {}\n this.head = null; /* where to save gzip header information */\n\n /* sliding window */\n this.wbits = 0; /* log base 2 of requested window size */\n this.wsize = 0; /* window size or zero if not using window */\n this.whave = 0; /* valid bytes in the window */\n this.wnext = 0; /* window write index */\n this.window = null; /* allocated sliding window, if needed */\n\n /* bit accumulator */\n this.hold = 0; /* input bit accumulator */\n this.bits = 0; /* number of bits in \"in\" */\n\n /* for string and stored block copying */\n this.length = 0; /* literal or length of data to copy */\n this.offset = 0; /* distance back to copy string from */\n\n /* for table and code decoding */\n this.extra = 0; /* extra bits needed */\n\n /* fixed and dynamic code tables */\n this.lencode = null; /* starting table for length/literal codes */\n this.distcode = null; /* starting table for distance codes */\n this.lenbits = 0; /* index bits for lencode */\n this.distbits = 0; /* index bits for distcode */\n\n /* dynamic table building */\n this.ncode = 0; /* number of code length code lengths */\n this.nlen = 0; /* number of length code lengths */\n this.ndist = 0; /* number of distance code lengths */\n this.have = 0; /* number of code lengths in lens[] */\n this.next = null; /* next available space in codes[] */\n\n this.lens = new utils.Buf16(320); /* temporary storage for code lengths */\n this.work = new utils.Buf16(288); /* work area for code table building */\n\n /*\n because we don't have pointers in js, we use lencode and distcode directly\n as buffers so we don't need codes\n */\n //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */\n this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */\n this.distdyn = null; /* dynamic table for distance codes (JS specific) */\n this.sane = 0; /* if false, allow invalid distance too far */\n this.back = 0; /* bits back of last unprocessed length/lit */\n this.was = 0; /* initial length of match */\n}\n\nfunction inflateResetKeep(strm) {\n var state;\n\n if (!strm || !strm.state) { return Z_STREAM_ERROR; }\n state = strm.state;\n strm.total_in = strm.total_out = state.total = 0;\n strm.msg = ''; /*Z_NULL*/\n if (state.wrap) { /* to support ill-conceived Java test suite */\n strm.adler = state.wrap & 1;\n }\n state.mode = HEAD;\n state.last = 0;\n state.havedict = 0;\n state.dmax = 32768;\n state.head = null/*Z_NULL*/;\n state.hold = 0;\n state.bits = 0;\n //state.lencode = state.distcode = state.next = state.codes;\n state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);\n state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);\n\n state.sane = 1;\n state.back = -1;\n //Tracev((stderr, \"inflate: reset\\n\"));\n return Z_OK;\n}\n\nfunction inflateReset(strm) {\n var state;\n\n if (!strm || !strm.state) { return Z_STREAM_ERROR; }\n state = strm.state;\n state.wsize = 0;\n state.whave = 0;\n state.wnext = 0;\n return inflateResetKeep(strm);\n\n}\n\nfunction inflateReset2(strm, windowBits) {\n var wrap;\n var state;\n\n /* get the state */\n if (!strm || !strm.state) { return Z_STREAM_ERROR; }\n state = strm.state;\n\n /* extract wrap request from windowBits parameter */\n if (windowBits < 0) {\n wrap = 0;\n windowBits = -windowBits;\n }\n else {\n wrap = (windowBits >> 4) + 1;\n if (windowBits < 48) {\n windowBits &= 15;\n }\n }\n\n /* set number of window bits, free window if different */\n if (windowBits && (windowBits < 8 || windowBits > 15)) {\n return Z_STREAM_ERROR;\n }\n if (state.window !== null && state.wbits !== windowBits) {\n state.window = null;\n }\n\n /* update state and reset the rest of it */\n state.wrap = wrap;\n state.wbits = windowBits;\n return inflateReset(strm);\n}\n\nfunction inflateInit2(strm, windowBits) {\n var ret;\n var state;\n\n if (!strm) { return Z_STREAM_ERROR; }\n //strm.msg = Z_NULL; /* in case we return an error */\n\n state = new InflateState();\n\n //if (state === Z_NULL) return Z_MEM_ERROR;\n //Tracev((stderr, \"inflate: allocated\\n\"));\n strm.state = state;\n state.window = null/*Z_NULL*/;\n ret = inflateReset2(strm, windowBits);\n if (ret !== Z_OK) {\n strm.state = null/*Z_NULL*/;\n }\n return ret;\n}\n\nfunction inflateInit(strm) {\n return inflateInit2(strm, DEF_WBITS);\n}\n\n\n/*\n Return state with length and distance decoding tables and index sizes set to\n fixed code decoding. Normally this returns fixed tables from inffixed.h.\n If BUILDFIXED is defined, then instead this routine builds the tables the\n first time it's called, and returns those tables the first time and\n thereafter. This reduces the size of the code by about 2K bytes, in\n exchange for a little execution time. However, BUILDFIXED should not be\n used for threaded applications, since the rewriting of the tables and virgin\n may not be thread-safe.\n */\nvar virgin = true;\n\nvar lenfix, distfix; // We have no pointers in JS, so keep tables separate\n\nfunction fixedtables(state) {\n /* build fixed huffman tables if first call (may not be thread safe) */\n if (virgin) {\n var sym;\n\n lenfix = new utils.Buf32(512);\n distfix = new utils.Buf32(32);\n\n /* literal/length table */\n sym = 0;\n while (sym < 144) { state.lens[sym++] = 8; }\n while (sym < 256) { state.lens[sym++] = 9; }\n while (sym < 280) { state.lens[sym++] = 7; }\n while (sym < 288) { state.lens[sym++] = 8; }\n\n inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });\n\n /* distance table */\n sym = 0;\n while (sym < 32) { state.lens[sym++] = 5; }\n\n inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });\n\n /* do this just once */\n virgin = false;\n }\n\n state.lencode = lenfix;\n state.lenbits = 9;\n state.distcode = distfix;\n state.distbits = 5;\n}\n\n\n/*\n Update the window with the last wsize (normally 32K) bytes written before\n returning. If window does not exist yet, create it. This is only called\n when a window is already in use, or when output has been written during this\n inflate call, but the end of the deflate stream has not been reached yet.\n It is also called to create a window for dictionary data when a dictionary\n is loaded.\n\n Providing output buffers larger than 32K to inflate() should provide a speed\n advantage, since only the last 32K of output is copied to the sliding window\n upon return from inflate(), and since all distances after the first 32K of\n output will fall in the output data, making match copies simpler and faster.\n The advantage may be dependent on the size of the processor's data caches.\n */\nfunction updatewindow(strm, src, end, copy) {\n var dist;\n var state = strm.state;\n\n /* if it hasn't been done already, allocate space for the window */\n if (state.window === null) {\n state.wsize = 1 << state.wbits;\n state.wnext = 0;\n state.whave = 0;\n\n state.window = new utils.Buf8(state.wsize);\n }\n\n /* copy state->wsize or less output bytes into the circular window */\n if (copy >= state.wsize) {\n utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);\n state.wnext = 0;\n state.whave = state.wsize;\n }\n else {\n dist = state.wsize - state.wnext;\n if (dist > copy) {\n dist = copy;\n }\n //zmemcpy(state->window + state->wnext, end - copy, dist);\n utils.arraySet(state.window, src, end - copy, dist, state.wnext);\n copy -= dist;\n if (copy) {\n //zmemcpy(state->window, end - copy, copy);\n utils.arraySet(state.window, src, end - copy, copy, 0);\n state.wnext = copy;\n state.whave = state.wsize;\n }\n else {\n state.wnext += dist;\n if (state.wnext === state.wsize) { state.wnext = 0; }\n if (state.whave < state.wsize) { state.whave += dist; }\n }\n }\n return 0;\n}\n\nfunction inflate(strm, flush) {\n var state;\n var input, output; // input/output buffers\n var next; /* next input INDEX */\n var put; /* next output INDEX */\n var have, left; /* available input and output */\n var hold; /* bit buffer */\n var bits; /* bits in bit buffer */\n var _in, _out; /* save starting available input and output */\n var copy; /* number of stored or match bytes to copy */\n var from; /* where to copy match bytes from */\n var from_source;\n var here = 0; /* current decoding table entry */\n var here_bits, here_op, here_val; // paked \"here\" denormalized (JS specific)\n //var last; /* parent table entry */\n var last_bits, last_op, last_val; // paked \"last\" denormalized (JS specific)\n var len; /* length to copy for repeats, bits to drop */\n var ret; /* return code */\n var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */\n var opts;\n\n var n; // temporary var for NEED_BITS\n\n var order = /* permutation of code lengths */\n [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];\n\n\n if (!strm || !strm.state || !strm.output ||\n (!strm.input && strm.avail_in !== 0)) {\n return Z_STREAM_ERROR;\n }\n\n state = strm.state;\n if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */\n\n\n //--- LOAD() ---\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n //---\n\n _in = have;\n _out = left;\n ret = Z_OK;\n\n inf_leave: // goto emulation\n for (;;) {\n switch (state.mode) {\n case HEAD:\n if (state.wrap === 0) {\n state.mode = TYPEDO;\n break;\n }\n //=== NEEDBITS(16);\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */\n state.check = 0/*crc32(0L, Z_NULL, 0)*/;\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32(state.check, hbuf, 2, 0);\n //===//\n\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = FLAGS;\n break;\n }\n state.flags = 0; /* expect zlib header */\n if (state.head) {\n state.head.done = false;\n }\n if (!(state.wrap & 1) || /* check if zlib header allowed */\n (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {\n strm.msg = 'incorrect header check';\n state.mode = BAD;\n break;\n }\n if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {\n strm.msg = 'unknown compression method';\n state.mode = BAD;\n break;\n }\n //--- DROPBITS(4) ---//\n hold >>>= 4;\n bits -= 4;\n //---//\n len = (hold & 0x0f)/*BITS(4)*/ + 8;\n if (state.wbits === 0) {\n state.wbits = len;\n }\n else if (len > state.wbits) {\n strm.msg = 'invalid window size';\n state.mode = BAD;\n break;\n }\n state.dmax = 1 << len;\n //Tracev((stderr, \"inflate: zlib header ok\\n\"));\n strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;\n state.mode = hold & 0x200 ? DICTID : TYPE;\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n break;\n case FLAGS:\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.flags = hold;\n if ((state.flags & 0xff) !== Z_DEFLATED) {\n strm.msg = 'unknown compression method';\n state.mode = BAD;\n break;\n }\n if (state.flags & 0xe000) {\n strm.msg = 'unknown header flags set';\n state.mode = BAD;\n break;\n }\n if (state.head) {\n state.head.text = ((hold >> 8) & 1);\n }\n if (state.flags & 0x0200) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = TIME;\n /* falls through */\n case TIME:\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (state.head) {\n state.head.time = hold;\n }\n if (state.flags & 0x0200) {\n //=== CRC4(state.check, hold)\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n hbuf[2] = (hold >>> 16) & 0xff;\n hbuf[3] = (hold >>> 24) & 0xff;\n state.check = crc32(state.check, hbuf, 4, 0);\n //===\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = OS;\n /* falls through */\n case OS:\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (state.head) {\n state.head.xflags = (hold & 0xff);\n state.head.os = (hold >> 8);\n }\n if (state.flags & 0x0200) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = EXLEN;\n /* falls through */\n case EXLEN:\n if (state.flags & 0x0400) {\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.length = hold;\n if (state.head) {\n state.head.extra_len = hold;\n }\n if (state.flags & 0x0200) {\n //=== CRC2(state.check, hold);\n hbuf[0] = hold & 0xff;\n hbuf[1] = (hold >>> 8) & 0xff;\n state.check = crc32(state.check, hbuf, 2, 0);\n //===//\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n }\n else if (state.head) {\n state.head.extra = null/*Z_NULL*/;\n }\n state.mode = EXTRA;\n /* falls through */\n case EXTRA:\n if (state.flags & 0x0400) {\n copy = state.length;\n if (copy > have) { copy = have; }\n if (copy) {\n if (state.head) {\n len = state.head.extra_len - state.length;\n if (!state.head.extra) {\n // Use untyped array for more convenient processing later\n state.head.extra = new Array(state.head.extra_len);\n }\n utils.arraySet(\n state.head.extra,\n input,\n next,\n // extra field is limited to 65536 bytes\n // - no need for additional size check\n copy,\n /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/\n len\n );\n //zmemcpy(state.head.extra + len, next,\n // len + copy > state.head.extra_max ?\n // state.head.extra_max - len : copy);\n }\n if (state.flags & 0x0200) {\n state.check = crc32(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n state.length -= copy;\n }\n if (state.length) { break inf_leave; }\n }\n state.length = 0;\n state.mode = NAME;\n /* falls through */\n case NAME:\n if (state.flags & 0x0800) {\n if (have === 0) { break inf_leave; }\n copy = 0;\n do {\n // TODO: 2 or 1 bytes?\n len = input[next + copy++];\n /* use constant limit because in js we should not preallocate memory */\n if (state.head && len &&\n (state.length < 65536 /*state.head.name_max*/)) {\n state.head.name += String.fromCharCode(len);\n }\n } while (len && copy < have);\n\n if (state.flags & 0x0200) {\n state.check = crc32(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) { break inf_leave; }\n }\n else if (state.head) {\n state.head.name = null;\n }\n state.length = 0;\n state.mode = COMMENT;\n /* falls through */\n case COMMENT:\n if (state.flags & 0x1000) {\n if (have === 0) { break inf_leave; }\n copy = 0;\n do {\n len = input[next + copy++];\n /* use constant limit because in js we should not preallocate memory */\n if (state.head && len &&\n (state.length < 65536 /*state.head.comm_max*/)) {\n state.head.comment += String.fromCharCode(len);\n }\n } while (len && copy < have);\n if (state.flags & 0x0200) {\n state.check = crc32(state.check, input, copy, next);\n }\n have -= copy;\n next += copy;\n if (len) { break inf_leave; }\n }\n else if (state.head) {\n state.head.comment = null;\n }\n state.mode = HCRC;\n /* falls through */\n case HCRC:\n if (state.flags & 0x0200) {\n //=== NEEDBITS(16); */\n while (bits < 16) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (hold !== (state.check & 0xffff)) {\n strm.msg = 'header crc mismatch';\n state.mode = BAD;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n }\n if (state.head) {\n state.head.hcrc = ((state.flags >> 9) & 1);\n state.head.done = true;\n }\n strm.adler = state.check = 0;\n state.mode = TYPE;\n break;\n case DICTID:\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n strm.adler = state.check = zswap32(hold);\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = DICT;\n /* falls through */\n case DICT:\n if (state.havedict === 0) {\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n return Z_NEED_DICT;\n }\n strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;\n state.mode = TYPE;\n /* falls through */\n case TYPE:\n if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }\n /* falls through */\n case TYPEDO:\n if (state.last) {\n //--- BYTEBITS() ---//\n hold >>>= bits & 7;\n bits -= bits & 7;\n //---//\n state.mode = CHECK;\n break;\n }\n //=== NEEDBITS(3); */\n while (bits < 3) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.last = (hold & 0x01)/*BITS(1)*/;\n //--- DROPBITS(1) ---//\n hold >>>= 1;\n bits -= 1;\n //---//\n\n switch ((hold & 0x03)/*BITS(2)*/) {\n case 0: /* stored block */\n //Tracev((stderr, \"inflate: stored block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = STORED;\n break;\n case 1: /* fixed block */\n fixedtables(state);\n //Tracev((stderr, \"inflate: fixed codes block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = LEN_; /* decode codes */\n if (flush === Z_TREES) {\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n break inf_leave;\n }\n break;\n case 2: /* dynamic block */\n //Tracev((stderr, \"inflate: dynamic codes block%s\\n\",\n // state.last ? \" (last)\" : \"\"));\n state.mode = TABLE;\n break;\n case 3:\n strm.msg = 'invalid block type';\n state.mode = BAD;\n }\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n break;\n case STORED:\n //--- BYTEBITS() ---// /* go to byte boundary */\n hold >>>= bits & 7;\n bits -= bits & 7;\n //---//\n //=== NEEDBITS(32); */\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {\n strm.msg = 'invalid stored block lengths';\n state.mode = BAD;\n break;\n }\n state.length = hold & 0xffff;\n //Tracev((stderr, \"inflate: stored length %u\\n\",\n // state.length));\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n state.mode = COPY_;\n if (flush === Z_TREES) { break inf_leave; }\n /* falls through */\n case COPY_:\n state.mode = COPY;\n /* falls through */\n case COPY:\n copy = state.length;\n if (copy) {\n if (copy > have) { copy = have; }\n if (copy > left) { copy = left; }\n if (copy === 0) { break inf_leave; }\n //--- zmemcpy(put, next, copy); ---\n utils.arraySet(output, input, next, copy, put);\n //---//\n have -= copy;\n next += copy;\n left -= copy;\n put += copy;\n state.length -= copy;\n break;\n }\n //Tracev((stderr, \"inflate: stored end\\n\"));\n state.mode = TYPE;\n break;\n case TABLE:\n //=== NEEDBITS(14); */\n while (bits < 14) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;\n //--- DROPBITS(5) ---//\n hold >>>= 5;\n bits -= 5;\n //---//\n state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;\n //--- DROPBITS(5) ---//\n hold >>>= 5;\n bits -= 5;\n //---//\n state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;\n //--- DROPBITS(4) ---//\n hold >>>= 4;\n bits -= 4;\n //---//\n//#ifndef PKZIP_BUG_WORKAROUND\n if (state.nlen > 286 || state.ndist > 30) {\n strm.msg = 'too many length or distance symbols';\n state.mode = BAD;\n break;\n }\n//#endif\n //Tracev((stderr, \"inflate: table sizes ok\\n\"));\n state.have = 0;\n state.mode = LENLENS;\n /* falls through */\n case LENLENS:\n while (state.have < state.ncode) {\n //=== NEEDBITS(3);\n while (bits < 3) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);\n //--- DROPBITS(3) ---//\n hold >>>= 3;\n bits -= 3;\n //---//\n }\n while (state.have < 19) {\n state.lens[order[state.have++]] = 0;\n }\n // We have separate tables & no pointers. 2 commented lines below not needed.\n //state.next = state.codes;\n //state.lencode = state.next;\n // Switch to use dynamic table\n state.lencode = state.lendyn;\n state.lenbits = 7;\n\n opts = { bits: state.lenbits };\n ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);\n state.lenbits = opts.bits;\n\n if (ret) {\n strm.msg = 'invalid code lengths set';\n state.mode = BAD;\n break;\n }\n //Tracev((stderr, \"inflate: code lengths ok\\n\"));\n state.have = 0;\n state.mode = CODELENS;\n /* falls through */\n case CODELENS:\n while (state.have < state.nlen + state.ndist) {\n for (;;) {\n here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if (here_val < 16) {\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.lens[state.have++] = here_val;\n }\n else {\n if (here_val === 16) {\n //=== NEEDBITS(here.bits + 2);\n n = here_bits + 2;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n if (state.have === 0) {\n strm.msg = 'invalid bit length repeat';\n state.mode = BAD;\n break;\n }\n len = state.lens[state.have - 1];\n copy = 3 + (hold & 0x03);//BITS(2);\n //--- DROPBITS(2) ---//\n hold >>>= 2;\n bits -= 2;\n //---//\n }\n else if (here_val === 17) {\n //=== NEEDBITS(here.bits + 3);\n n = here_bits + 3;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n len = 0;\n copy = 3 + (hold & 0x07);//BITS(3);\n //--- DROPBITS(3) ---//\n hold >>>= 3;\n bits -= 3;\n //---//\n }\n else {\n //=== NEEDBITS(here.bits + 7);\n n = here_bits + 7;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n len = 0;\n copy = 11 + (hold & 0x7f);//BITS(7);\n //--- DROPBITS(7) ---//\n hold >>>= 7;\n bits -= 7;\n //---//\n }\n if (state.have + copy > state.nlen + state.ndist) {\n strm.msg = 'invalid bit length repeat';\n state.mode = BAD;\n break;\n }\n while (copy--) {\n state.lens[state.have++] = len;\n }\n }\n }\n\n /* handle error breaks in while */\n if (state.mode === BAD) { break; }\n\n /* check for end-of-block code (better have one) */\n if (state.lens[256] === 0) {\n strm.msg = 'invalid code -- missing end-of-block';\n state.mode = BAD;\n break;\n }\n\n /* build code tables -- note: do not change the lenbits or distbits\n values here (9 and 6) without reading the comments in inftrees.h\n concerning the ENOUGH constants, which depend on those values */\n state.lenbits = 9;\n\n opts = { bits: state.lenbits };\n ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);\n // We have separate tables & no pointers. 2 commented lines below not needed.\n // state.next_index = opts.table_index;\n state.lenbits = opts.bits;\n // state.lencode = state.next;\n\n if (ret) {\n strm.msg = 'invalid literal/lengths set';\n state.mode = BAD;\n break;\n }\n\n state.distbits = 6;\n //state.distcode.copy(state.codes);\n // Switch to use dynamic table\n state.distcode = state.distdyn;\n opts = { bits: state.distbits };\n ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);\n // We have separate tables & no pointers. 2 commented lines below not needed.\n // state.next_index = opts.table_index;\n state.distbits = opts.bits;\n // state.distcode = state.next;\n\n if (ret) {\n strm.msg = 'invalid distances set';\n state.mode = BAD;\n break;\n }\n //Tracev((stderr, 'inflate: codes ok\\n'));\n state.mode = LEN_;\n if (flush === Z_TREES) { break inf_leave; }\n /* falls through */\n case LEN_:\n state.mode = LEN;\n /* falls through */\n case LEN:\n if (have >= 6 && left >= 258) {\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n inflate_fast(strm, _out);\n //--- LOAD() ---\n put = strm.next_out;\n output = strm.output;\n left = strm.avail_out;\n next = strm.next_in;\n input = strm.input;\n have = strm.avail_in;\n hold = state.hold;\n bits = state.bits;\n //---\n\n if (state.mode === TYPE) {\n state.back = -1;\n }\n break;\n }\n state.back = 0;\n for (;;) {\n here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if (here_bits <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if (here_op && (here_op & 0xf0) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (;;) {\n here = state.lencode[last_val +\n ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((last_bits + here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n //--- DROPBITS(last.bits) ---//\n hold >>>= last_bits;\n bits -= last_bits;\n //---//\n state.back += last_bits;\n }\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.back += here_bits;\n state.length = here_val;\n if (here_op === 0) {\n //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?\n // \"inflate: literal '%c'\\n\" :\n // \"inflate: literal 0x%02x\\n\", here.val));\n state.mode = LIT;\n break;\n }\n if (here_op & 32) {\n //Tracevv((stderr, \"inflate: end of block\\n\"));\n state.back = -1;\n state.mode = TYPE;\n break;\n }\n if (here_op & 64) {\n strm.msg = 'invalid literal/length code';\n state.mode = BAD;\n break;\n }\n state.extra = here_op & 15;\n state.mode = LENEXT;\n /* falls through */\n case LENEXT:\n if (state.extra) {\n //=== NEEDBITS(state.extra);\n n = state.extra;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;\n //--- DROPBITS(state.extra) ---//\n hold >>>= state.extra;\n bits -= state.extra;\n //---//\n state.back += state.extra;\n }\n //Tracevv((stderr, \"inflate: length %u\\n\", state.length));\n state.was = state.length;\n state.mode = DIST;\n /* falls through */\n case DIST:\n for (;;) {\n here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n if ((here_op & 0xf0) === 0) {\n last_bits = here_bits;\n last_op = here_op;\n last_val = here_val;\n for (;;) {\n here = state.distcode[last_val +\n ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];\n here_bits = here >>> 24;\n here_op = (here >>> 16) & 0xff;\n here_val = here & 0xffff;\n\n if ((last_bits + here_bits) <= bits) { break; }\n //--- PULLBYTE() ---//\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n //---//\n }\n //--- DROPBITS(last.bits) ---//\n hold >>>= last_bits;\n bits -= last_bits;\n //---//\n state.back += last_bits;\n }\n //--- DROPBITS(here.bits) ---//\n hold >>>= here_bits;\n bits -= here_bits;\n //---//\n state.back += here_bits;\n if (here_op & 64) {\n strm.msg = 'invalid distance code';\n state.mode = BAD;\n break;\n }\n state.offset = here_val;\n state.extra = (here_op) & 15;\n state.mode = DISTEXT;\n /* falls through */\n case DISTEXT:\n if (state.extra) {\n //=== NEEDBITS(state.extra);\n n = state.extra;\n while (bits < n) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;\n //--- DROPBITS(state.extra) ---//\n hold >>>= state.extra;\n bits -= state.extra;\n //---//\n state.back += state.extra;\n }\n//#ifdef INFLATE_STRICT\n if (state.offset > state.dmax) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD;\n break;\n }\n//#endif\n //Tracevv((stderr, \"inflate: distance %u\\n\", state.offset));\n state.mode = MATCH;\n /* falls through */\n case MATCH:\n if (left === 0) { break inf_leave; }\n copy = _out - left;\n if (state.offset > copy) { /* copy from window */\n copy = state.offset - copy;\n if (copy > state.whave) {\n if (state.sane) {\n strm.msg = 'invalid distance too far back';\n state.mode = BAD;\n break;\n }\n// (!) This block is disabled in zlib defaults,\n// don't enable it for binary compatibility\n//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR\n// Trace((stderr, \"inflate.c too far\\n\"));\n// copy -= state.whave;\n// if (copy > state.length) { copy = state.length; }\n// if (copy > left) { copy = left; }\n// left -= copy;\n// state.length -= copy;\n// do {\n// output[put++] = 0;\n// } while (--copy);\n// if (state.length === 0) { state.mode = LEN; }\n// break;\n//#endif\n }\n if (copy > state.wnext) {\n copy -= state.wnext;\n from = state.wsize - copy;\n }\n else {\n from = state.wnext - copy;\n }\n if (copy > state.length) { copy = state.length; }\n from_source = state.window;\n }\n else { /* copy from output */\n from_source = output;\n from = put - state.offset;\n copy = state.length;\n }\n if (copy > left) { copy = left; }\n left -= copy;\n state.length -= copy;\n do {\n output[put++] = from_source[from++];\n } while (--copy);\n if (state.length === 0) { state.mode = LEN; }\n break;\n case LIT:\n if (left === 0) { break inf_leave; }\n output[put++] = state.length;\n left--;\n state.mode = LEN;\n break;\n case CHECK:\n if (state.wrap) {\n //=== NEEDBITS(32);\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n // Use '|' instead of '+' to make sure that result is signed\n hold |= input[next++] << bits;\n bits += 8;\n }\n //===//\n _out -= left;\n strm.total_out += _out;\n state.total += _out;\n if (_out) {\n strm.adler = state.check =\n /*UPDATE(state.check, put - _out, _out);*/\n (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));\n\n }\n _out = left;\n // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too\n if ((state.flags ? hold : zswap32(hold)) !== state.check) {\n strm.msg = 'incorrect data check';\n state.mode = BAD;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n //Tracev((stderr, \"inflate: check matches trailer\\n\"));\n }\n state.mode = LENGTH;\n /* falls through */\n case LENGTH:\n if (state.wrap && state.flags) {\n //=== NEEDBITS(32);\n while (bits < 32) {\n if (have === 0) { break inf_leave; }\n have--;\n hold += input[next++] << bits;\n bits += 8;\n }\n //===//\n if (hold !== (state.total & 0xffffffff)) {\n strm.msg = 'incorrect length check';\n state.mode = BAD;\n break;\n }\n //=== INITBITS();\n hold = 0;\n bits = 0;\n //===//\n //Tracev((stderr, \"inflate: length matches trailer\\n\"));\n }\n state.mode = DONE;\n /* falls through */\n case DONE:\n ret = Z_STREAM_END;\n break inf_leave;\n case BAD:\n ret = Z_DATA_ERROR;\n break inf_leave;\n case MEM:\n return Z_MEM_ERROR;\n case SYNC:\n /* falls through */\n default:\n return Z_STREAM_ERROR;\n }\n }\n\n // inf_leave <- here is real place for \"goto inf_leave\", emulated via \"break inf_leave\"\n\n /*\n Return from inflate(), updating the total counts and the check value.\n If there was no progress during the inflate() call, return a buffer\n error. Call updatewindow() to create and/or update the window state.\n Note: a memory error from inflate() is non-recoverable.\n */\n\n //--- RESTORE() ---\n strm.next_out = put;\n strm.avail_out = left;\n strm.next_in = next;\n strm.avail_in = have;\n state.hold = hold;\n state.bits = bits;\n //---\n\n if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&\n (state.mode < CHECK || flush !== Z_FINISH))) {\n if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {\n state.mode = MEM;\n return Z_MEM_ERROR;\n }\n }\n _in -= strm.avail_in;\n _out -= strm.avail_out;\n strm.total_in += _in;\n strm.total_out += _out;\n state.total += _out;\n if (state.wrap && _out) {\n strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/\n (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));\n }\n strm.data_type = state.bits + (state.last ? 64 : 0) +\n (state.mode === TYPE ? 128 : 0) +\n (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);\n if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {\n ret = Z_BUF_ERROR;\n }\n return ret;\n}\n\nfunction inflateEnd(strm) {\n\n if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {\n return Z_STREAM_ERROR;\n }\n\n var state = strm.state;\n if (state.window) {\n state.window = null;\n }\n strm.state = null;\n return Z_OK;\n}\n\nfunction inflateGetHeader(strm, head) {\n var state;\n\n /* check state */\n if (!strm || !strm.state) { return Z_STREAM_ERROR; }\n state = strm.state;\n if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }\n\n /* save header structure */\n state.head = head;\n head.done = false;\n return Z_OK;\n}\n\nfunction inflateSetDictionary(strm, dictionary) {\n var dictLength = dictionary.length;\n\n var state;\n var dictid;\n var ret;\n\n /* check state */\n if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }\n state = strm.state;\n\n if (state.wrap !== 0 && state.mode !== DICT) {\n return Z_STREAM_ERROR;\n }\n\n /* check for correct dictionary identifier */\n if (state.mode === DICT) {\n dictid = 1; /* adler32(0, null, 0)*/\n /* dictid = adler32(dictid, dictionary, dictLength); */\n dictid = adler32(dictid, dictionary, dictLength, 0);\n if (dictid !== state.check) {\n return Z_DATA_ERROR;\n }\n }\n /* copy dictionary to window using updatewindow(), which will amend the\n existing dictionary if appropriate */\n ret = updatewindow(strm, dictionary, dictLength, dictLength);\n if (ret) {\n state.mode = MEM;\n return Z_MEM_ERROR;\n }\n state.havedict = 1;\n // Tracev((stderr, \"inflate: dictionary set\\n\"));\n return Z_OK;\n}\n\nexports.inflateReset = inflateReset;\nexports.inflateReset2 = inflateReset2;\nexports.inflateResetKeep = inflateResetKeep;\nexports.inflateInit = inflateInit;\nexports.inflateInit2 = inflateInit2;\nexports.inflate = inflate;\nexports.inflateEnd = inflateEnd;\nexports.inflateGetHeader = inflateGetHeader;\nexports.inflateSetDictionary = inflateSetDictionary;\nexports.inflateInfo = 'pako inflate (from Nodeca project)';\n\n/* Not implemented\nexports.inflateCopy = inflateCopy;\nexports.inflateGetDictionary = inflateGetDictionary;\nexports.inflateMark = inflateMark;\nexports.inflatePrime = inflatePrime;\nexports.inflateSync = inflateSync;\nexports.inflateSyncPoint = inflateSyncPoint;\nexports.inflateUndermine = inflateUndermine;\n*/\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nmodule.exports = {\n\n /* Allowed flush values; see deflate() and inflate() below for details */\n Z_NO_FLUSH: 0,\n Z_PARTIAL_FLUSH: 1,\n Z_SYNC_FLUSH: 2,\n Z_FULL_FLUSH: 3,\n Z_FINISH: 4,\n Z_BLOCK: 5,\n Z_TREES: 6,\n\n /* Return codes for the compression/decompression functions. Negative values\n * are errors, positive values are used for special but normal events.\n */\n Z_OK: 0,\n Z_STREAM_END: 1,\n Z_NEED_DICT: 2,\n Z_ERRNO: -1,\n Z_STREAM_ERROR: -2,\n Z_DATA_ERROR: -3,\n //Z_MEM_ERROR: -4,\n Z_BUF_ERROR: -5,\n //Z_VERSION_ERROR: -6,\n\n /* compression levels */\n Z_NO_COMPRESSION: 0,\n Z_BEST_SPEED: 1,\n Z_BEST_COMPRESSION: 9,\n Z_DEFAULT_COMPRESSION: -1,\n\n\n Z_FILTERED: 1,\n Z_HUFFMAN_ONLY: 2,\n Z_RLE: 3,\n Z_FIXED: 4,\n Z_DEFAULT_STRATEGY: 0,\n\n /* Possible values of the data_type field (though see inflate()) */\n Z_BINARY: 0,\n Z_TEXT: 1,\n //Z_ASCII: 1, // = Z_TEXT (deprecated)\n Z_UNKNOWN: 2,\n\n /* The deflate compression method */\n Z_DEFLATED: 8\n //Z_NULL: null // Use -1 or null inline, depending on var type\n};\n","'use strict';\n\n// (C) 1995-2013 Jean-loup Gailly and Mark Adler\n// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin\n//\n// This software is provided 'as-is', without any express or implied\n// warranty. In no event will the authors be held liable for any damages\n// arising from the use of this software.\n//\n// Permission is granted to anyone to use this software for any purpose,\n// including commercial applications, and to alter it and redistribute it\n// freely, subject to the following restrictions:\n//\n// 1. The origin of this software must not be misrepresented; you must not\n// claim that you wrote the original software. If you use this software\n// in a product, an acknowledgment in the product documentation would be\n// appreciated but is not required.\n// 2. Altered source versions must be plainly marked as such, and must not be\n// misrepresented as being the original software.\n// 3. This notice may not be removed or altered from any source distribution.\n\nfunction GZheader() {\n /* true if compressed data believed to be text */\n this.text = 0;\n /* modification time */\n this.time = 0;\n /* extra flags (not used when writing a gzip file) */\n this.xflags = 0;\n /* operating system */\n this.os = 0;\n /* pointer to extra field or Z_NULL if none */\n this.extra = null;\n /* extra field length (valid if extra != Z_NULL) */\n this.extra_len = 0; // Actually, we don't need it in JS,\n // but leave for few code modifications\n\n //\n // Setup limits is not necessary because in js we should not preallocate memory\n // for inflate use constant limit in 65536 bytes\n //\n\n /* space at extra (only when reading header) */\n // this.extra_max = 0;\n /* pointer to zero-terminated file name or Z_NULL */\n this.name = '';\n /* space at name (only when reading header) */\n // this.name_max = 0;\n /* pointer to zero-terminated comment or Z_NULL */\n this.comment = '';\n /* space at comment (only when reading header) */\n // this.comm_max = 0;\n /* true if there was or will be a header crc */\n this.hcrc = 0;\n /* true when done reading gzip header (not used when writing a gzip file) */\n this.done = false;\n}\n\nmodule.exports = GZheader;\n","'use strict';\n\n\nvar zlib_inflate = require('./zlib/inflate');\nvar utils = require('./utils/common');\nvar strings = require('./utils/strings');\nvar c = require('./zlib/constants');\nvar msg = require('./zlib/messages');\nvar ZStream = require('./zlib/zstream');\nvar GZheader = require('./zlib/gzheader');\n\nvar toString = Object.prototype.toString;\n\n/**\n * class Inflate\n *\n * Generic JS-style wrapper for zlib calls. If you don't need\n * streaming behaviour - use more simple functions: [[inflate]]\n * and [[inflateRaw]].\n **/\n\n/* internal\n * inflate.chunks -> Array\n *\n * Chunks of output data, if [[Inflate#onData]] not overridden.\n **/\n\n/**\n * Inflate.result -> Uint8Array|Array|String\n *\n * Uncompressed result, generated by default [[Inflate#onData]]\n * and [[Inflate#onEnd]] handlers. Filled after you push last chunk\n * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you\n * push a chunk with explicit flush (call [[Inflate#push]] with\n * `Z_SYNC_FLUSH` param).\n **/\n\n/**\n * Inflate.err -> Number\n *\n * Error code after inflate finished. 0 (Z_OK) on success.\n * Should be checked if broken data possible.\n **/\n\n/**\n * Inflate.msg -> String\n *\n * Error message, if [[Inflate.err]] != 0\n **/\n\n\n/**\n * new Inflate(options)\n * - options (Object): zlib inflate options.\n *\n * Creates new inflator instance with specified params. Throws exception\n * on bad params. Supported options:\n *\n * - `windowBits`\n * - `dictionary`\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information on these.\n *\n * Additional options, for internal needs:\n *\n * - `chunkSize` - size of generated data chunks (16K by default)\n * - `raw` (Boolean) - do raw inflate\n * - `to` (String) - if equal to 'string', then result will be converted\n * from utf8 to utf16 (javascript) string. When string output requested,\n * chunk length can differ from `chunkSize`, depending on content.\n *\n * By default, when no options set, autodetect deflate/gzip data format via\n * wrapper header.\n *\n * ##### Example:\n *\n * ```javascript\n * var pako = require('pako')\n * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])\n * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);\n *\n * var inflate = new pako.Inflate({ level: 3});\n *\n * inflate.push(chunk1, false);\n * inflate.push(chunk2, true); // true -> last chunk\n *\n * if (inflate.err) { throw new Error(inflate.err); }\n *\n * console.log(inflate.result);\n * ```\n **/\nfunction Inflate(options) {\n if (!(this instanceof Inflate)) return new Inflate(options);\n\n this.options = utils.assign({\n chunkSize: 16384,\n windowBits: 0,\n to: ''\n }, options || {});\n\n var opt = this.options;\n\n // Force window size for `raw` data, if not set directly,\n // because we have no header for autodetect.\n if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {\n opt.windowBits = -opt.windowBits;\n if (opt.windowBits === 0) { opt.windowBits = -15; }\n }\n\n // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate\n if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&\n !(options && options.windowBits)) {\n opt.windowBits += 32;\n }\n\n // Gzip header has no info about windows size, we can do autodetect only\n // for deflate. So, if window size not set, force it to max when gzip possible\n if ((opt.windowBits > 15) && (opt.windowBits < 48)) {\n // bit 3 (16) -> gzipped data\n // bit 4 (32) -> autodetect gzip/deflate\n if ((opt.windowBits & 15) === 0) {\n opt.windowBits |= 15;\n }\n }\n\n this.err = 0; // error code, if happens (0 = Z_OK)\n this.msg = ''; // error message\n this.ended = false; // used to avoid multiple onEnd() calls\n this.chunks = []; // chunks of compressed data\n\n this.strm = new ZStream();\n this.strm.avail_out = 0;\n\n var status = zlib_inflate.inflateInit2(\n this.strm,\n opt.windowBits\n );\n\n if (status !== c.Z_OK) {\n throw new Error(msg[status]);\n }\n\n this.header = new GZheader();\n\n zlib_inflate.inflateGetHeader(this.strm, this.header);\n\n // Setup dictionary\n if (opt.dictionary) {\n // Convert data if needed\n if (typeof opt.dictionary === 'string') {\n opt.dictionary = strings.string2buf(opt.dictionary);\n } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {\n opt.dictionary = new Uint8Array(opt.dictionary);\n }\n if (opt.raw) { //In raw mode we need to set the dictionary early\n status = zlib_inflate.inflateSetDictionary(this.strm, opt.dictionary);\n if (status !== c.Z_OK) {\n throw new Error(msg[status]);\n }\n }\n }\n}\n\n/**\n * Inflate#push(data[, mode]) -> Boolean\n * - data (Uint8Array|Array|ArrayBuffer|String): input data\n * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.\n * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.\n *\n * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with\n * new output chunks. Returns `true` on success. The last data block must have\n * mode Z_FINISH (or `true`). That will flush internal pending buffers and call\n * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you\n * can use mode Z_SYNC_FLUSH, keeping the decompression context.\n *\n * On fail call [[Inflate#onEnd]] with error code and return false.\n *\n * We strongly recommend to use `Uint8Array` on input for best speed (output\n * format is detected automatically). Also, don't skip last param and always\n * use the same type in your code (boolean or number). That will improve JS speed.\n *\n * For regular `Array`-s make sure all elements are [0..255].\n *\n * ##### Example\n *\n * ```javascript\n * push(chunk, false); // push one of data chunks\n * ...\n * push(chunk, true); // push last chunk\n * ```\n **/\nInflate.prototype.push = function (data, mode) {\n var strm = this.strm;\n var chunkSize = this.options.chunkSize;\n var dictionary = this.options.dictionary;\n var status, _mode;\n var next_out_utf8, tail, utf8str;\n\n // Flag to properly process Z_BUF_ERROR on testing inflate call\n // when we check that all output data was flushed.\n var allowBufError = false;\n\n if (this.ended) { return false; }\n _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);\n\n // Convert data if needed\n if (typeof data === 'string') {\n // Only binary strings can be decompressed on practice\n strm.input = strings.binstring2buf(data);\n } else if (toString.call(data) === '[object ArrayBuffer]') {\n strm.input = new Uint8Array(data);\n } else {\n strm.input = data;\n }\n\n strm.next_in = 0;\n strm.avail_in = strm.input.length;\n\n do {\n if (strm.avail_out === 0) {\n strm.output = new utils.Buf8(chunkSize);\n strm.next_out = 0;\n strm.avail_out = chunkSize;\n }\n\n status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */\n\n if (status === c.Z_NEED_DICT && dictionary) {\n status = zlib_inflate.inflateSetDictionary(this.strm, dictionary);\n }\n\n if (status === c.Z_BUF_ERROR && allowBufError === true) {\n status = c.Z_OK;\n allowBufError = false;\n }\n\n if (status !== c.Z_STREAM_END && status !== c.Z_OK) {\n this.onEnd(status);\n this.ended = true;\n return false;\n }\n\n if (strm.next_out) {\n if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) {\n\n if (this.options.to === 'string') {\n\n next_out_utf8 = strings.utf8border(strm.output, strm.next_out);\n\n tail = strm.next_out - next_out_utf8;\n utf8str = strings.buf2string(strm.output, next_out_utf8);\n\n // move tail\n strm.next_out = tail;\n strm.avail_out = chunkSize - tail;\n if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }\n\n this.onData(utf8str);\n\n } else {\n this.onData(utils.shrinkBuf(strm.output, strm.next_out));\n }\n }\n }\n\n // When no more input data, we should check that internal inflate buffers\n // are flushed. The only way to do it when avail_out = 0 - run one more\n // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.\n // Here we set flag to process this error properly.\n //\n // NOTE. Deflate does not return error in this case and does not needs such\n // logic.\n if (strm.avail_in === 0 && strm.avail_out === 0) {\n allowBufError = true;\n }\n\n } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END);\n\n if (status === c.Z_STREAM_END) {\n _mode = c.Z_FINISH;\n }\n\n // Finalize on the last chunk.\n if (_mode === c.Z_FINISH) {\n status = zlib_inflate.inflateEnd(this.strm);\n this.onEnd(status);\n this.ended = true;\n return status === c.Z_OK;\n }\n\n // callback interim results if Z_SYNC_FLUSH.\n if (_mode === c.Z_SYNC_FLUSH) {\n this.onEnd(c.Z_OK);\n strm.avail_out = 0;\n return true;\n }\n\n return true;\n};\n\n\n/**\n * Inflate#onData(chunk) -> Void\n * - chunk (Uint8Array|Array|String): output data. Type of array depends\n * on js engine support. When string output requested, each chunk\n * will be string.\n *\n * By default, stores data blocks in `chunks[]` property and glue\n * those in `onEnd`. Override this handler, if you need another behaviour.\n **/\nInflate.prototype.onData = function (chunk) {\n this.chunks.push(chunk);\n};\n\n\n/**\n * Inflate#onEnd(status) -> Void\n * - status (Number): inflate status. 0 (Z_OK) on success,\n * other if not.\n *\n * Called either after you tell inflate that the input stream is\n * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)\n * or if an error happened. By default - join collected chunks,\n * free memory and fill `results` / `err` properties.\n **/\nInflate.prototype.onEnd = function (status) {\n // On success - join\n if (status === c.Z_OK) {\n if (this.options.to === 'string') {\n // Glue & convert here, until we teach pako to send\n // utf8 aligned strings to onData\n this.result = this.chunks.join('');\n } else {\n this.result = utils.flattenChunks(this.chunks);\n }\n }\n this.chunks = [];\n this.err = status;\n this.msg = this.strm.msg;\n};\n\n\n/**\n * inflate(data[, options]) -> Uint8Array|Array|String\n * - data (Uint8Array|Array|String): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * Decompress `data` with inflate/ungzip and `options`. Autodetect\n * format via wrapper header by default. That's why we don't provide\n * separate `ungzip` method.\n *\n * Supported options are:\n *\n * - windowBits\n *\n * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)\n * for more information.\n *\n * Sugar (options):\n *\n * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify\n * negative windowBits implicitly.\n * - `to` (String) - if equal to 'string', then result will be converted\n * from utf8 to utf16 (javascript) string. When string output requested,\n * chunk length can differ from `chunkSize`, depending on content.\n *\n *\n * ##### Example:\n *\n * ```javascript\n * var pako = require('pako')\n * , input = pako.deflate([1,2,3,4,5,6,7,8,9])\n * , output;\n *\n * try {\n * output = pako.inflate(input);\n * } catch (err)\n * console.log(err);\n * }\n * ```\n **/\nfunction inflate(input, options) {\n var inflator = new Inflate(options);\n\n inflator.push(input, true);\n\n // That will never happens, if you don't cheat with options :)\n if (inflator.err) { throw inflator.msg || msg[inflator.err]; }\n\n return inflator.result;\n}\n\n\n/**\n * inflateRaw(data[, options]) -> Uint8Array|Array|String\n * - data (Uint8Array|Array|String): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * The same as [[inflate]], but creates raw data, without wrapper\n * (header and adler32 crc).\n **/\nfunction inflateRaw(input, options) {\n options = options || {};\n options.raw = true;\n return inflate(input, options);\n}\n\n\n/**\n * ungzip(data[, options]) -> Uint8Array|Array|String\n * - data (Uint8Array|Array|String): input data to decompress.\n * - options (Object): zlib inflate options.\n *\n * Just shortcut to [[inflate]], because it autodetects format\n * by header.content. Done for convenience.\n **/\n\n\nexports.Inflate = Inflate;\nexports.inflate = inflate;\nexports.inflateRaw = inflateRaw;\nexports.ungzip = inflate;\n","// Top level file is just a mixin of submodules & constants\n'use strict';\n\nvar assign = require('./lib/utils/common').assign;\n\nvar deflate = require('./lib/deflate');\nvar inflate = require('./lib/inflate');\nvar constants = require('./lib/zlib/constants');\n\nvar pako = {};\n\nassign(pako, deflate, inflate, constants);\n\nmodule.exports = pako;\n","export function showloading(txt) {\r\n $(\"#luckysheet-cell-loading\").find(\"span\").text(txt).end().show();\r\n};\r\n\r\nexport function hideloading() {\r\n $(\"#luckysheet-cell-loading\").hide();\r\n};","import Store from '../store';\r\nimport luckysheetConfigsetting from '../controllers/luckysheetConfigsetting';\r\n\r\nexport default function rhchInit(rowheight, colwidth) {\r\n zoomSetting();//Zoom sheet on first load\r\n //行高\r\n if(rowheight != null){\r\n Store.visibledatarow = [];\r\n Store.rh_height = 0;\r\n\r\n for (let r = 0; r < rowheight; r++) {\r\n let rowlen = Store.defaultrowlen;\r\n\r\n if (Store.config[\"rowlen\"] != null && Store.config[\"rowlen\"][r] != null) {\r\n rowlen = Store.config[\"rowlen\"][r];\r\n }\r\n\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n Store.visibledatarow.push(Store.rh_height);\r\n continue;\r\n }\r\n \r\n Store.rh_height += Math.round((rowlen + 1) * Store.zoomRatio);\r\n\r\n Store.visibledatarow.push(Store.rh_height); //行的临时长度分布\r\n }\r\n\r\n // 如果增加行和回到顶部按钮隐藏,则减少底部空白区域,但是预留足够空间给单元格下拉按钮\r\n if(!luckysheetConfigsetting.enableAddRow && !luckysheetConfigsetting.enableAddBackTop){\r\n Store.rh_height += 29;\r\n }else{\r\n Store.rh_height += 80; //最底部增加空白\r\n }\r\n \r\n }\r\n\r\n //列宽\r\n if(colwidth != null){\r\n Store.visibledatacolumn = [];\r\n Store.ch_width = 0;\r\n\r\n let maxColumnlen = 120;\r\n\r\n for (let c = 0; c < colwidth; c++) {\r\n let firstcolumnlen = Store.defaultcollen;\r\n\r\n if (Store.config[\"columnlen\"] != null && Store.config[\"columnlen\"][c] != null) {\r\n firstcolumnlen = Store.config[\"columnlen\"][c];\r\n }\r\n else {\r\n if (Store.flowdata[0] != null && Store.flowdata[0][c] != null) {\r\n if (firstcolumnlen > 300) {\r\n firstcolumnlen = 300;\r\n }\r\n else if (firstcolumnlen < Store.defaultcollen) {\r\n firstcolumnlen = Store.defaultcollen;\r\n }\r\n\r\n if (firstcolumnlen != Store.defaultcollen) {\r\n if (Store.config[\"columnlen\"] == null) {\r\n Store.config[\"columnlen\"] = {};\r\n }\r\n\r\n Store.config[\"columnlen\"][c] = firstcolumnlen;\r\n }\r\n }\r\n }\r\n\r\n if(Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][c] != null){\r\n Store.visibledatacolumn.push(Store.ch_width);\r\n continue;\r\n }\r\n\r\n Store.ch_width += Math.round((firstcolumnlen + 1)*Store.zoomRatio);\r\n\r\n Store.visibledatacolumn.push(Store.ch_width);//列的临时长度分布\r\n\r\n // if(maxColumnlen < firstcolumnlen + 1){\r\n // maxColumnlen = firstcolumnlen + 1;\r\n // }\r\n }\r\n \r\n // Store.ch_width += 120;\r\n Store.ch_width += maxColumnlen;\r\n }\r\n}\r\n\r\n\r\nexport function zoomSetting(){\r\n //zoom\r\n Store.rowHeaderWidth = luckysheetConfigsetting.rowHeaderWidth * Store.zoomRatio;\r\n Store.columnHeaderHeight = luckysheetConfigsetting.columnHeaderHeight *Store.zoomRatio;\r\n $(\"#luckysheet-rows-h\").width((Store.rowHeaderWidth-1.5));\r\n $(\"#luckysheet-cols-h-c\").height((Store.columnHeaderHeight-1.5));\r\n $(\"#luckysheet-left-top\").css({width:Store.rowHeaderWidth-1.5, height:Store.columnHeaderHeight-1.5});\r\n}","import { getObjType } from '../utils/util';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport Store from '../store';\r\n\r\n//动态数组计算\r\nfunction dynamicArrayCompute(dynamicArray) {\r\n let dynamicArray_compute = {};\r\n\r\n if(getObjType(dynamicArray) == \"array\"){\r\n for(let i = 0; i < dynamicArray.length; i++){\r\n let d_row = dynamicArray[i].r;\r\n let d_col = dynamicArray[i].c;\r\n let d_f = dynamicArray[i].f;\r\n \r\n if(Store.flowdata[d_row][d_col] != null && Store.flowdata[d_row][d_col].f != null && Store.flowdata[d_row][d_col].f == d_f){\r\n if((d_row + \"_\" + d_col) in dynamicArray_compute){\r\n dynamicArray_compute = dynamicArraySpillEditCompute(dynamicArray_compute, d_row , d_col);\r\n }\r\n\r\n let d_data = dynamicArray[i].data;\r\n let d_rowlen = d_data.length;\r\n let d_collen = 1;\r\n\r\n if(getObjType(d_data[0]) == \"array\"){\r\n d_collen = d_data[0].length;\r\n }\r\n\r\n if(dynamicArrayRangeIsAllNull({ \"row\": [d_row, d_row + d_rowlen - 1], \"column\": [d_col, d_col + d_collen - 1] }, Store.flowdata)){\r\n for(let x = 0; x < d_rowlen; x++){\r\n for(let y = 0; y < d_collen; y++){\r\n let rowIndex = d_row + x;\r\n let colIndex = d_col + y;\r\n\r\n if(getObjType(d_data[0]) == \"array\"){\r\n dynamicArray_compute[rowIndex + \"_\" + colIndex] = {\"v\": d_data[x][y], \"r\": d_row, \"c\": d_col};\r\n }\r\n else{\r\n dynamicArray_compute[rowIndex + \"_\" + colIndex] = {\"v\": d_data[x], \"r\": d_row, \"c\": d_col};\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n dynamicArray_compute[d_row + \"_\" + d_col] = {\"v\": \"#SPILL!\", \"r\": d_row, \"c\": d_col};\r\n }\r\n }\r\n }\r\n }\r\n\r\n return dynamicArray_compute; \r\n}\r\n\r\nfunction dynamicArraySpillEditCompute(computeObj, r, c) {\r\n let rowIndex = computeObj[r + \"_\" + c].r;\r\n let colIndex = computeObj[r + \"_\" + c].c;\r\n\r\n for(let x in computeObj){\r\n if(x == (rowIndex + \"_\" + colIndex)){\r\n computeObj[x].v = \"#SPILL!\";\r\n }\r\n else if(computeObj[x].r == rowIndex && computeObj[x].c == colIndex){\r\n delete computeObj[x];\r\n }\r\n }\r\n\r\n return computeObj;\r\n}\r\n\r\n//范围是否都是空单元格(除第一个单元格)\r\nfunction dynamicArrayRangeIsAllNull(range, data) {\r\n let r1 = range[\"row\"][0], r2 = range[\"row\"][1];\r\n let c1 = range[\"column\"][0], c2 = range[\"column\"][1];\r\n\r\n let isAllNull = true;\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n if(!(r == r1 && c == c1) && data[r][c] != null && data[r][c].v != null && data[r][c].v.toString() != \"\"){\r\n isAllNull = false;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return isAllNull;\r\n}\r\n\r\n//点击表格区域是否属于动态数组区域\r\nfunction dynamicArrayHightShow(r, c) {\r\n let dynamicArray = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray\"] == null ? [] : Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray\"];\r\n let dynamicArray_compute = dynamicArrayCompute(dynamicArray);\r\n\r\n if((r + \"_\" + c) in dynamicArray_compute && dynamicArray_compute[r + \"_\" + c].v != \"#SPILL!\"){\r\n let d_row = dynamicArray_compute[r + \"_\" + c].r;\r\n let d_col = dynamicArray_compute[r + \"_\" + c].c;\r\n\r\n let d_f = Store.flowdata[d_row][d_col].f;\r\n\r\n let rlen, clen;\r\n for(let i = 0; i < dynamicArray.length; i++){\r\n if(dynamicArray[i].f == d_f){\r\n rlen = dynamicArray[i].data.length;\r\n\r\n if(getObjType(dynamicArray[i].data[0]) == \"array\"){\r\n clen = dynamicArray[i].data[0].length;\r\n }\r\n else{\r\n clen = 1;\r\n }\r\n }\r\n }\r\n\r\n let d_row_end = d_row + rlen - 1;\r\n let d_col_end = d_col + clen - 1;\r\n\r\n let row = Store.visibledatarow[d_row_end], \r\n row_pre = d_row - 1 == -1 ? 0 : Store.visibledatarow[d_row - 1];\r\n let col = Store.visibledatacolumn[d_col_end], \r\n col_pre = d_col - 1 == -1 ? 0 : Store.visibledatacolumn[d_col - 1];\r\n\r\n $(\"#luckysheet-dynamicArray-hightShow\").css({ \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1, \r\n \"display\": \"block\" \r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-dynamicArray-hightShow\").hide();\r\n }\r\n}\r\n\r\nexport {\r\n dynamicArrayCompute,\r\n dynamicArraySpillEditCompute,\r\n dynamicArrayRangeIsAllNull,\r\n dynamicArrayHightShow,\r\n}","import Store from '../store';\r\n\r\nfunction luckysheetRangeLast(obj) {\r\n let range;\r\n \r\n if(document.createRange){ //chrome, firefox, opera, safari, ie9+\r\n if(obj.innerHTML != obj.innerText || obj.innerHTML == \"\"){\r\n obj.focus(); //解决ff不获取焦点无法定位问题\r\n range = window.getSelection();//创建range\r\n range.selectAllChildren(obj);//range 选择obj下所有子内容\r\n range.collapseToEnd();//光标移至最后\r\n }\r\n else{\r\n let len = obj.innerText.length;\r\n\r\n range = document.createRange();\r\n range.selectNodeContents(obj);\r\n range.setStart(obj.childNodes[0], len);\r\n range.collapse(true);\r\n\r\n let selection = window.getSelection();\r\n selection.removeAllRanges();\r\n selection.addRange(range); \r\n }\r\n }\r\n else if(document.selection){ //ie8 and lower\r\n range = document.body.createTextRange();\r\n range.moveToElementText(obj);\r\n range.collapse(false);\r\n range.select();\r\n }\r\n}\r\n\r\nfunction getCursortPosition(textDom){\r\n let cursorPos = 0;\r\n \r\n if(document.selection){\r\n textDom.focus();\r\n let selectRange = document.selection.createRange();\r\n selectRange.moveStart(\"character\", -textDom.value.length);\r\n cursorPos = selectRange.text.length;\r\n }\r\n else if(textDom.selectionStart || textDom.selectionStart == \"0\"){\r\n cursorPos = textDom.selectionStart;\r\n }\r\n\r\n return cursorPos;\r\n}\r\n\r\nfunction hideMenuByCancel(event){\r\n\r\n // Right-click the menu in the title bar, and click on the elements whose class is luckysheet-cols-rows-shift-left and luckysheet-cols-rows-shift-right will trigger the hiding of the menu bar. It should be prohibited. Exclude these two elements. There may be more Other elements will also jump here for more testing\r\n\r\n if(event.target.classList.contains('luckysheet-cols-rows-shift-left') || event.target.classList.contains('luckysheet-cols-rows-shift-right')){\r\n return;\r\n }\r\n\r\n if (!$(event.target).hasClass(\"luckysheet-mousedown-cancel\") && $(event.target).filter(\"[class*='sp-palette']\").length == 0 && $(event.target).filter(\"[class*='sp-thumb']\").length == 0 && $(event.target).filter(\"[class*='sp-']\").length == 0) {\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\"#luckysheet-cols-h-hover\").hide();\r\n $(\"#luckysheet-cols-menu-btn\").hide();\r\n // $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu, #luckysheet-user-menu\").hide();\r\n $(\"body > .luckysheet-filter-menu, body > .luckysheet-filter-submenu, body > .luckysheet-cols-menu\").hide();\r\n //$(\"body > luckysheet-menuButton\").hide();\r\n Store.luckysheet_cols_menu_status = false;\r\n }\r\n}\r\n\r\nfunction selectTextDom(ele){\r\n if (window.getSelection) {\r\n let range = document.createRange();\r\n range.selectNodeContents(ele);\r\n if(range.startContainer && isInPage(range.startContainer)){\r\n window.getSelection().removeAllRanges();\r\n window.getSelection().addRange(range);\r\n }\r\n }\r\n else if (document.selection) {\r\n let range = document.body.createTextRange();\r\n range.moveToElementText(ele);\r\n range.select();\r\n } \r\n}\r\n\r\nfunction selectTextContent(ele){\r\n if (window.getSelection) {\r\n let range = document.createRange();\r\n var content=ele.firstChild;\r\n range.setStart(content,0);\r\n range.setEnd(content,content.length);\r\n if(range.startContainer && isInPage(range.startContainer)){\r\n window.getSelection().removeAllRanges();\r\n window.getSelection().addRange(range);\r\n }\r\n }\r\n else if (document.selection) {\r\n let range = document.body.createTextRange();\r\n range.moveToElementText(ele);\r\n range.select();\r\n } \r\n}\r\n\r\nfunction selectTextContentCross(sEle, eEle){\r\n if (window.getSelection) {\r\n let range = document.createRange();\r\n var sContent=sEle.firstChild, eContent=eEle.firstChild;\r\n range.setStart(sContent,0);\r\n range.setEnd(eContent,eContent.length);\r\n if(range.startContainer && isInPage(range.startContainer)){\r\n window.getSelection().removeAllRanges();\r\n window.getSelection().addRange(range);\r\n }\r\n }\r\n}\r\n\r\nfunction selectTextContentCollapse(sEle, index){\r\n if (window.getSelection) {\r\n let range = document.createRange();\r\n var sContent=sEle.firstChild;\r\n if(index>sContent.length){\r\n index=sContent.length;\r\n }\r\n else if(index<0){\r\n index = 0;\r\n }\r\n range.setStart(sContent,index);\r\n range.collapse(true);\r\n if(range.startContainer && isInPage(range.startContainer)){\r\n window.getSelection().removeAllRanges();\r\n window.getSelection().addRange(range);\r\n }\r\n\r\n }\r\n}\r\n\r\nfunction isInPage(node) {\r\n return (node === document.body) ? false : document.body.contains(node);\r\n}\r\n\r\nexport {\r\n luckysheetRangeLast,\r\n getCursortPosition,\r\n hideMenuByCancel,\r\n selectTextContent,\r\n selectTextDom,\r\n selectTextContentCross,\r\n selectTextContentCollapse\r\n}","import {getFontStyleByCell, textTrim} from \"../global/getdata\";\r\nimport {selectTextContent,selectTextContentCross,selectTextContentCollapse} from '../global/cursorPos';\r\nimport locale from '../locale/locale';\r\nimport Store from '../store';\r\n\r\nexport const inlineStyleAffectAttribute = {\"bl\":1, \"it\":1 , \"ff\":1, \"cl\":1, \"un\":1,\"fs\":1,\"fc\":1};\r\nexport const inlineStyleAffectCssName = {\"font-weight\":1, \"font-style\":1 , \"font-family\":1, \"text-decoration\":1, \"border-bottom\":1,\"font-size\":1,\"color\":1};\r\n\r\nexport function isInlineStringCell(cell){\r\n let isIs = cell && cell.ct!=null && cell.ct.t==\"inlineStr\" && cell.ct.s!=null && cell.ct.s.length>0;\r\n return isIs; \r\n}\r\n\r\nexport function isInlineStringCT(ct){\r\n let isIs = ct!=null && ct.t==\"inlineStr\" && ct.s!=null && ct.s.length>0;\r\n return isIs; \r\n}\r\n\r\nexport function updateInlineStringFormat(cell, attr, value, $input){\r\n // let s = Store.inlineStringEditCache;\r\n var w = window.getSelection(); \r\n var range;\r\n if(w.type==\"None\"){\r\n range = Store.inlineStringEditRange;\r\n }\r\n else{\r\n range = w.getRangeAt(0);\r\n } \r\n \r\n\r\n // if(isInlineStringCell(cell)){\r\n // if(Store.inlineStringEditCache==null){\r\n // Store.inlineStringEditCache = JSON.parse(JSON.stringify(cell.ct.s));\r\n // }\r\n // }\r\n // else{\r\n // Store.inlineStringEditCache = [{\r\n // v:cell.v\r\n // }];\r\n // }\r\n\r\n let cac = range.commonAncestorContainer;\r\n let $textEditor;\r\n if(cac.id==\"luckysheet-rich-text-editor\"){\r\n $textEditor = $(cac);\r\n }\r\n else{\r\n $textEditor = $(cac).closest(\"#luckysheet-rich-text-editor\");\r\n }\r\n let $functionbox = $(cac).closest(\"#luckysheet-functionbox-cell\");\r\n\r\n if($textEditor.length==0 && $functionbox.length==0 && Store.inlineStringEditRange!=null){\r\n range = Store.inlineStringEditRange;\r\n cac = range.commonAncestorContainer;\r\n if(cac.id==\"luckysheet-rich-text-editor\"){\r\n $textEditor = $(cac);\r\n }\r\n else{\r\n $textEditor = $(cac).closest(\"#luckysheet-rich-text-editor\");\r\n }\r\n $functionbox = $(cac).closest(\"#luckysheet-functionbox-cell\");\r\n }\r\n\r\n if(range.collapsed===true){\r\n return;\r\n }\r\n\r\n let endContainer = range.endContainer, startContainer = range.startContainer;\r\n let endOffset = range.endOffset, startOffset = range.startOffset;\r\n\r\n if($textEditor.length>0){\r\n if(startContainer===endContainer){\r\n let span = startContainer.parentNode, spanIndex, inherit=false;\r\n \r\n let content = span.innerHTML;\r\n\r\n let fullContent = $textEditor.html();\r\n if(fullContent.substr(0,5) != \"\" + left + \"\";\r\n }\r\n\r\n if(mid!=\"\"){\r\n // let styleObj = {};\r\n // styleObj[attr] = value;\r\n // let s = getFontStyleByCell(styleObj, undefined, undefined, false);\r\n // let ukey = textTrim(s.substr(0, s.indexOf(':')));\r\n // let uvalue = textTrim(s.substr(s.indexOf(':')+1));\r\n // uvalue = uvalue.substr(0, uvalue.length-1);\r\n // let cssText = span.style.cssText;\r\n // cssText = removeClassWidthCss(cssText, attr);\r\n\r\n let cssText = getCssText(span.style.cssText, attr, value);\r\n\r\n if(inherit){\r\n let box = $(span).closest(\"#luckysheet-input-box\").get(0);\r\n if(box!=null){\r\n cssText = extendCssText(box.style.cssText, cssText);\r\n }\r\n }\r\n \r\n cont += \"\" + mid + \"\";\r\n }\r\n\r\n if(right!=\"\"){\r\n let cssText = span.style.cssText;\r\n if(inherit){\r\n let box = $(span).closest(\"#luckysheet-input-box\").get(0);\r\n if(box!=null){\r\n cssText = extendCssText(box.style.cssText, cssText);\r\n }\r\n }\r\n cont += \"\" + right + \"\";\r\n }\r\n\r\n if(startContainer.parentNode.tagName==\"SPAN\"){\r\n spanIndex = $textEditor.find(\"span\").index(span);\r\n $(span).replaceWith(cont);\r\n }\r\n else{\r\n spanIndex = 0;\r\n $(span).html(cont);\r\n }\r\n \r\n\r\n let seletedNodeIndex = 0;\r\n if(s1==s2){\r\n seletedNodeIndex = spanIndex;\r\n }\r\n else{\r\n seletedNodeIndex = spanIndex+1;\r\n }\r\n\r\n selectTextContent($textEditor.find(\"span\").get(seletedNodeIndex));\r\n }\r\n else{\r\n if(startContainer.parentNode.tagName==\"SPAN\" && endContainer.parentNode.tagName==\"SPAN\"){\r\n let startSpan = startContainer.parentNode, startSpanIndex;\r\n let endSpan = endContainer.parentNode, endSpanIndex;\r\n\r\n startSpanIndex = $textEditor.find(\"span\").index(startSpan);\r\n endSpanIndex = $textEditor.find(\"span\").index(endSpan);\r\n\r\n let startContent = startSpan.innerHTML, endContent = endSpan.innerHTML;\r\n let sleft=\"\" , sright=\"\", eleft=\"\" , eright=\"\";\r\n let s1=0, s2=startOffset, s3 = endOffset, s4=endContent.length;\r\n\r\n sleft = startContent.substring(s1, s2);\r\n sright = startContent.substring(s2, startContent.length);\r\n\r\n eleft = endContent.substring(0, s3);\r\n eright = endContent.substring(s3, s4);\r\n let spans = $textEditor.find(\"span\");\r\n let replaceSpans = spans.slice(startSpanIndex, endSpanIndex+1);\r\n let cont = \"\";\r\n for(let i=0;i\" + content + \"\";\r\n }\r\n if(sleft!=\"\"){\r\n cont += \"\" + sleft + \"\";\r\n }\r\n\r\n if(sright!=\"\"){\r\n let cssText = getCssText(startSpan.style.cssText, attr, value);\r\n cont += \"\" + sright + \"\";\r\n }\r\n\r\n if(startSpanIndex\" + content + \"\";\r\n }\r\n }\r\n\r\n if(eleft!=\"\"){\r\n let cssText = getCssText(endSpan.style.cssText, attr, value);\r\n cont += \"\" + eleft + \"\";\r\n } \r\n \r\n if(eright!=\"\"){\r\n cont += \"\" + eright + \"\";\r\n }\r\n\r\n for(let i=endSpanIndex+1;i\" + content + \"\";\r\n }\r\n\r\n $textEditor.html(cont);\r\n\r\n // console.log(replaceSpans, cont);\r\n // replaceSpans.replaceWith(cont);\r\n\r\n let startSeletedNodeIndex, endSeletedNodeIndex;\r\n if(s1==s2){\r\n startSeletedNodeIndex = startSpanIndex;\r\n endSeletedNodeIndex = endSpanIndex;\r\n }\r\n else{\r\n startSeletedNodeIndex = startSpanIndex+1;\r\n endSeletedNodeIndex = endSpanIndex+1;\r\n }\r\n\r\n spans = $textEditor.find(\"span\");\r\n\r\n selectTextContentCross(spans.get(startSeletedNodeIndex), spans.get(endSeletedNodeIndex));\r\n }\r\n }\r\n }\r\n else if($functionbox.length>0){\r\n\r\n }\r\n}\r\n\r\nexport function enterKeyControll(cell){\r\n var w = window.getSelection(); \r\n \r\n if(w.type==\"None\"){\r\n return\r\n }\r\n var range = w.getRangeAt(0);\r\n let cac = range.commonAncestorContainer;\r\n let $textEditor;\r\n if(cac.id==\"luckysheet-rich-text-editor\"){\r\n $textEditor = $(cac);\r\n }\r\n else{\r\n $textEditor = $(cac).closest(\"#luckysheet-rich-text-editor\");\r\n }\r\n let $functionbox = $(cac).closest(\"#luckysheet-functionbox-cell\");\r\n\r\n // if(range.collapsed===true){\r\n // return;\r\n // }\r\n\r\n let endContainer = range.endContainer, startContainer = range.startContainer;\r\n let endOffset = range.endOffset, startOffset = range.startOffset;\r\n \r\n if($textEditor.length>0){\r\n let startSpan = startContainer.parentNode;\r\n if(startContainer.id==\"luckysheet-rich-text-editor\"){\r\n startSpan = $(startContainer).find(\"span\");\r\n if(startSpan.length==0){\r\n startContainer.innerHTML = \"\";\r\n startSpan = $(startContainer).find(\"span\");\r\n }\r\n startSpan = startSpan.get(startSpan.length-1);\r\n startOffset = startSpan.innerHTML.length;\r\n }\r\n // let startSpanIndex = $textEditor.find(\"span\").index(startSpan);\r\n if(range.collapsed===false){\r\n range.deleteContents();\r\n }\r\n\r\n let startContent = startSpan.innerHTML;\r\n let sleft=\"\" , sright=\"\";\r\n let s1=0, s2=startOffset;\r\n\r\n sleft = startContent.substring(s1, s2);\r\n sright = startContent.substring(s2, startContent.length);\r\n\r\n \r\n let spanIndex,cont;\r\n if(startContainer.parentNode.tagName==\"SPAN\"){\r\n let textSpan = $textEditor.find(\"span\");\r\n spanIndex = textSpan.index(startSpan);\r\n if((spanIndex==textSpan.length-1) && sright==\"\"){\r\n let txt = textSpan[spanIndex].innerHTML;\r\n if(txt.substr(txt.length-1, 1)==\"\\n\"){\r\n cont = \"\" + sleft + \"\\n\" + \"\";\r\n }\r\n else{\r\n cont = \"\" + sleft + \"\\n\\n\" + \"\";\r\n }\r\n \r\n }\r\n else{\r\n cont = \"\" + sleft + \"\\n\" + sright + \"\";\r\n }\r\n \r\n $(startSpan).replaceWith(cont);\r\n }\r\n else{\r\n \r\n let cssText = getFontStyleByCell(cell);\r\n if(sright==\"\"){\r\n cont = \"\" + sleft + \"\\n\\n\" + \"\";\r\n }\r\n else{\r\n cont = \"\" + sleft + \"\\n\" + sright + \"\";\r\n }\r\n \r\n if(startContainer.id==\"luckysheet-rich-text-editor\"){\r\n $(startSpan).replaceWith(cont);\r\n let textSpan = $textEditor.find(\"span\");\r\n spanIndex = textSpan.length-1;\r\n startOffset = textSpan.get(spanIndex).innerHTML.length-1;\r\n }\r\n else{\r\n $(startSpan).html(cont);\r\n spanIndex = 0;\r\n }\r\n \r\n }\r\n\r\n selectTextContentCollapse($textEditor.find(\"span\").get(spanIndex), startOffset+1);\r\n\r\n }\r\n else if($functionbox.length>0){\r\n\r\n }\r\n}\r\n\r\nexport function updateInlineStringFormatOutside(cell, key, value){\r\n if(cell.ct==null){\r\n return;\r\n }\r\n let s = cell.ct.s;\r\n if(s==null){\r\n return;\r\n }\r\n for(let i=0;i {\r\n s = s.toLowerCase();\r\n let key = textTrim(s.substr(0, s.indexOf(':')));\r\n let value = textTrim(s.substr(s.indexOf(':') + 1));\r\n if(key==\"font-weight\"){\r\n if(value==\"bold\"){\r\n styleList[\"bl\"] = 1;\r\n }\r\n else{\r\n styleList[\"bl\"] = 0;\r\n }\r\n }\r\n\r\n if(key==\"font-style\"){\r\n if(value==\"italic\"){\r\n styleList[\"it\"] = 1;\r\n }\r\n else{\r\n styleList[\"it\"] = 0;\r\n }\r\n }\r\n\r\n if(key==\"font-family\"){\r\n let ff = locale_fontjson[value];\r\n if(ff==null){\r\n styleList[\"ff\"] = value;\r\n }\r\n else{\r\n styleList[\"ff\"] = ff;\r\n }\r\n }\r\n\r\n if(key==\"font-size\"){\r\n styleList[\"fs\"] = parseInt(value);\r\n }\r\n\r\n if(key==\"color\"){\r\n styleList[\"fc\"] = value;\r\n }\r\n\r\n if(key==\"text-decoration\"){\r\n styleList[\"cl\"] = 1;\r\n }\r\n\r\n if(key==\"border-bottom\"){\r\n styleList[\"un\"] = 1;\r\n }\r\n\r\n if(key==\"lucky-strike\"){\r\n styleList[\"cl\"] = value;\r\n }\r\n\r\n if(key==\"lucky-underline\"){\r\n styleList[\"un\"] = value;\r\n }\r\n\r\n });\r\n\r\n return styleList;\r\n}\r\n\r\nconst luckyToCssName = {\r\n \"bl\":\"font-weight\",\r\n \"it\":\"font-style\",\r\n \"ff\":\"font-family\",\r\n \"fs\":\"font-size\",\r\n \"fc\":\"color\",\r\n \"cl\":\"text-decoration\",\r\n \"un\":\"border-bottom\",\r\n}\r\n\r\nfunction getClassWithcss(cssText, ukey){\r\n let cssTextArray = cssText.split(\";\");\r\n if(ukey==null || ukey.length==0){\r\n return cssText;\r\n }\r\n if(cssText.indexOf(ukey)>-1){\r\n for(let i=0;i-1){\r\n for(let i=0;i0){\r\n newCss += key + \":\" + value + \";\";\r\n }\r\n }\r\n }\r\n else if(ukey.length>0){\r\n cssText += ukey + \":\" + uvalue + \";\"; \r\n newCss = cssText;\r\n }\r\n\r\n return newCss;\r\n}\r\n\r\nfunction removeClassWidthCss(cssText, ukey){\r\n let cssTextArray = cssText.split(\";\");\r\n let newCss = \"\";\r\n let oUkey = ukey;\r\n if(ukey==null || ukey.length==0){\r\n return cssText;\r\n }\r\n if(ukey in luckyToCssName){\r\n ukey = luckyToCssName[ukey];\r\n }\r\n if(cssText.indexOf(ukey)>-1){\r\n for(let i=0;i0){\r\n newCss += key + \":\" + value + \";\";\r\n }\r\n }\r\n }\r\n else{\r\n newCss = cssText;\r\n }\r\n\r\n return newCss;\r\n}\r\n\r\nfunction getCssText(cssText, attr, value){\r\n let styleObj = {};\r\n styleObj[attr] = value;\r\n if(attr==\"un\"){\r\n let fontColor = getClassWithcss(cssText,\"color\");\r\n if(fontColor==\"\"){\r\n fontColor = \"#000000\";\r\n }\r\n let fs = getClassWithcss(cssText,\"font-size\");\r\n if(fs==\"\"){\r\n fs = 11;\r\n }\r\n fs = parseInt(fs);\r\n styleObj[\"_fontSize\"] = fs;\r\n styleObj[\"_color\"] = fontColor;\r\n }\r\n let s = getFontStyleByCell(styleObj, undefined, undefined, false);\r\n let ukey = textTrim(s.substr(0, s.indexOf(':')));\r\n let uvalue = textTrim(s.substr(s.indexOf(':')+1));\r\n uvalue = uvalue.substr(0, uvalue.length-1);\r\n // let cssText = span.style.cssText;\r\n cssText = removeClassWidthCss(cssText, attr);\r\n\r\n cssText = upsetClassWithCss(cssText, ukey, uvalue);\r\n\r\n return cssText;\r\n}\r\n\r\nfunction extendCssText(origin, cover, isLimit=true){\r\n let originArray = origin.split(\";\");\r\n let coverArray = cover.split(\";\");\r\n let newCss = \"\";\r\n \r\n let addKeyList = {};\r\n for(let i=0;i\" + strObj.v + \"\";\r\n }\r\n }\r\n return value;\r\n }\r\n\r\n return \"\";\r\n}\r\n\r\nexport function getFontStyleByCell(cell,checksAF,checksCF, isCheck=true){\r\n if(cell==null){\r\n return;\r\n }\r\n let style = \"\";\r\n const _locale = locale();\r\n const locale_fontarray = _locale.fontarray;\r\n for(let key in cell){\r\n let value = cell[key];\r\n if(isCheck){\r\n value = checkstatusByCell(cell, key);\r\n }\r\n if(key == \"bl\" && value != \"0\"){\r\n style += \"font-weight: bold;\";\r\n }\r\n\r\n if(key == \"it\" && value != \"0\"){\r\n style += \"font-style:italic;\";\r\n }\r\n\r\n if(key == \"ff\"){\r\n let f = value;\r\n if(!isNaN(parseInt(value))){\r\n f = locale_fontarray[parseInt(value)];\r\n }\r\n else{\r\n f = value;\r\n }\r\n style += \"font-family: \" + f + \";\";\r\n }\r\n\r\n if(key == \"fs\" && value != \"10\"){\r\n style += \"font-size: \"+ value + \"pt;\";\r\n }\r\n\r\n if((key == \"fc\" && value != \"#000000\") || checksAF != null || (checksCF != null && checksCF[\"textColor\"] != null)){\r\n if(checksCF != null && checksCF[\"textColor\"] != null){\r\n style += \"color: \" + checksCF[\"textColor\"] + \";\";\r\n }\r\n else if(checksAF != null){\r\n style += \"color: \" + checksAF[0] + \";\";\r\n }\r\n else{\r\n style += \"color: \" + value + \";\"; \r\n }\r\n }\r\n\r\n if(key == \"cl\" && value != \"0\"){\r\n style += \"text-decoration: line-through;\";\r\n }\r\n\r\n if(key == \"un\" && (value == \"1\" || value == \"3\")){\r\n let color = cell[\"_color\"];\r\n if(color==null){\r\n color = cell[\"fc\"];\r\n }\r\n let fs = cell[\"_fontSize\"];\r\n if(fs==null){\r\n fs = cell[\"fs\"];\r\n }\r\n style += \"border-bottom: \"+ Math.floor(fs/9) +\"px solid \"+ color +\";\";\r\n }\r\n\r\n }\r\n return style;\r\n}\r\n\r\nexport function checkstatusByCell(cell, a){\r\n let foucsStatus =cell;\r\n let tf = {\"bl\":1, \"it\":1 , \"ff\":1, \"cl\":1, \"un\":1};\r\n\r\n if(a in tf || (a==\"fs\" && isInlineStringCell(cell)) ){\r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n else{\r\n // var w = window.getSelection(), isInlineEdit=false; \r\n // if(w.type!=\"None\"){\r\n // var range = w.getRangeAt(0);\r\n // let startContainer = range.startContainer;\r\n // if (parseInt($(\"#luckysheet-input-box\").css(\"top\")) > 0 && startContainer.parentNode.tagName==\"SPAN\" && !range.collapsed) {\r\n // let span = startContainer.parentNode;\r\n // let styleList = convertCssToStyleList(span.style.cssText);\r\n // foucsStatus = styleList[a];\r\n // isInlineEdit = true;\r\n // }\r\n // }\r\n \r\n // if(!isInlineEdit){ \r\n // if(isInlineStringCell(cell)){\r\n // foucsStatus = cell.ct.s[0][a];\r\n // }\r\n // else{\r\n // foucsStatus = foucsStatus[a];\r\n // }\r\n // } \r\n \r\n foucsStatus = foucsStatus[a];\r\n \r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n }\r\n }\r\n else if(a == \"fc\"){\r\n if(foucsStatus == null){\r\n foucsStatus = \"#000000\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n\r\n if(foucsStatus == null){\r\n foucsStatus = \"#000000\";\r\n }\r\n\r\n if(foucsStatus.indexOf(\"rgba\") > -1){\r\n foucsStatus = rgbTohex(foucsStatus);\r\n }\r\n }\r\n }\r\n else if(a == \"bg\"){\r\n if(foucsStatus == null){\r\n foucsStatus = null;\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n\r\n if(foucsStatus == null){\r\n foucsStatus = null;\r\n }\r\n else if(foucsStatus.toString().indexOf(\"rgba\") > -1){\r\n foucsStatus = rgbTohex(foucsStatus);\r\n }\r\n }\r\n }\r\n else if(a.substr(0, 2) == \"bs\"){\r\n if(foucsStatus == null){\r\n foucsStatus = \"none\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = \"none\";\r\n }\r\n }\r\n }\r\n else if(a.substr(0, 2) == \"bc\"){\r\n if(foucsStatus == null){\r\n foucsStatus = \"#000000\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = \"#000000\";\r\n }\r\n }\r\n }\r\n else if(a == \"ht\"){\r\n if(foucsStatus == null){\r\n foucsStatus = \"1\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = \"1\";\r\n }\r\n }\r\n\r\n if([\"0\", \"1\", \"2\"].indexOf(foucsStatus.toString()) == -1){\r\n foucsStatus = \"1\";\r\n }\r\n }\r\n else if(a == \"vt\"){//默认垂直居中\r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n }\r\n\r\n if([\"0\", \"1\", \"2\"].indexOf(foucsStatus.toString()) == -1){\r\n foucsStatus = \"0\";\r\n }\r\n }\r\n else if(a == \"ct\"){\r\n if(foucsStatus == null){\r\n foucsStatus = null;\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = null;\r\n }\r\n }\r\n }\r\n else if(a == \"fs\"){\r\n if(foucsStatus == null){\r\n foucsStatus = \"10\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = \"10\";\r\n }\r\n }\r\n }\r\n else if(a == \"tb\"){\r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n }\r\n }\r\n else if(a == \"tr\"){\r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = \"0\";\r\n }\r\n }\r\n }\r\n else if(a == \"rt\"){\r\n if(foucsStatus == null){\r\n foucsStatus = null;\r\n }\r\n else{\r\n foucsStatus = foucsStatus[a];\r\n if(foucsStatus == null){\r\n foucsStatus = null;\r\n }\r\n }\r\n }\r\n\r\n return foucsStatus;\r\n}\r\n\r\nexport function textTrim(x) {\r\n if(x==null || x.length==0){\r\n return x;\r\n }\r\n return x.replace(/^\\s+|\\s+$/gm,'');\r\n}","import browser from './browser';\r\nimport formula from './formula';\r\nimport { datagridgrowth } from './getdata';\r\nimport { jfrefreshgrid, jfrefreshgridall, jfrefreshrange } from './refresh';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport Store from '../store';\r\n\r\nconst editor = {\r\n //worker+blob实现深拷贝替换extend\r\n deepCopyFlowDataState:false,\r\n deepCopyFlowDataCache:\"\",\r\n deepCopyFlowDataWorker:null,\r\n deepCopyFlowData:function(flowData){\r\n let _this = this;\r\n\r\n if(_this.deepCopyFlowDataState){\r\n if(_this.deepCopyFlowDataWorker != null){\r\n _this.deepCopyFlowDataWorker.terminate(); \r\n }\r\n return _this.deepCopyFlowDataCache;\r\n }\r\n else{\r\n if(flowData == null){\r\n flowData = Store.flowdata;\r\n }\r\n\r\n return $.extend(true, [], flowData);\r\n }\r\n },\r\n webWorkerFlowDataCache:function(flowData){\r\n let _this = this;\r\n\r\n try{\r\n if(_this.deepCopyFlowDataWorker != null){//存新的webwork前先销毁以前的\r\n _this.deepCopyFlowDataWorker.terminate();\r\n }\r\n\r\n let funcTxt = 'data:text/javascript;chartset=US-ASCII,onmessage = function (e) { postMessage(e.data); };';\r\n _this.deepCopyFlowDataState = false;\r\n\r\n //适配IE\r\n let worker;\r\n if(browser.isIE() == 1){\r\n let response = \"self.onmessage=function(e){postMessage(e.data);}\";\r\n worker = new Worker('./plugins/Worker-helper.js');\r\n worker.postMessage(response);\r\n }\r\n else{\r\n worker = new Worker(funcTxt);\r\n }\r\n\r\n _this.deepCopyFlowDataWorker = worker;\r\n worker.postMessage(flowData);\r\n worker.onmessage = function(e) { \r\n _this.deepCopyFlowDataCache = e.data;\r\n _this.deepCopyFlowDataState = true;\r\n };\r\n }\r\n catch(e){\r\n _this.deepCopyFlowDataCache = $.extend(true, [], flowData);\r\n }\r\n },\r\n\r\n /**\r\n * @param {Array} dataChe \r\n * @param {Object} range 是否指定选区,默认为当前选区\r\n * @since Add range parameter. Update by siwei@2020-09-10. \r\n */\r\n controlHandler: function (dataChe, range) {\r\n let _this = this;\r\n\r\n let d = _this.deepCopyFlowData(Store.flowdata);//取数据\r\n\r\n // let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let last = range || Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let curR = last[\"row\"] == null ? 0 : last[\"row\"][0];\r\n let curC = last[\"column\"] == null ? 0 : last[\"column\"][0];\r\n let rlen = dataChe.length, clen = dataChe[0].length;\r\n\r\n let addr = curR + rlen - d.length, addc = curC + clen - d[0].length;\r\n if(addr > 0 || addc > 0){\r\n d = datagridgrowth([].concat(d), addr, addc, true);\r\n }\r\n\r\n for (let r = 0; r < rlen; r++) {\r\n let x = [].concat(d[r + curR]);\r\n for (let c = 0; c < clen; c++) {\r\n let value = \"\";\r\n if (dataChe[r] != null && dataChe[r][c] != null) {\r\n value = dataChe[r][c];\r\n }\r\n x[c + curC] = value;\r\n }\r\n d[r + curR] = x;\r\n }\r\n\r\n if (addr > 0 || addc > 0) {\r\n jfrefreshgridall(d[0].length, d.length, d, null, Store.luckysheet_select_save, \"datachangeAll\");\r\n }\r\n else {\r\n jfrefreshrange(d, Store.luckysheet_select_save);\r\n }\r\n },\r\n clearRangeByindex: function (st_r, ed_r, st_c, ed_c, sheetIndex) {\r\n let index = getSheetIndex(sheetIndex);\r\n let d = $.extend(true, [], Store.luckysheetfile[index][\"data\"]);\r\n \r\n for (let r = st_r; r <= ed_r; r++) {\r\n let x = [].concat(d[r]);\r\n for (let c = st_c; c <= ed_c; c++) {\r\n formula.delFunctionGroup(r, c);\r\n formula.execFunctionGroup(r, c, \"\");\r\n x[c] = null;\r\n }\r\n d[r] = x;\r\n }\r\n\r\n if(sheetIndex == Store.currentSheetIndex){\r\n let rlen = ed_r - st_r + 1, \r\n clen = ed_c - st_c + 1;\r\n \r\n if (rlen > 5000) {\r\n jfrefreshgrid(d, [{ \"row\": [st_r, ed_r], \"column\": [st_c, ed_c] }]);\r\n }\r\n else {\r\n jfrefreshrange(d, { \"row\": [st_r, ed_r], \"column\": [st_c, ed_c] });\r\n }\r\n }\r\n else{\r\n Store.luckysheetfile[index][\"data\"] = d;\r\n }\r\n },\r\n controlHandlerD: function (dataChe) {\r\n let _this = this;\r\n\r\n let d = _this.deepCopyFlowData(Store.flowdata);//取数据\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let r1 = last[\"row\"][0], r2 = last[\"row\"][1];\r\n let c1 = last[\"column\"][0], c2 = last[\"column\"][1];\r\n let rlen = dataChe.length, clen = dataChe[0].length;\r\n\r\n let addr = r1 + rlen - d.length, addc = c1 + clen - d[0].length;\r\n if(addr >0 || addc > 0){\r\n d = datagridgrowth([].concat(d), addr, addc, true);\r\n }\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n d[r][c] = null;\r\n }\r\n }\r\n\r\n for(let i = 0; i < rlen; i++){\r\n for(let j = 0; j < clen; j++){\r\n d[r1 + i][c1 + j] = dataChe[i][j];\r\n }\r\n }\r\n\r\n let range = [\r\n { \"row\": [r1, r2], \"column\": [c1, c2] },\r\n { \"row\": [r1, r1 + rlen - 1], \"column\": [c1, c1 + clen - 1] }\r\n ];\r\n\r\n jfrefreshgrid(d, range);\r\n }\r\n};\r\n\r\nexport default editor;","'use strict';\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar toInteger = require('../internals/to-integer');\nvar toLength = require('../internals/to-length');\nvar arrayMethodIsStrict = require('../internals/array-method-is-strict');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar min = Math.min;\nvar nativeLastIndexOf = [].lastIndexOf;\nvar NEGATIVE_ZERO = !!nativeLastIndexOf && 1 / [1].lastIndexOf(1, -0) < 0;\nvar STRICT_METHOD = arrayMethodIsStrict('lastIndexOf');\n// For preventing possible almost infinite loop in non-standard implementations, test the forward version of the method\nvar USES_TO_LENGTH = arrayMethodUsesToLength('indexOf', { ACCESSORS: true, 1: 0 });\nvar FORCED = NEGATIVE_ZERO || !STRICT_METHOD || !USES_TO_LENGTH;\n\n// `Array.prototype.lastIndexOf` method implementation\n// https://tc39.github.io/ecma262/#sec-array.prototype.lastindexof\nmodule.exports = FORCED ? function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {\n // convert -0 to +0\n if (NEGATIVE_ZERO) return nativeLastIndexOf.apply(this, arguments) || 0;\n var O = toIndexedObject(this);\n var length = toLength(O.length);\n var index = length - 1;\n if (arguments.length > 1) index = min(index, toInteger(arguments[1]));\n if (index < 0) index = length + index;\n for (;index >= 0; index--) if (index in O && O[index] === searchElement) return index || 0;\n return -1;\n} : nativeLastIndexOf;\n","var $ = require('../internals/export');\nvar lastIndexOf = require('../internals/array-last-index-of');\n\n// `Array.prototype.lastIndexOf` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.lastindexof\n$({ target: 'Array', proto: true, forced: lastIndexOf !== [].lastIndexOf }, {\n lastIndexOf: lastIndexOf\n});\n","!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):t.dayjs=e()}(this,function(){\"use strict\";var t=\"millisecond\",e=\"second\",n=\"minute\",r=\"hour\",i=\"day\",s=\"week\",u=\"month\",a=\"quarter\",o=\"year\",f=\"date\",h=/^(\\d{4})[-/]?(\\d{1,2})?[-/]?(\\d{0,2})[^0-9]*(\\d{1,2})?:?(\\d{1,2})?:?(\\d{1,2})?.?(\\d+)?$/,c=/\\[([^\\]]+)]|Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,d={name:\"en\",weekdays:\"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday\".split(\"_\"),months:\"January_February_March_April_May_June_July_August_September_October_November_December\".split(\"_\")},$=function(t,e,n){var r=String(t);return!r||r.length>=e?t:\"\"+Array(e+1-r.length).join(n)+t},l={s:$,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?\"+\":\"-\")+$(r,2,\"0\")+\":\"+$(i,2,\"0\")},m:function t(e,n){if(e.date() 12){\r\n return false;\r\n }\r\n\r\n if(day > 31){\r\n return false;\r\n }\r\n\r\n if(month == 2){\r\n if(new Date(year, 1, 29).getDate() == 29 && day > 29){\r\n return false;\r\n }\r\n else if(new Date(year, 1, 29).getDate() != 29 && day > 28){\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n\r\nfunction diff(now, then) {\r\n return dayjs(now).diff(dayjs(then));\r\n}\r\n\r\nfunction isdatatypemulti(s) {\r\n let type = {};\r\n\r\n if (isdatetime(s)) {\r\n type[\"date\"] = true;\r\n }\r\n\r\n if (!isNaN(parseFloat(s)) && !hasChinaword(s)) {\r\n type[\"num\"] = true;\r\n }\r\n\r\n return type;\r\n}\r\n\r\nfunction isdatatype(s) {\r\n let type = \"string\";\r\n\r\n if (isdatetime(s)) {\r\n type = \"date\";\r\n }\r\n else if (!isNaN(parseFloat(s)) && !hasChinaword(s)) {\r\n type = \"num\";\r\n }\r\n\r\n return type;\r\n}\r\n\r\nexport {\r\n isdatetime,\r\n diff,\r\n isdatatypemulti,\r\n isdatatype,\r\n}\r\n","/*! @preserve\n * numeral.js\n * version : 2.0.6\n * author : Adam Draper\n * license : MIT\n * http://adamwdraper.github.com/Numeral-js/\n */\n\n(function (global, factory) {\n if (typeof define === 'function' && define.amd) {\n define(factory);\n } else if (typeof module === 'object' && module.exports) {\n module.exports = factory();\n } else {\n global.numeral = factory();\n }\n}(this, function () {\n /************************************\n Variables\n ************************************/\n\n var numeral,\n _,\n VERSION = '2.0.6',\n formats = {},\n locales = {},\n defaults = {\n currentLocale: 'en',\n zeroFormat: null,\n nullFormat: null,\n defaultFormat: '0,0',\n scalePercentBy100: true\n },\n options = {\n currentLocale: defaults.currentLocale,\n zeroFormat: defaults.zeroFormat,\n nullFormat: defaults.nullFormat,\n defaultFormat: defaults.defaultFormat,\n scalePercentBy100: defaults.scalePercentBy100\n };\n\n\n /************************************\n Constructors\n ************************************/\n\n // Numeral prototype object\n function Numeral(input, number) {\n this._input = input;\n\n this._value = number;\n }\n\n numeral = function(input) {\n var value,\n kind,\n unformatFunction,\n regexp;\n\n if (numeral.isNumeral(input)) {\n value = input.value();\n } else if (input === 0 || typeof input === 'undefined') {\n value = 0;\n } else if (input === null || _.isNaN(input)) {\n value = null;\n } else if (typeof input === 'string') {\n if (options.zeroFormat && input === options.zeroFormat) {\n value = 0;\n } else if (options.nullFormat && input === options.nullFormat || !input.replace(/[^0-9]+/g, '').length) {\n value = null;\n } else {\n for (kind in formats) {\n regexp = typeof formats[kind].regexps.unformat === 'function' ? formats[kind].regexps.unformat() : formats[kind].regexps.unformat;\n\n if (regexp && input.match(regexp)) {\n unformatFunction = formats[kind].unformat;\n\n break;\n }\n }\n\n unformatFunction = unformatFunction || numeral._.stringToNumber;\n\n value = unformatFunction(input);\n }\n } else {\n value = Number(input)|| null;\n }\n\n return new Numeral(input, value);\n };\n\n // version number\n numeral.version = VERSION;\n\n // compare numeral object\n numeral.isNumeral = function(obj) {\n return obj instanceof Numeral;\n };\n\n // helper functions\n numeral._ = _ = {\n // formats numbers separators, decimals places, signs, abbreviations\n numberToFormat: function(value, format, roundingFunction) {\n var locale = locales[numeral.options.currentLocale],\n negP = false,\n optDec = false,\n leadingCount = 0,\n abbr = '',\n trillion = 1000000000000,\n billion = 1000000000,\n million = 1000000,\n thousand = 1000,\n decimal = '',\n neg = false,\n abbrForce, // force abbreviation\n abs,\n min,\n max,\n power,\n int,\n precision,\n signed,\n thousands,\n output;\n\n // make sure we never format a null value\n value = value || 0;\n\n abs = Math.abs(value);\n\n // see if we should use parentheses for negative number or if we should prefix with a sign\n // if both are present we default to parentheses\n if (numeral._.includes(format, '(')) {\n negP = true;\n format = format.replace(/[\\(|\\)]/g, '');\n } else if (numeral._.includes(format, '+') || numeral._.includes(format, '-')) {\n signed = numeral._.includes(format, '+') ? format.indexOf('+') : value < 0 ? format.indexOf('-') : -1;\n format = format.replace(/[\\+|\\-]/g, '');\n }\n\n // see if abbreviation is wanted\n if (numeral._.includes(format, 'a')) {\n abbrForce = format.match(/a(k|m|b|t)?/);\n\n abbrForce = abbrForce ? abbrForce[1] : false;\n\n // check for space before abbreviation\n if (numeral._.includes(format, ' a')) {\n abbr = ' ';\n }\n\n format = format.replace(new RegExp(abbr + 'a[kmbt]?'), '');\n\n if (abs >= trillion && !abbrForce || abbrForce === 't') {\n // trillion\n abbr += locale.abbreviations.trillion;\n value = value / trillion;\n } else if (abs < trillion && abs >= billion && !abbrForce || abbrForce === 'b') {\n // billion\n abbr += locale.abbreviations.billion;\n value = value / billion;\n } else if (abs < billion && abs >= million && !abbrForce || abbrForce === 'm') {\n // million\n abbr += locale.abbreviations.million;\n value = value / million;\n } else if (abs < million && abs >= thousand && !abbrForce || abbrForce === 'k') {\n // thousand\n abbr += locale.abbreviations.thousand;\n value = value / thousand;\n }\n }\n\n // check for optional decimals\n if (numeral._.includes(format, '[.]')) {\n optDec = true;\n format = format.replace('[.]', '.');\n }\n\n // break number and format\n int = value.toString().split('.')[0];\n precision = format.split('.')[1];\n thousands = format.indexOf(',');\n leadingCount = (format.split('.')[0].split(',')[0].match(/0/g) || []).length;\n\n if (precision) {\n if (numeral._.includes(precision, '[')) {\n precision = precision.replace(']', '');\n precision = precision.split('[');\n decimal = numeral._.toFixed(value, (precision[0].length + precision[1].length), roundingFunction, precision[1].length);\n } else {\n decimal = numeral._.toFixed(value, precision.length, roundingFunction);\n }\n\n int = decimal.split('.')[0];\n\n if (numeral._.includes(decimal, '.')) {\n decimal = locale.delimiters.decimal + decimal.split('.')[1];\n } else {\n decimal = '';\n }\n\n if (optDec && Number(decimal.slice(1)) === 0) {\n decimal = '';\n }\n } else {\n int = numeral._.toFixed(value, 0, roundingFunction);\n }\n\n // check abbreviation again after rounding\n if (abbr && !abbrForce && Number(int) >= 1000 && abbr !== locale.abbreviations.trillion) {\n int = String(Number(int) / 1000);\n\n switch (abbr) {\n case locale.abbreviations.thousand:\n abbr = locale.abbreviations.million;\n break;\n case locale.abbreviations.million:\n abbr = locale.abbreviations.billion;\n break;\n case locale.abbreviations.billion:\n abbr = locale.abbreviations.trillion;\n break;\n }\n }\n\n\n // format number\n if (numeral._.includes(int, '-')) {\n int = int.slice(1);\n neg = true;\n }\n\n if (int.length < leadingCount) {\n for (var i = leadingCount - int.length; i > 0; i--) {\n int = '0' + int;\n }\n }\n\n if (thousands > -1) {\n int = int.toString().replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, '$1' + locale.delimiters.thousands);\n }\n\n if (format.indexOf('.') === 0) {\n int = '';\n }\n\n output = int + decimal + (abbr ? abbr : '');\n\n if (negP) {\n output = (negP && neg ? '(' : '') + output + (negP && neg ? ')' : '');\n } else {\n if (signed >= 0) {\n output = signed === 0 ? (neg ? '-' : '+') + output : output + (neg ? '-' : '+');\n } else if (neg) {\n output = '-' + output;\n }\n }\n\n return output;\n },\n // unformats numbers separators, decimals places, signs, abbreviations\n stringToNumber: function(string) {\n var locale = locales[options.currentLocale],\n stringOriginal = string,\n abbreviations = {\n thousand: 3,\n million: 6,\n billion: 9,\n trillion: 12\n },\n abbreviation,\n value,\n i,\n regexp;\n\n if (options.zeroFormat && string === options.zeroFormat) {\n value = 0;\n } else if (options.nullFormat && string === options.nullFormat || !string.replace(/[^0-9]+/g, '').length) {\n value = null;\n } else {\n value = 1;\n\n if (locale.delimiters.decimal !== '.') {\n string = string.replace(/\\./g, '').replace(locale.delimiters.decimal, '.');\n }\n\n for (abbreviation in abbreviations) {\n regexp = new RegExp('[^a-zA-Z]' + locale.abbreviations[abbreviation] + '(?:\\\\)|(\\\\' + locale.currency.symbol + ')?(?:\\\\))?)?$');\n\n if (stringOriginal.match(regexp)) {\n value *= Math.pow(10, abbreviations[abbreviation]);\n break;\n }\n }\n\n // check for negative number\n value *= (string.split('-').length + Math.min(string.split('(').length - 1, string.split(')').length - 1)) % 2 ? 1 : -1;\n\n // remove non numbers\n string = string.replace(/[^0-9\\.]+/g, '');\n\n value *= Number(string);\n }\n\n return value;\n },\n isNaN: function(value) {\n return typeof value === 'number' && isNaN(value);\n },\n includes: function(string, search) {\n return string.indexOf(search) !== -1;\n },\n insert: function(string, subString, start) {\n return string.slice(0, start) + subString + string.slice(start);\n },\n reduce: function(array, callback /*, initialValue*/) {\n if (this === null) {\n throw new TypeError('Array.prototype.reduce called on null or undefined');\n }\n\n if (typeof callback !== 'function') {\n throw new TypeError(callback + ' is not a function');\n }\n\n var t = Object(array),\n len = t.length >>> 0,\n k = 0,\n value;\n\n if (arguments.length === 3) {\n value = arguments[2];\n } else {\n while (k < len && !(k in t)) {\n k++;\n }\n\n if (k >= len) {\n throw new TypeError('Reduce of empty array with no initial value');\n }\n\n value = t[k++];\n }\n for (; k < len; k++) {\n if (k in t) {\n value = callback(value, t[k], k, t);\n }\n }\n return value;\n },\n /**\n * Computes the multiplier necessary to make x >= 1,\n * effectively eliminating miscalculations caused by\n * finite precision.\n */\n multiplier: function (x) {\n var parts = x.toString().split('.');\n\n return parts.length < 2 ? 1 : Math.pow(10, parts[1].length);\n },\n /**\n * Given a variable number of arguments, returns the maximum\n * multiplier that must be used to normalize an operation involving\n * all of them.\n */\n correctionFactor: function () {\n var args = Array.prototype.slice.call(arguments);\n\n return args.reduce(function(accum, next) {\n var mn = _.multiplier(next);\n return accum > mn ? accum : mn;\n }, 1);\n },\n /**\n * Implementation of toFixed() that treats floats more like decimals\n *\n * Fixes binary rounding issues (eg. (0.615).toFixed(2) === '0.61') that present\n * problems for accounting- and finance-related software.\n */\n toFixed: function(value, maxDecimals, roundingFunction, optionals) {\n var splitValue = value.toString().split('.'),\n minDecimals = maxDecimals - (optionals || 0),\n boundedPrecision,\n optionalsRegExp,\n power,\n output;\n\n // Use the smallest precision value possible to avoid errors from floating point representation\n if (splitValue.length === 2) {\n boundedPrecision = Math.min(Math.max(splitValue[1].length, minDecimals), maxDecimals);\n } else {\n boundedPrecision = minDecimals;\n }\n\n power = Math.pow(10, boundedPrecision);\n\n // Multiply up by precision, round accurately, then divide and use native toFixed():\n output = (roundingFunction(value + 'e+' + boundedPrecision) / power).toFixed(boundedPrecision);\n\n if (optionals > maxDecimals - boundedPrecision) {\n optionalsRegExp = new RegExp('\\\\.?0{1,' + (optionals - (maxDecimals - boundedPrecision)) + '}$');\n output = output.replace(optionalsRegExp, '');\n }\n\n return output;\n }\n };\n\n // avaliable options\n numeral.options = options;\n\n // avaliable formats\n numeral.formats = formats;\n\n // avaliable formats\n numeral.locales = locales;\n\n // This function sets the current locale. If\n // no arguments are passed in, it will simply return the current global\n // locale key.\n numeral.locale = function(key) {\n if (key) {\n options.currentLocale = key.toLowerCase();\n }\n\n return options.currentLocale;\n };\n\n // This function provides access to the loaded locale data. If\n // no arguments are passed in, it will simply return the current\n // global locale object.\n numeral.localeData = function(key) {\n if (!key) {\n return locales[options.currentLocale];\n }\n\n key = key.toLowerCase();\n\n if (!locales[key]) {\n throw new Error('Unknown locale : ' + key);\n }\n\n return locales[key];\n };\n\n numeral.reset = function() {\n for (var property in defaults) {\n options[property] = defaults[property];\n }\n };\n\n numeral.zeroFormat = function(format) {\n options.zeroFormat = typeof(format) === 'string' ? format : null;\n };\n\n numeral.nullFormat = function (format) {\n options.nullFormat = typeof(format) === 'string' ? format : null;\n };\n\n numeral.defaultFormat = function(format) {\n options.defaultFormat = typeof(format) === 'string' ? format : '0.0';\n };\n\n numeral.register = function(type, name, format) {\n name = name.toLowerCase();\n\n if (this[type + 's'][name]) {\n throw new TypeError(name + ' ' + type + ' already registered.');\n }\n\n this[type + 's'][name] = format;\n\n return format;\n };\n\n\n numeral.validate = function(val, culture) {\n var _decimalSep,\n _thousandSep,\n _currSymbol,\n _valArray,\n _abbrObj,\n _thousandRegEx,\n localeData,\n temp;\n\n //coerce val to string\n if (typeof val !== 'string') {\n val += '';\n\n if (console.warn) {\n console.warn('Numeral.js: Value is not string. It has been co-erced to: ', val);\n }\n }\n\n //trim whitespaces from either sides\n val = val.trim();\n\n //if val is just digits return true\n if (!!val.match(/^\\d+$/)) {\n return true;\n }\n\n //if val is empty return false\n if (val === '') {\n return false;\n }\n\n //get the decimal and thousands separator from numeral.localeData\n try {\n //check if the culture is understood by numeral. if not, default it to current locale\n localeData = numeral.localeData(culture);\n } catch (e) {\n localeData = numeral.localeData(numeral.locale());\n }\n\n //setup the delimiters and currency symbol based on culture/locale\n _currSymbol = localeData.currency.symbol;\n _abbrObj = localeData.abbreviations;\n _decimalSep = localeData.delimiters.decimal;\n if (localeData.delimiters.thousands === '.') {\n _thousandSep = '\\\\.';\n } else {\n _thousandSep = localeData.delimiters.thousands;\n }\n\n // validating currency symbol\n temp = val.match(/^[^\\d]+/);\n if (temp !== null) {\n val = val.substr(1);\n if (temp[0] !== _currSymbol) {\n return false;\n }\n }\n\n //validating abbreviation symbol\n temp = val.match(/[^\\d]+$/);\n if (temp !== null) {\n val = val.slice(0, -1);\n if (temp[0] !== _abbrObj.thousand && temp[0] !== _abbrObj.million && temp[0] !== _abbrObj.billion && temp[0] !== _abbrObj.trillion) {\n return false;\n }\n }\n\n _thousandRegEx = new RegExp(_thousandSep + '{2}');\n\n if (!val.match(/[^\\d.,]/g)) {\n _valArray = val.split(_decimalSep);\n if (_valArray.length > 2) {\n return false;\n } else {\n if (_valArray.length < 2) {\n return ( !! _valArray[0].match(/^\\d+.*\\d$/) && !_valArray[0].match(_thousandRegEx));\n } else {\n if (_valArray[0].length === 1) {\n return ( !! _valArray[0].match(/^\\d+$/) && !_valArray[0].match(_thousandRegEx) && !! _valArray[1].match(/^\\d+$/));\n } else {\n return ( !! _valArray[0].match(/^\\d+.*\\d$/) && !_valArray[0].match(_thousandRegEx) && !! _valArray[1].match(/^\\d+$/));\n }\n }\n }\n }\n\n return false;\n };\n\n\n /************************************\n Numeral Prototype\n ************************************/\n\n numeral.fn = Numeral.prototype = {\n clone: function() {\n return numeral(this);\n },\n format: function(inputString, roundingFunction) {\n var value = this._value,\n format = inputString || options.defaultFormat,\n kind,\n output,\n formatFunction;\n\n // make sure we have a roundingFunction\n roundingFunction = roundingFunction || Math.round;\n\n // format based on value\n if (value === 0 && options.zeroFormat !== null) {\n output = options.zeroFormat;\n } else if (value === null && options.nullFormat !== null) {\n output = options.nullFormat;\n } else {\n for (kind in formats) {\n if (format.match(formats[kind].regexps.format)) {\n formatFunction = formats[kind].format;\n\n break;\n }\n }\n\n formatFunction = formatFunction || numeral._.numberToFormat;\n\n output = formatFunction(value, format, roundingFunction);\n }\n\n return output;\n },\n value: function() {\n return this._value;\n },\n input: function() {\n return this._input;\n },\n set: function(value) {\n this._value = Number(value);\n\n return this;\n },\n add: function(value) {\n var corrFactor = _.correctionFactor.call(null, this._value, value);\n\n function cback(accum, curr, currI, O) {\n return accum + Math.round(corrFactor * curr);\n }\n\n this._value = _.reduce([this._value, value], cback, 0) / corrFactor;\n\n return this;\n },\n subtract: function(value) {\n var corrFactor = _.correctionFactor.call(null, this._value, value);\n\n function cback(accum, curr, currI, O) {\n return accum - Math.round(corrFactor * curr);\n }\n\n this._value = _.reduce([value], cback, Math.round(this._value * corrFactor)) / corrFactor;\n\n return this;\n },\n multiply: function(value) {\n function cback(accum, curr, currI, O) {\n var corrFactor = _.correctionFactor(accum, curr);\n return Math.round(accum * corrFactor) * Math.round(curr * corrFactor) / Math.round(corrFactor * corrFactor);\n }\n\n this._value = _.reduce([this._value, value], cback, 1);\n\n return this;\n },\n divide: function(value) {\n function cback(accum, curr, currI, O) {\n var corrFactor = _.correctionFactor(accum, curr);\n return Math.round(accum * corrFactor) / Math.round(curr * corrFactor);\n }\n\n this._value = _.reduce([this._value, value], cback);\n\n return this;\n },\n difference: function(value) {\n return Math.abs(numeral(this._value).subtract(value).value());\n }\n };\n\n /************************************\n Default Locale && Format\n ************************************/\n\n numeral.register('locale', 'en', {\n delimiters: {\n thousands: ',',\n decimal: '.'\n },\n abbreviations: {\n thousand: 'k',\n million: 'm',\n billion: 'b',\n trillion: 't'\n },\n ordinal: function(number) {\n var b = number % 10;\n return (~~(number % 100 / 10) === 1) ? 'th' :\n (b === 1) ? 'st' :\n (b === 2) ? 'nd' :\n (b === 3) ? 'rd' : 'th';\n },\n currency: {\n symbol: '$'\n }\n });\n\n \n\n(function() {\n numeral.register('format', 'bps', {\n regexps: {\n format: /(BPS)/,\n unformat: /(BPS)/\n },\n format: function(value, format, roundingFunction) {\n var space = numeral._.includes(format, ' BPS') ? ' ' : '',\n output;\n\n value = value * 10000;\n\n // check for space before BPS\n format = format.replace(/\\s?BPS/, '');\n\n output = numeral._.numberToFormat(value, format, roundingFunction);\n\n if (numeral._.includes(output, ')')) {\n output = output.split('');\n\n output.splice(-1, 0, space + 'BPS');\n\n output = output.join('');\n } else {\n output = output + space + 'BPS';\n }\n\n return output;\n },\n unformat: function(string) {\n return +(numeral._.stringToNumber(string) * 0.0001).toFixed(15);\n }\n });\n})();\n\n\n(function() {\n var decimal = {\n base: 1000,\n suffixes: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']\n },\n binary = {\n base: 1024,\n suffixes: ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']\n };\n\n var allSuffixes = decimal.suffixes.concat(binary.suffixes.filter(function (item) {\n return decimal.suffixes.indexOf(item) < 0;\n }));\n var unformatRegex = allSuffixes.join('|');\n // Allow support for BPS (http://www.investopedia.com/terms/b/basispoint.asp)\n unformatRegex = '(' + unformatRegex.replace('B', 'B(?!PS)') + ')';\n\n numeral.register('format', 'bytes', {\n regexps: {\n format: /([0\\s]i?b)/,\n unformat: new RegExp(unformatRegex)\n },\n format: function(value, format, roundingFunction) {\n var output,\n bytes = numeral._.includes(format, 'ib') ? binary : decimal,\n suffix = numeral._.includes(format, ' b') || numeral._.includes(format, ' ib') ? ' ' : '',\n power,\n min,\n max;\n\n // check for space before\n format = format.replace(/\\s?i?b/, '');\n\n for (power = 0; power <= bytes.suffixes.length; power++) {\n min = Math.pow(bytes.base, power);\n max = Math.pow(bytes.base, power + 1);\n\n if (value === null || value === 0 || value >= min && value < max) {\n suffix += bytes.suffixes[power];\n\n if (min > 0) {\n value = value / min;\n }\n\n break;\n }\n }\n\n output = numeral._.numberToFormat(value, format, roundingFunction);\n\n return output + suffix;\n },\n unformat: function(string) {\n var value = numeral._.stringToNumber(string),\n power,\n bytesMultiplier;\n\n if (value) {\n for (power = decimal.suffixes.length - 1; power >= 0; power--) {\n if (numeral._.includes(string, decimal.suffixes[power])) {\n bytesMultiplier = Math.pow(decimal.base, power);\n\n break;\n }\n\n if (numeral._.includes(string, binary.suffixes[power])) {\n bytesMultiplier = Math.pow(binary.base, power);\n\n break;\n }\n }\n\n value *= (bytesMultiplier || 1);\n }\n\n return value;\n }\n });\n})();\n\n\n(function() {\n numeral.register('format', 'currency', {\n regexps: {\n format: /(\\$)/\n },\n format: function(value, format, roundingFunction) {\n var locale = numeral.locales[numeral.options.currentLocale],\n symbols = {\n before: format.match(/^([\\+|\\-|\\(|\\s|\\$]*)/)[0],\n after: format.match(/([\\+|\\-|\\)|\\s|\\$]*)$/)[0]\n },\n output,\n symbol,\n i;\n\n // strip format of spaces and $\n format = format.replace(/\\s?\\$\\s?/, '');\n\n // format the number\n output = numeral._.numberToFormat(value, format, roundingFunction);\n\n // update the before and after based on value\n if (value >= 0) {\n symbols.before = symbols.before.replace(/[\\-\\(]/, '');\n symbols.after = symbols.after.replace(/[\\-\\)]/, '');\n } else if (value < 0 && (!numeral._.includes(symbols.before, '-') && !numeral._.includes(symbols.before, '('))) {\n symbols.before = '-' + symbols.before;\n }\n\n // loop through each before symbol\n for (i = 0; i < symbols.before.length; i++) {\n symbol = symbols.before[i];\n\n switch (symbol) {\n case '$':\n output = numeral._.insert(output, locale.currency.symbol, i);\n break;\n case ' ':\n output = numeral._.insert(output, ' ', i + locale.currency.symbol.length - 1);\n break;\n }\n }\n\n // loop through each after symbol\n for (i = symbols.after.length - 1; i >= 0; i--) {\n symbol = symbols.after[i];\n\n switch (symbol) {\n case '$':\n output = i === symbols.after.length - 1 ? output + locale.currency.symbol : numeral._.insert(output, locale.currency.symbol, -(symbols.after.length - (1 + i)));\n break;\n case ' ':\n output = i === symbols.after.length - 1 ? output + ' ' : numeral._.insert(output, ' ', -(symbols.after.length - (1 + i) + locale.currency.symbol.length - 1));\n break;\n }\n }\n\n\n return output;\n }\n });\n})();\n\n\n(function() {\n numeral.register('format', 'exponential', {\n regexps: {\n format: /(e\\+|e-)/,\n unformat: /(e\\+|e-)/\n },\n format: function(value, format, roundingFunction) {\n var output,\n exponential = typeof value === 'number' && !numeral._.isNaN(value) ? value.toExponential() : '0e+0',\n parts = exponential.split('e');\n\n format = format.replace(/e[\\+|\\-]{1}0/, '');\n\n output = numeral._.numberToFormat(Number(parts[0]), format, roundingFunction);\n\n return output + 'e' + parts[1];\n },\n unformat: function(string) {\n var parts = numeral._.includes(string, 'e+') ? string.split('e+') : string.split('e-'),\n value = Number(parts[0]),\n power = Number(parts[1]);\n\n power = numeral._.includes(string, 'e-') ? power *= -1 : power;\n\n function cback(accum, curr, currI, O) {\n var corrFactor = numeral._.correctionFactor(accum, curr),\n num = (accum * corrFactor) * (curr * corrFactor) / (corrFactor * corrFactor);\n return num;\n }\n\n return numeral._.reduce([value, Math.pow(10, power)], cback, 1);\n }\n });\n})();\n\n\n(function() {\n numeral.register('format', 'ordinal', {\n regexps: {\n format: /(o)/\n },\n format: function(value, format, roundingFunction) {\n var locale = numeral.locales[numeral.options.currentLocale],\n output,\n ordinal = numeral._.includes(format, ' o') ? ' ' : '';\n\n // check for space before\n format = format.replace(/\\s?o/, '');\n\n ordinal += locale.ordinal(value);\n\n output = numeral._.numberToFormat(value, format, roundingFunction);\n\n return output + ordinal;\n }\n });\n})();\n\n\n(function() {\n numeral.register('format', 'percentage', {\n regexps: {\n format: /(%)/,\n unformat: /(%)/\n },\n format: function(value, format, roundingFunction) {\n var space = numeral._.includes(format, ' %') ? ' ' : '',\n output;\n\n if (numeral.options.scalePercentBy100) {\n value = value * 100;\n }\n\n // check for space before %\n format = format.replace(/\\s?\\%/, '');\n\n output = numeral._.numberToFormat(value, format, roundingFunction);\n\n if (numeral._.includes(output, ')')) {\n output = output.split('');\n\n output.splice(-1, 0, space + '%');\n\n output = output.join('');\n } else {\n output = output + space + '%';\n }\n\n return output;\n },\n unformat: function(string) {\n var number = numeral._.stringToNumber(string);\n if (numeral.options.scalePercentBy100) {\n return number * 0.01;\n }\n return number;\n }\n });\n})();\n\n\n(function() {\n numeral.register('format', 'time', {\n regexps: {\n format: /(:)/,\n unformat: /(:)/\n },\n format: function(value, format, roundingFunction) {\n var hours = Math.floor(value / 60 / 60),\n minutes = Math.floor((value - (hours * 60 * 60)) / 60),\n seconds = Math.round(value - (hours * 60 * 60) - (minutes * 60));\n\n return hours + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds);\n },\n unformat: function(string) {\n var timeArray = string.split(':'),\n seconds = 0;\n\n // turn hours and minutes into seconds and add them all up\n if (timeArray.length === 3) {\n // hours\n seconds = seconds + (Number(timeArray[0]) * 60 * 60);\n // minutes\n seconds = seconds + (Number(timeArray[1]) * 60);\n // seconds\n seconds = seconds + Number(timeArray[2]);\n } else if (timeArray.length === 2) {\n // minutes\n seconds = seconds + (Number(timeArray[0]) * 60);\n // seconds\n seconds = seconds + Number(timeArray[1]);\n }\n return Number(seconds);\n }\n });\n})();\n\nreturn numeral;\n}));\n","import { isRealNum, valueIsError } from './validate';\r\nimport { isdatetime } from './datecontroll';\r\nimport { getcellvalue } from './getdata';\r\nimport numeral from 'numeral';\r\n\r\nvar SSF = ({});\r\nvar make_ssf = function make_ssf(SSF) {\r\n SSF.version = '0.11.2';\r\n\r\n function _strrev(x) {\r\n var o = \"\",\r\n i = x.length - 1;\r\n while (i >= 0) o += x.charAt(i--);\r\n return o;\r\n }\r\n\r\n function fill(c, l) {\r\n var o = \"\";\r\n while (o.length < l) o += c;\r\n return o;\r\n }\r\n\r\n function pad0(v, d) {\r\n var t = \"\" + v;\r\n return t.length >= d ? t : fill('0', d - t.length) + t;\r\n }\r\n\r\n function pad_(v, d) {\r\n var t = \"\" + v;\r\n return t.length >= d ? t : fill(' ', d - t.length) + t;\r\n }\r\n\r\n function rpad_(v, d) {\r\n var t = \"\" + v;\r\n return t.length >= d ? t : t + fill(' ', d - t.length);\r\n }\r\n\r\n function pad0r1(v, d) {\r\n var t = \"\" + Math.round(v);\r\n return t.length >= d ? t : fill('0', d - t.length) + t;\r\n }\r\n\r\n function pad0r2(v, d) {\r\n var t = \"\" + v;\r\n return t.length >= d ? t : fill('0', d - t.length) + t;\r\n }\r\n var p2_32 = Math.pow(2, 32);\r\n\r\n function pad0r(v, d) {\r\n if (v > p2_32 || v < -p2_32) return pad0r1(v, d);\r\n var i = Math.round(v);\r\n return pad0r2(i, d);\r\n }\r\n\r\n function isgeneral(s, i) {\r\n i = i || 0;\r\n return s.length >= 7 + i && (s.charCodeAt(i) | 32) === 103 && (s.charCodeAt(i + 1) | 32) === 101 && (s.charCodeAt(i + 2) | 32) === 110 && (s.charCodeAt(i + 3) | 32) === 101 && (s.charCodeAt(i + 4) | 32) === 114 && (s.charCodeAt(i + 5) | 32) === 97 && (s.charCodeAt(i + 6) | 32) === 108;\r\n }\r\n var days = [\r\n ['Sun', 'Sunday'],\r\n ['Mon', 'Monday'],\r\n ['Tue', 'Tuesday'],\r\n ['Wed', 'Wednesday'],\r\n ['Thu', 'Thursday'],\r\n ['Fri', 'Friday'],\r\n ['Sat', 'Saturday']\r\n ];\r\n var months = [\r\n ['J', 'Jan', 'January'],\r\n ['F', 'Feb', 'February'],\r\n ['M', 'Mar', 'March'],\r\n ['A', 'Apr', 'April'],\r\n ['M', 'May', 'May'],\r\n ['J', 'Jun', 'June'],\r\n ['J', 'Jul', 'July'],\r\n ['A', 'Aug', 'August'],\r\n ['S', 'Sep', 'September'],\r\n ['O', 'Oct', 'October'],\r\n ['N', 'Nov', 'November'],\r\n ['D', 'Dec', 'December']\r\n ];\r\n\r\n function init_table(t) {\r\n t[0] = 'General';\r\n t[1] = '0';\r\n t[2] = '0.00';\r\n t[3] = '#,##0';\r\n t[4] = '#,##0.00';\r\n t[9] = '0%';\r\n t[10] = '0.00%';\r\n t[11] = '0.00E+00';\r\n t[12] = '# ?/?';\r\n t[13] = '# ??/??';\r\n t[14] = 'm/d/yy';\r\n t[15] = 'd-mmm-yy';\r\n t[16] = 'd-mmm';\r\n t[17] = 'mmm-yy';\r\n t[18] = 'h:mm AM/PM';\r\n t[19] = 'h:mm:ss AM/PM';\r\n t[20] = 'h:mm';\r\n t[21] = 'h:mm:ss';\r\n t[22] = 'm/d/yy h:mm';\r\n t[37] = '#,##0 ;(#,##0)';\r\n t[38] = '#,##0 ;[Red](#,##0)';\r\n t[39] = '#,##0.00;(#,##0.00)';\r\n t[40] = '#,##0.00;[Red](#,##0.00)';\r\n t[45] = 'mm:ss';\r\n t[46] = '[h]:mm:ss';\r\n t[47] = 'mmss.0';\r\n t[48] = '##0.0E+0';\r\n t[49] = '@';\r\n t[56] = '\"上午/下午 \"hh\"時\"mm\"分\"ss\"秒 \"';\r\n t[65535] = 'General';\r\n }\r\n var table_fmt = {};\r\n init_table(table_fmt);\r\n /* Defaults determined by systematically testing in Excel 2019 */\r\n /* These formats appear to default to other formats in the table */\r\n var default_map = [];\r\n var defi = 0;\r\n // 5 -> 37 ... 8 -> 40\r\n for (defi = 5; defi <= 8; ++defi) default_map[defi] = 32 + defi;\r\n // 23 -> 0 ... 26 -> 0\r\n for (defi = 23; defi <= 26; ++defi) default_map[defi] = 0;\r\n // 27 -> 14 ... 31 -> 14\r\n for (defi = 27; defi <= 31; ++defi) default_map[defi] = 14;\r\n // 50 -> 14 ... 58 -> 14\r\n for (defi = 50; defi <= 58; ++defi) default_map[defi] = 14;\r\n // 59 -> 1 ... 62 -> 4\r\n for (defi = 59; defi <= 62; ++defi) default_map[defi] = defi - 58;\r\n // 67 -> 9 ... 68 -> 10\r\n for (defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 58;\r\n // 72 -> 14 ... 75 -> 17\r\n for (defi = 72; defi <= 75; ++defi) default_map[defi] = defi - 58;\r\n // 69 -> 12 ... 71 -> 14\r\n for (defi = 67; defi <= 68; ++defi) default_map[defi] = defi - 57;\r\n // 76 -> 20 ... 78 -> 22\r\n for (defi = 76; defi <= 78; ++defi) default_map[defi] = defi - 56;\r\n // 79 -> 45 ... 81 -> 47\r\n for (defi = 79; defi <= 81; ++defi) default_map[defi] = defi - 34;\r\n // 82 -> 0 ... 65536 -> 0 (omitted)\r\n /* These formats technically refer to Accounting formats with no equivalent */\r\n var default_str = [];\r\n // 5 -- Currency, 0 decimal, black negative\r\n default_str[5] = default_str[63] = '\"$\"#,##0_);\\\\(\"$\"#,##0\\\\)';\r\n // 6 -- Currency, 0 decimal, red negative\r\n default_str[6] = default_str[64] = '\"$\"#,##0_);[Red]\\\\(\"$\"#,##0\\\\)';\r\n // 7 -- Currency, 2 decimal, black negative\r\n default_str[7] = default_str[65] = '\"$\"#,##0.00_);\\\\(\"$\"#,##0.00\\\\)';\r\n // 8 -- Currency, 2 decimal, red negative\r\n default_str[8] = default_str[66] = '\"$\"#,##0.00_);[Red]\\\\(\"$\"#,##0.00\\\\)';\r\n // 41 -- Accounting, 0 decimal, No Symbol\r\n default_str[41] = '_(* #,##0_);_(* \\\\(#,##0\\\\);_(* \"-\"_);_(@_)';\r\n // 42 -- Accounting, 0 decimal, $ Symbol\r\n default_str[42] = '_(\"$\"* #,##0_);_(\"$\"* \\\\(#,##0\\\\);_(\"$\"* \"-\"_);_(@_)';\r\n // 43 -- Accounting, 2 decimal, No Symbol\r\n default_str[43] = '_(* #,##0.00_);_(* \\\\(#,##0.00\\\\);_(* \"-\"??_);_(@_)';\r\n // 44 -- Accounting, 2 decimal, $ Symbol\r\n default_str[44] = '_(\"$\"* #,##0.00_);_(\"$\"* \\\\(#,##0.00\\\\);_(\"$\"* \"-\"??_);_(@_)';\r\n\r\n function frac(x, D, mixed) {\r\n var sgn = x < 0 ? -1 : 1;\r\n var B = x * sgn;\r\n var P_2 = 0,\r\n P_1 = 1,\r\n P = 0;\r\n var Q_2 = 1,\r\n Q_1 = 0,\r\n Q = 0;\r\n var A = Math.floor(B);\r\n while (Q_1 < D) {\r\n A = Math.floor(B);\r\n P = A * P_1 + P_2;\r\n Q = A * Q_1 + Q_2;\r\n if ((B - A) < 0.00000005) break;\r\n B = 1 / (B - A);\r\n P_2 = P_1;\r\n P_1 = P;\r\n Q_2 = Q_1;\r\n Q_1 = Q;\r\n }\r\n if (Q > D) {\r\n if (Q_1 > D) {\r\n Q = Q_2;\r\n P = P_2;\r\n } else {\r\n Q = Q_1;\r\n P = P_1;\r\n }\r\n }\r\n if (!mixed) return [0, sgn * P, Q];\r\n var q = Math.floor(sgn * P / Q);\r\n return [q, sgn * P - q * Q, Q];\r\n }\r\n\r\n function parse_date_code(v, opts, b2) {\r\n if (v > 2958465 || v < 0) return null;\r\n var date = (v | 0),\r\n time = Math.floor(86400 * (v - date)),\r\n dow = 0;\r\n var dout = [];\r\n var out = {\r\n D: date,\r\n T: time,\r\n u: 86400 * (v - date) - time,\r\n y: 0,\r\n m: 0,\r\n d: 0,\r\n H: 0,\r\n M: 0,\r\n S: 0,\r\n q: 0\r\n };\r\n if (Math.abs(out.u) < 1e-6) out.u = 0;\r\n if (opts && opts.date1904) date += 1462;\r\n if (out.u > 0.9999) {\r\n out.u = 0;\r\n if (++time == 86400) {\r\n out.T = time = 0;\r\n ++date;\r\n ++out.D;\r\n }\r\n }\r\n if (date === 60) {\r\n dout = b2 ? [1317, 10, 29] : [1900, 2, 29];\r\n dow = 3;\r\n } else if (date === 0) {\r\n dout = b2 ? [1317, 8, 29] : [1900, 1, 0];\r\n dow = 6;\r\n } else {\r\n if (date > 60) --date;\r\n /* 1 = Jan 1 1900 in Gregorian */\r\n var d = new Date(1900, 0, 1);\r\n d.setDate(d.getDate() + date - 1);\r\n dout = [d.getFullYear(), d.getMonth() + 1, d.getDate()];\r\n dow = d.getDay();\r\n if (date < 60) dow = (dow + 6) % 7;\r\n if (b2) dow = fix_hijri(d, dout);\r\n }\r\n out.y = dout[0];\r\n out.m = dout[1];\r\n out.d = dout[2];\r\n out.S = time % 60;\r\n time = Math.floor(time / 60);\r\n out.M = time % 60;\r\n time = Math.floor(time / 60);\r\n out.H = time;\r\n out.q = dow;\r\n return out;\r\n }\r\n SSF.parse_date_code = parse_date_code;\r\n var basedate = new Date(1899, 11, 31, 0, 0, 0);\r\n var dnthresh = basedate.getTime();\r\n var base1904 = new Date(1900, 2, 1, 0, 0, 0);\r\n\r\n function datenum_local(v, date1904) {\r\n var epoch = v.getTime();\r\n if (date1904) epoch -= 1461 * 24 * 60 * 60 * 1000;\r\n else if (v >= base1904) epoch += 24 * 60 * 60 * 1000;\r\n return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000);\r\n }\r\n /* The longest 32-bit integer text is \"-4294967296\", exactly 11 chars */\r\n function general_fmt_int(v) {\r\n return v.toString(10);\r\n }\r\n SSF._general_int = general_fmt_int;\r\n /* ECMA-376 18.8.30 numFmt*/\r\n /* Note: `toPrecision` uses standard form when prec > E and E >= -6 */\r\n var general_fmt_num = (function make_general_fmt_num() {\r\n var trailing_zeroes_and_decimal = /(?:\\.0*|(\\.\\d*[1-9])0+)$/;\r\n\r\n function strip_decimal(o) {\r\n return (o.indexOf(\".\") == -1) ? o : o.replace(trailing_zeroes_and_decimal, \"$1\");\r\n }\r\n /* General Exponential always shows 2 digits exp and trims the mantissa */\r\n var mantissa_zeroes_and_decimal = /(?:\\.0*|(\\.\\d*[1-9])0+)[Ee]/;\r\n var exp_with_single_digit = /(E[+-])(\\d)$/;\r\n\r\n function normalize_exp(o) {\r\n if (o.indexOf(\"E\") == -1) return o;\r\n return o.replace(mantissa_zeroes_and_decimal, \"$1E\").replace(exp_with_single_digit, \"$10$2\");\r\n }\r\n /* exponent >= -9 and <= 9 */\r\n function small_exp(v) {\r\n var w = (v < 0 ? 12 : 11);\r\n var o = strip_decimal(v.toFixed(12));\r\n if (o.length <= w) return o;\r\n o = v.toPrecision(10);\r\n if (o.length <= w) return o;\r\n return v.toExponential(5);\r\n }\r\n /* exponent >= 11 or <= -10 likely exponential */\r\n function large_exp(v) {\r\n var o = strip_decimal(v.toFixed(11));\r\n return (o.length > (v < 0 ? 12 : 11) || o === \"0\" || o === \"-0\") ? v.toPrecision(6) : o;\r\n }\r\n\r\n function general_fmt_num_base(v) {\r\n var V = Math.floor(Math.log(Math.abs(v)) * Math.LOG10E),\r\n o;\r\n if (V >= -4 && V <= -1) o = v.toPrecision(10 + V);\r\n else if (Math.abs(V) <= 9) o = small_exp(v);\r\n else if (V === 10) o = v.toFixed(10).substr(0, 12);\r\n else o = large_exp(v);\r\n return strip_decimal(normalize_exp(o.toUpperCase()));\r\n }\r\n return general_fmt_num_base;\r\n })();\r\n SSF._general_num = general_fmt_num;\r\n /*\r\n \"General\" rules:\r\n - text is passed through (\"@\")\r\n - booleans are rendered as TRUE/FALSE\r\n - \"up to 11 characters\" displayed for numbers\r\n - Default date format (code 14) used for Dates\r\n TODO: technically the display depends on the width of the cell\r\n */\r\n function general_fmt(v, opts) {\r\n switch (typeof v) {\r\n case 'string':\r\n return v;\r\n case 'boolean':\r\n return v ? \"TRUE\" : \"FALSE\";\r\n case 'number':\r\n return (v | 0) === v ? v.toString(10) : general_fmt_num(v);\r\n case 'undefined':\r\n return \"\";\r\n case 'object':\r\n if (v == null) return \"\";\r\n if (v instanceof Date) return format(14, datenum_local(v, opts && opts.date1904), opts);\r\n }\r\n throw new Error(\"unsupported value in General format: \" + v);\r\n }\r\n SSF._general = general_fmt;\r\n\r\n function fix_hijri(date, o) {\r\n /* TODO: properly adjust y/m/d and */\r\n o[0] -= 581;\r\n var dow = date.getDay();\r\n if (date < 60) dow = (dow + 6) % 7;\r\n return dow;\r\n }\r\n var THAI_DIGITS = \"\\u0E50\\u0E51\\u0E52\\u0E53\\u0E54\\u0E55\\u0E56\\u0E57\\u0E58\\u0E59\".split(\"\");\r\n /*jshint -W086 */\r\n function write_date(type, fmt, val, ss0) {\r\n var o = \"\",\r\n ss = 0,\r\n tt = 0,\r\n y = val.y,\r\n out, outl = 0;\r\n switch (type) {\r\n case 98:\r\n /* 'b' buddhist year */ y = val.y + 543;\r\n /* falls through */\r\n case 121:\r\n /* 'y' year */ switch (fmt.length) {\r\n case 1:\r\n case 2:\r\n out = y % 100;\r\n outl = 2;\r\n break;\r\n default:\r\n out = y % 10000;\r\n outl = 4;\r\n break;\r\n }\r\n break;\r\n case 109:\r\n /* 'm' month */ switch (fmt.length) {\r\n case 1:\r\n case 2:\r\n out = val.m;\r\n outl = fmt.length;\r\n break;\r\n case 3:\r\n return months[val.m - 1][1];\r\n case 5:\r\n return months[val.m - 1][0];\r\n default:\r\n return months[val.m - 1][2];\r\n }\r\n break;\r\n case 100:\r\n /* 'd' day */ switch (fmt.length) {\r\n case 1:\r\n case 2:\r\n out = val.d;\r\n outl = fmt.length;\r\n break;\r\n case 3:\r\n return days[val.q][0];\r\n default:\r\n return days[val.q][1];\r\n }\r\n break;\r\n case 104:\r\n /* 'h' 12-hour */ switch (fmt.length) {\r\n case 1:\r\n case 2:\r\n out = 1 + (val.H + 11) % 12;\r\n outl = fmt.length;\r\n break;\r\n default:\r\n throw 'bad hour format: ' + fmt;\r\n }\r\n break;\r\n case 72:\r\n /* 'H' 24-hour */ switch (fmt.length) {\r\n case 1:\r\n case 2:\r\n out = val.H;\r\n outl = fmt.length;\r\n break;\r\n default:\r\n throw 'bad hour format: ' + fmt;\r\n }\r\n break;\r\n case 77:\r\n /* 'M' minutes */ switch (fmt.length) {\r\n case 1:\r\n case 2:\r\n out = val.M;\r\n outl = fmt.length;\r\n break;\r\n default:\r\n throw 'bad minute format: ' + fmt;\r\n }\r\n break;\r\n case 115:\r\n /* 's' seconds */ if (fmt != 's' && fmt != 'ss' && fmt != '.0' && fmt != '.00' && fmt != '.000') throw 'bad second format: ' + fmt;\r\n if (val.u === 0 && (fmt == \"s\" || fmt == \"ss\")) return pad0(val.S, fmt.length);\r\n if (ss0 >= 2) tt = ss0 === 3 ? 1000 : 100;\r\n else tt = ss0 === 1 ? 10 : 1;\r\n ss = Math.round((tt) * (val.S + val.u));\r\n if (ss >= 60 * tt) ss = 0;\r\n if (fmt === 's') return ss === 0 ? \"0\" : \"\" + ss / tt;\r\n o = pad0(ss, 2 + ss0);\r\n if (fmt === 'ss') return o.substr(0, 2);\r\n return \".\" + o.substr(2, fmt.length - 1);\r\n case 90:\r\n /* 'Z' absolute time */ switch (fmt) {\r\n case '[h]':\r\n case '[hh]':\r\n out = val.D * 24 + val.H;\r\n break;\r\n case '[m]':\r\n case '[mm]':\r\n out = (val.D * 24 + val.H) * 60 + val.M;\r\n break;\r\n case '[s]':\r\n case '[ss]':\r\n out = ((val.D * 24 + val.H) * 60 + val.M) * 60 + Math.round(val.S + val.u);\r\n break;\r\n default:\r\n throw 'bad abstime format: ' + fmt;\r\n }\r\n outl = fmt.length === 3 ? 1 : 2;\r\n break;\r\n case 101:\r\n /* 'e' era */ out = y;\r\n outl = 1;\r\n break;\r\n }\r\n var outstr = outl > 0 ? pad0(out, outl) : \"\";\r\n return outstr;\r\n }\r\n /*jshint +W086 */\r\n function commaify(s) {\r\n var w = 3;\r\n if (s.length <= w) return s;\r\n var j = (s.length % w),\r\n o = s.substr(0, j);\r\n for (; j != s.length; j += w) o += (o.length > 0 ? \",\" : \"\") + s.substr(j, w);\r\n return o;\r\n }\r\n var write_num = (function make_write_num() {\r\n var pct1 = /%/g;\r\n\r\n function write_num_pct(type, fmt, val) {\r\n var sfmt = fmt.replace(pct1, \"\"),\r\n mul = fmt.length - sfmt.length;\r\n return write_num(type, sfmt, val * Math.pow(10, 2 * mul)) + fill(\"%\", mul);\r\n }\r\n\r\n function write_num_cm(type, fmt, val) {\r\n var idx = fmt.length - 1;\r\n while (fmt.charCodeAt(idx - 1) === 44) --idx;\r\n return write_num(type, fmt.substr(0, idx), val / Math.pow(10, 3 * (fmt.length - idx)));\r\n }\r\n\r\n function write_num_exp(fmt, val) {\r\n var o;\r\n var idx = fmt.indexOf(\"E\") - fmt.indexOf(\".\") - 1;\r\n if (fmt.match(/^#+0.0E\\+0$/)) {\r\n if (val == 0) return \"0.0E+0\";\r\n else if (val < 0) return \"-\" + write_num_exp(fmt, -val);\r\n var period = fmt.indexOf(\".\");\r\n if (period === -1) period = fmt.indexOf('E');\r\n var ee = Math.floor(Math.log(val) * Math.LOG10E) % period;\r\n if (ee < 0) ee += period;\r\n o = (val / Math.pow(10, ee)).toPrecision(idx + 1 + (period + ee) % period);\r\n if (o.indexOf(\"e\") === -1) {\r\n var fakee = Math.floor(Math.log(val) * Math.LOG10E);\r\n if (o.indexOf(\".\") === -1) o = o.charAt(0) + \".\" + o.substr(1) + \"E+\" + (fakee - o.length + ee);\r\n else o += \"E+\" + (fakee - ee);\r\n while (o.substr(0, 2) === \"0.\") {\r\n o = o.charAt(0) + o.substr(2, period) + \".\" + o.substr(2 + period);\r\n o = o.replace(/^0+([1-9])/, \"$1\").replace(/^0+\\./, \"0.\");\r\n }\r\n o = o.replace(/\\+-/, \"-\");\r\n }\r\n o = o.replace(/^([+-]?)(\\d*)\\.(\\d*)[Ee]/, function($$, $1, $2, $3) {\r\n return $1 + $2 + $3.substr(0, (period + ee) % period) + \".\" + $3.substr(ee) + \"E\";\r\n });\r\n } else o = val.toExponential(idx);\r\n if (fmt.match(/E\\+00$/) && o.match(/e[+-]\\d$/)) o = o.substr(0, o.length - 1) + \"0\" + o.charAt(o.length - 1);\r\n if (fmt.match(/E\\-/) && o.match(/e\\+/)) o = o.replace(/e\\+/, \"e\");\r\n return o.replace(\"e\", \"E\");\r\n }\r\n var frac1 = /# (\\?+)( ?)\\/( ?)(\\d+)/;\r\n\r\n function write_num_f1(r, aval, sign) {\r\n var den = parseInt(r[4], 10),\r\n rr = Math.round(aval * den),\r\n base = Math.floor(rr / den);\r\n var myn = (rr - base * den),\r\n myd = den;\r\n return sign + (base === 0 ? \"\" : \"\" + base) + \" \" + (myn === 0 ? fill(\" \", r[1].length + 1 + r[4].length) : pad_(myn, r[1].length) + r[2] + \"/\" + r[3] + pad0(myd, r[4].length));\r\n }\r\n\r\n function write_num_f2(r, aval, sign) {\r\n return sign + (aval === 0 ? \"\" : \"\" + aval) + fill(\" \", r[1].length + 2 + r[4].length);\r\n }\r\n var dec1 = /^#*0*\\.([0#]+)/;\r\n var closeparen = /\\).*[0#]/;\r\n var phone = /\\(###\\) ###\\\\?-####/;\r\n\r\n function hashq(str) {\r\n var o = \"\",\r\n cc;\r\n for (var i = 0; i != str.length; ++i) switch ((cc = str.charCodeAt(i))) {\r\n case 35:\r\n break;\r\n case 63:\r\n o += \" \";\r\n break;\r\n case 48:\r\n o += \"0\";\r\n break;\r\n default:\r\n o += String.fromCharCode(cc);\r\n }\r\n return o;\r\n }\r\n\r\n function rnd(val, d) {\r\n var dd = Math.pow(10, d);\r\n return \"\" + (Math.round(val * dd) / dd);\r\n }\r\n\r\n function dec(val, d) {\r\n var _frac = val - Math.floor(val),\r\n dd = Math.pow(10, d);\r\n if (d < ('' + Math.round(_frac * dd)).length) return 0;\r\n return Math.round(_frac * dd);\r\n }\r\n\r\n function carry(val, d) {\r\n if (d < ('' + Math.round((val - Math.floor(val)) * Math.pow(10, d))).length) {\r\n return 1;\r\n }\r\n return 0;\r\n }\r\n\r\n function flr(val) {\r\n if (val < 2147483647 && val > -2147483648) return \"\" + (val >= 0 ? (val | 0) : (val - 1 | 0));\r\n return \"\" + Math.floor(val);\r\n }\r\n\r\n function write_num_flt(type, fmt, val) {\r\n if (type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {\r\n var ffmt = fmt.replace(/\\( */, \"\").replace(/ \\)/, \"\").replace(/\\)/, \"\");\r\n if (val >= 0) return write_num_flt('n', ffmt, val);\r\n return '(' + write_num_flt('n', ffmt, -val) + ')';\r\n }\r\n if (fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm(type, fmt, val);\r\n if (fmt.indexOf('%') !== -1) return write_num_pct(type, fmt, val);\r\n if (fmt.indexOf('E') !== -1) return write_num_exp(fmt, val);\r\n if (fmt.charCodeAt(0) === 36) return \"$\" + write_num_flt(type, fmt.substr(fmt.charAt(1) == ' ' ? 2 : 1), val);\r\n var o;\r\n var r, ri, ff, aval = Math.abs(val),\r\n sign = val < 0 ? \"-\" : \"\";\r\n if (fmt.match(/^00+$/)) return sign + pad0r(aval, fmt.length);\r\n if (fmt.match(/^[#?]+$/)) {\r\n o = pad0r(val, 0);\r\n if (o === \"0\") o = \"\";\r\n return o.length > fmt.length ? o : hashq(fmt.substr(0, fmt.length - o.length)) + o;\r\n }\r\n if ((r = fmt.match(frac1))) return write_num_f1(r, aval, sign);\r\n if (fmt.match(/^#+0+$/)) return sign + pad0r(aval, fmt.length - fmt.indexOf(\"0\"));\r\n if ((r = fmt.match(dec1))) {\r\n o = rnd(val, r[1].length).replace(/^([^\\.]+)$/, \"$1.\" + hashq(r[1])).replace(/\\.$/, \".\" + hashq(r[1])).replace(/\\.(\\d*)$/, function($$, $1) {\r\n return \".\" + $1 + fill(\"0\", hashq(r[1]).length - $1.length);\r\n });\r\n return fmt.indexOf(\"0.\") !== -1 ? o : o.replace(/^0\\./, \".\");\r\n }\r\n fmt = fmt.replace(/^#+([0.])/, \"$1\");\r\n if ((r = fmt.match(/^(0*)\\.(#*)$/))) {\r\n return sign + rnd(aval, r[2].length).replace(/\\.(\\d*[1-9])0*$/, \".$1\").replace(/^(-?\\d*)$/, \"$1.\").replace(/^0\\./, r[1].length ? \"0.\" : \".\");\r\n }\r\n if ((r = fmt.match(/^#{1,3},##0(\\.?)$/))) return sign + commaify(pad0r(aval, 0));\r\n if ((r = fmt.match(/^#,##0\\.([#0]*0)$/))) {\r\n return val < 0 ? \"-\" + write_num_flt(type, fmt, -val) : commaify(\"\" + (Math.floor(val) + carry(val, r[1].length))) + \".\" + pad0(dec(val, r[1].length), r[1].length);\r\n }\r\n if ((r = fmt.match(/^#,#*,#0/))) return write_num_flt(type, fmt.replace(/^#,#*,/, \"\"), val);\r\n if ((r = fmt.match(/^([0#]+)(\\\\?-([0#]+))+$/))) {\r\n o = _strrev(write_num_flt(type, fmt.replace(/[\\\\-]/g, \"\"), val));\r\n ri = 0;\r\n return _strrev(_strrev(fmt.replace(/\\\\/g, \"\")).replace(/[0#]/g, function(x) {\r\n return ri < o.length ? o.charAt(ri++) : x === '0' ? '0' : \"\";\r\n }));\r\n }\r\n if (fmt.match(phone)) {\r\n o = write_num_flt(type, \"##########\", val);\r\n return \"(\" + o.substr(0, 3) + \") \" + o.substr(3, 3) + \"-\" + o.substr(6);\r\n }\r\n var oa = \"\";\r\n if ((r = fmt.match(/^([#0?]+)( ?)\\/( ?)([#0?]+)/))) {\r\n ri = Math.min(r[4].length, 7);\r\n ff = frac(aval, Math.pow(10, ri) - 1, false);\r\n o = \"\" + sign;\r\n oa = write_num(\"n\", r[1], ff[1]);\r\n if (oa.charAt(oa.length - 1) == \" \") oa = oa.substr(0, oa.length - 1) + \"0\";\r\n o += oa + r[2] + \"/\" + r[3];\r\n oa = rpad_(ff[2], ri);\r\n if (oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length - oa.length)) + oa;\r\n o += oa;\r\n return o;\r\n }\r\n if ((r = fmt.match(/^# ([#0?]+)( ?)\\/( ?)([#0?]+)/))) {\r\n ri = Math.min(Math.max(r[1].length, r[4].length), 7);\r\n ff = frac(aval, Math.pow(10, ri) - 1, true);\r\n return sign + (ff[0] || (ff[1] ? \"\" : \"0\")) + \" \" + (ff[1] ? pad_(ff[1], ri) + r[2] + \"/\" + r[3] + rpad_(ff[2], ri) : fill(\" \", 2 * ri + 1 + r[2].length + r[3].length));\r\n }\r\n if ((r = fmt.match(/^[#0?]+$/))) {\r\n o = pad0r(val, 0);\r\n if (fmt.length <= o.length) return o;\r\n return hashq(fmt.substr(0, fmt.length - o.length)) + o;\r\n }\r\n if ((r = fmt.match(/^([#0?]+)\\.([#0]+)$/))) {\r\n o = \"\" + val.toFixed(Math.min(r[2].length, 10)).replace(/([^0])0+$/, \"$1\");\r\n ri = o.indexOf(\".\");\r\n var lres = fmt.indexOf(\".\") - ri,\r\n rres = fmt.length - o.length - lres;\r\n return hashq(fmt.substr(0, lres) + o + fmt.substr(fmt.length - rres));\r\n }\r\n if ((r = fmt.match(/^00,000\\.([#0]*0)$/))) {\r\n ri = dec(val, r[1].length);\r\n return val < 0 ? \"-\" + write_num_flt(type, fmt, -val) : commaify(flr(val)).replace(/^\\d,\\d{3}$/, \"0$&\").replace(/^\\d*$/, function($$) {\r\n return \"00,\" + ($$.length < 3 ? pad0(0, 3 - $$.length) : \"\") + $$;\r\n }) + \".\" + pad0(ri, r[1].length);\r\n }\r\n switch (fmt) {\r\n case \"###,##0.00\":\r\n return write_num_flt(type, \"#,##0.00\", val);\r\n case \"###,###\":\r\n case \"##,###\":\r\n case \"#,###\":\r\n var x = commaify(pad0r(aval, 0));\r\n return x !== \"0\" ? sign + x : \"\";\r\n case \"###,###.00\":\r\n return write_num_flt(type, \"###,##0.00\", val).replace(/^0\\./, \".\");\r\n case \"#,###.00\":\r\n return write_num_flt(type, \"#,##0.00\", val).replace(/^0\\./, \".\");\r\n default:\r\n }\r\n throw new Error(\"unsupported format |\" + fmt + \"|\");\r\n }\r\n\r\n function write_num_cm2(type, fmt, val) {\r\n var idx = fmt.length - 1;\r\n while (fmt.charCodeAt(idx - 1) === 44) --idx;\r\n return write_num(type, fmt.substr(0, idx), val / Math.pow(10, 3 * (fmt.length - idx)));\r\n }\r\n\r\n function write_num_pct2(type, fmt, val) {\r\n var sfmt = fmt.replace(pct1, \"\"),\r\n mul = fmt.length - sfmt.length;\r\n return write_num(type, sfmt, val * Math.pow(10, 2 * mul)) + fill(\"%\", mul);\r\n }\r\n\r\n function write_num_exp2(fmt, val) {\r\n var o;\r\n var idx = fmt.indexOf(\"E\") - fmt.indexOf(\".\") - 1;\r\n if (fmt.match(/^#+0.0E\\+0$/)) {\r\n if (val == 0) return \"0.0E+0\";\r\n else if (val < 0) return \"-\" + write_num_exp2(fmt, -val);\r\n var period = fmt.indexOf(\".\");\r\n if (period === -1) period = fmt.indexOf('E');\r\n var ee = Math.floor(Math.log(val) * Math.LOG10E) % period;\r\n if (ee < 0) ee += period;\r\n o = (val / Math.pow(10, ee)).toPrecision(idx + 1 + (period + ee) % period);\r\n if (!o.match(/[Ee]/)) {\r\n var fakee = Math.floor(Math.log(val) * Math.LOG10E);\r\n if (o.indexOf(\".\") === -1) o = o.charAt(0) + \".\" + o.substr(1) + \"E+\" + (fakee - o.length + ee);\r\n else o += \"E+\" + (fakee - ee);\r\n o = o.replace(/\\+-/, \"-\");\r\n }\r\n o = o.replace(/^([+-]?)(\\d*)\\.(\\d*)[Ee]/, function($$, $1, $2, $3) {\r\n return $1 + $2 + $3.substr(0, (period + ee) % period) + \".\" + $3.substr(ee) + \"E\";\r\n });\r\n } else o = val.toExponential(idx);\r\n if (fmt.match(/E\\+00$/) && o.match(/e[+-]\\d$/)) o = o.substr(0, o.length - 1) + \"0\" + o.charAt(o.length - 1);\r\n if (fmt.match(/E\\-/) && o.match(/e\\+/)) o = o.replace(/e\\+/, \"e\");\r\n return o.replace(\"e\", \"E\");\r\n }\r\n\r\n function write_num_int(type, fmt, val) {\r\n if (type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {\r\n var ffmt = fmt.replace(/\\( */, \"\").replace(/ \\)/, \"\").replace(/\\)/, \"\");\r\n if (val >= 0) return write_num_int('n', ffmt, val);\r\n return '(' + write_num_int('n', ffmt, -val) + ')';\r\n }\r\n if (fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm2(type, fmt, val);\r\n if (fmt.indexOf('%') !== -1) return write_num_pct2(type, fmt, val);\r\n if (fmt.indexOf('E') !== -1) return write_num_exp2(fmt, val);\r\n if (fmt.charCodeAt(0) === 36) return \"$\" + write_num_int(type, fmt.substr(fmt.charAt(1) == ' ' ? 2 : 1), val);\r\n var o;\r\n var r, ri, ff, aval = Math.abs(val),\r\n sign = val < 0 ? \"-\" : \"\";\r\n if (fmt.match(/^00+$/)) return sign + pad0(aval, fmt.length);\r\n if (fmt.match(/^[#?]+$/)) {\r\n o = (\"\" + val);\r\n if (val === 0) o = \"\";\r\n return o.length > fmt.length ? o : hashq(fmt.substr(0, fmt.length - o.length)) + o;\r\n }\r\n if ((r = fmt.match(frac1))) return write_num_f2(r, aval, sign);\r\n if (fmt.match(/^#+0+$/)) return sign + pad0(aval, fmt.length - fmt.indexOf(\"0\"));\r\n if ((r = fmt.match(dec1))) {\r\n o = (\"\" + val).replace(/^([^\\.]+)$/, \"$1.\" + hashq(r[1])).replace(/\\.$/, \".\" + hashq(r[1]));\r\n o = o.replace(/\\.(\\d*)$/, function($$, $1) {\r\n return \".\" + $1 + fill(\"0\", hashq(r[1]).length - $1.length);\r\n });\r\n return fmt.indexOf(\"0.\") !== -1 ? o : o.replace(/^0\\./, \".\");\r\n }\r\n fmt = fmt.replace(/^#+([0.])/, \"$1\");\r\n if ((r = fmt.match(/^(0*)\\.(#*)$/))) {\r\n return sign + (\"\" + aval).replace(/\\.(\\d*[1-9])0*$/, \".$1\").replace(/^(-?\\d*)$/, \"$1.\").replace(/^0\\./, r[1].length ? \"0.\" : \".\");\r\n }\r\n if ((r = fmt.match(/^#{1,3},##0(\\.?)$/))) return sign + commaify((\"\" + aval));\r\n if ((r = fmt.match(/^#,##0\\.([#0]*0)$/))) {\r\n return val < 0 ? \"-\" + write_num_int(type, fmt, -val) : commaify((\"\" + val)) + \".\" + fill('0', r[1].length);\r\n }\r\n if ((r = fmt.match(/^#,#*,#0/))) return write_num_int(type, fmt.replace(/^#,#*,/, \"\"), val);\r\n if ((r = fmt.match(/^([0#]+)(\\\\?-([0#]+))+$/))) {\r\n o = _strrev(write_num_int(type, fmt.replace(/[\\\\-]/g, \"\"), val));\r\n ri = 0;\r\n return _strrev(_strrev(fmt.replace(/\\\\/g, \"\")).replace(/[0#]/g, function(x) {\r\n return ri < o.length ? o.charAt(ri++) : x === '0' ? '0' : \"\";\r\n }));\r\n }\r\n if (fmt.match(phone)) {\r\n o = write_num_int(type, \"##########\", val);\r\n return \"(\" + o.substr(0, 3) + \") \" + o.substr(3, 3) + \"-\" + o.substr(6);\r\n }\r\n var oa = \"\";\r\n if ((r = fmt.match(/^([#0?]+)( ?)\\/( ?)([#0?]+)/))) {\r\n ri = Math.min(r[4].length, 7);\r\n ff = frac(aval, Math.pow(10, ri) - 1, false);\r\n o = \"\" + sign;\r\n oa = write_num(\"n\", r[1], ff[1]);\r\n if (oa.charAt(oa.length - 1) == \" \") oa = oa.substr(0, oa.length - 1) + \"0\";\r\n o += oa + r[2] + \"/\" + r[3];\r\n oa = rpad_(ff[2], ri);\r\n if (oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length - oa.length)) + oa;\r\n o += oa;\r\n return o;\r\n }\r\n if ((r = fmt.match(/^# ([#0?]+)( ?)\\/( ?)([#0?]+)/))) {\r\n ri = Math.min(Math.max(r[1].length, r[4].length), 7);\r\n ff = frac(aval, Math.pow(10, ri) - 1, true);\r\n return sign + (ff[0] || (ff[1] ? \"\" : \"0\")) + \" \" + (ff[1] ? pad_(ff[1], ri) + r[2] + \"/\" + r[3] + rpad_(ff[2], ri) : fill(\" \", 2 * ri + 1 + r[2].length + r[3].length));\r\n }\r\n if ((r = fmt.match(/^[#0?]+$/))) {\r\n o = \"\" + val;\r\n if (fmt.length <= o.length) return o;\r\n return hashq(fmt.substr(0, fmt.length - o.length)) + o;\r\n }\r\n if ((r = fmt.match(/^([#0]+)\\.([#0]+)$/))) {\r\n o = \"\" + val.toFixed(Math.min(r[2].length, 10)).replace(/([^0])0+$/, \"$1\");\r\n ri = o.indexOf(\".\");\r\n var lres = fmt.indexOf(\".\") - ri,\r\n rres = fmt.length - o.length - lres;\r\n return hashq(fmt.substr(0, lres) + o + fmt.substr(fmt.length - rres));\r\n }\r\n if ((r = fmt.match(/^00,000\\.([#0]*0)$/))) {\r\n return val < 0 ? \"-\" + write_num_int(type, fmt, -val) : commaify(\"\" + val).replace(/^\\d,\\d{3}$/, \"0$&\").replace(/^\\d*$/, function($$) {\r\n return \"00,\" + ($$.length < 3 ? pad0(0, 3 - $$.length) : \"\") + $$;\r\n }) + \".\" + pad0(0, r[1].length);\r\n }\r\n switch (fmt) {\r\n case \"###,###\":\r\n case \"##,###\":\r\n case \"#,###\":\r\n var x = commaify(\"\" + aval);\r\n return x !== \"0\" ? sign + x : \"\";\r\n default:\r\n if (fmt.match(/\\.[0#?]*$/)) return write_num_int(type, fmt.slice(0, fmt.lastIndexOf(\".\")), val) + hashq(fmt.slice(fmt.lastIndexOf(\".\")));\r\n }\r\n throw new Error(\"unsupported format |\" + fmt + \"|\");\r\n }\r\n return function write_num(type, fmt, val) {\r\n return (val | 0) === val ? write_num_int(type, fmt, val) : write_num_flt(type, fmt, val);\r\n };\r\n })();\r\n\r\n function split_fmt(fmt) {\r\n var out = [];\r\n var in_str = false /*, cc*/ ;\r\n for (var i = 0, j = 0; i < fmt.length; ++i) switch (( /*cc=*/ fmt.charCodeAt(i))) {\r\n case 34:\r\n /* '\"' */ in_str = !in_str;\r\n break;\r\n case 95:\r\n case 42:\r\n case 92:\r\n /* '_' '*' '\\\\' */\r\n ++i;\r\n break;\r\n case 59:\r\n /* ';' */ out[out.length] = fmt.substr(j, i - j);\r\n j = i + 1;\r\n }\r\n out[out.length] = fmt.substr(j);\r\n if (in_str === true) throw new Error(\"Format |\" + fmt + \"| unterminated string \");\r\n return out;\r\n }\r\n SSF._split = split_fmt;\r\n var abstime = /\\[[HhMmSs\\u0E0A\\u0E19\\u0E17]*\\]/;\r\n\r\n function fmt_is_date(fmt) {\r\n var i = 0,\r\n /*cc = 0,*/ c = \"\",\r\n o = \"\";\r\n while (i < fmt.length) {\r\n switch ((c = fmt.charAt(i))) {\r\n case 'G':\r\n if (isgeneral(fmt, i)) i += 6;\r\n i++;\r\n break;\r\n case '\"':\r\n for (;\r\n ( /*cc=*/ fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) { /*empty*/ }++i;\r\n break;\r\n case '\\\\':\r\n i += 2;\r\n break;\r\n case '_':\r\n i += 2;\r\n break;\r\n case '@':\r\n ++i;\r\n break;\r\n case 'B':\r\n case 'b':\r\n if (fmt.charAt(i + 1) === \"1\" || fmt.charAt(i + 1) === \"2\") return true;\r\n /* falls through */\r\n case 'M':\r\n case 'D':\r\n case 'Y':\r\n case 'H':\r\n case 'S':\r\n case 'E':\r\n /* falls through */\r\n case 'm':\r\n case 'd':\r\n case 'y':\r\n case 'h':\r\n case 's':\r\n case 'e':\r\n case 'g':\r\n return true;\r\n case 'A':\r\n case 'a':\r\n case '上':\r\n if (fmt.substr(i, 3).toUpperCase() === \"A/P\") return true;\r\n if (fmt.substr(i, 5).toUpperCase() === \"AM/PM\") return true;\r\n if (fmt.substr(i, 5).toUpperCase() === \"上午/下午\") return true;\r\n ++i;\r\n break;\r\n case '[':\r\n o = c;\r\n while (fmt.charAt(i++) !== ']' && i < fmt.length) o += fmt.charAt(i);\r\n if (o.match(abstime)) return true;\r\n break;\r\n case '.':\r\n /* falls through */\r\n case '0':\r\n case '#':\r\n while (i < fmt.length && (\"0#?.,E+-%\".indexOf(c = fmt.charAt(++i)) > -1 || (c == '\\\\' && fmt.charAt(i + 1) == \"-\" && \"0#\".indexOf(fmt.charAt(i + 2)) > -1))) { /* empty */ }\r\n break;\r\n case '?':\r\n while (fmt.charAt(++i) === c) { /* empty */ }\r\n break;\r\n case '*':\r\n ++i;\r\n if (fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i;\r\n break;\r\n case '(':\r\n case ')':\r\n ++i;\r\n break;\r\n case '1':\r\n case '2':\r\n case '3':\r\n case '4':\r\n case '5':\r\n case '6':\r\n case '7':\r\n case '8':\r\n case '9':\r\n while (i < fmt.length && \"0123456789\".indexOf(fmt.charAt(++i)) > -1) { /* empty */ }\r\n break;\r\n case ' ':\r\n ++i;\r\n break;\r\n default:\r\n ++i;\r\n break;\r\n }\r\n }\r\n return false;\r\n }\r\n SSF.is_date = fmt_is_date;\r\n\r\n function eval_fmt(fmt, v, opts, flen) {\r\n var out = [],\r\n o = \"\",\r\n i = 0,\r\n c = \"\",\r\n lst = 't',\r\n dt, j, cc;\r\n var hr = 'H';\r\n /* Tokenize */\r\n while (i < fmt.length) {\r\n switch ((c = fmt.charAt(i))) {\r\n case 'G':\r\n /* General */ if (!isgeneral(fmt, i)) throw new Error('unrecognized character ' + c + ' in ' + fmt);\r\n out[out.length] = {\r\n t: 'G',\r\n v: 'General'\r\n };\r\n i += 7;\r\n break;\r\n case '\"':\r\n /* Literal text */ for (o = \"\";\r\n (cc = fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) o += String.fromCharCode(cc);\r\n out[out.length] = {\r\n t: 't',\r\n v: o\r\n };\r\n ++i;\r\n break;\r\n case '\\\\':\r\n var w = fmt.charAt(++i),\r\n t = (w === \"(\" || w === \")\") ? w : 't';\r\n out[out.length] = {\r\n t: t,\r\n v: w\r\n };\r\n ++i;\r\n break;\r\n case '_':\r\n out[out.length] = {\r\n t: 't',\r\n v: \" \"\r\n };\r\n i += 2;\r\n break;\r\n case '@':\r\n /* Text Placeholder */ out[out.length] = {\r\n t: 'T',\r\n v: v\r\n };\r\n ++i;\r\n break;\r\n case 'B':\r\n case 'b':\r\n if (fmt.charAt(i + 1) === \"1\" || fmt.charAt(i + 1) === \"2\") {\r\n if (dt == null) {\r\n dt = parse_date_code(v, opts, fmt.charAt(i + 1) === \"2\");\r\n if (dt == null) return \"\";\r\n }\r\n out[out.length] = {\r\n t: 'X',\r\n v: fmt.substr(i, 2)\r\n };\r\n lst = c;\r\n i += 2;\r\n break;\r\n }\r\n /* falls through */\r\n case 'M':\r\n case 'D':\r\n case 'Y':\r\n case 'H':\r\n case 'S':\r\n case 'E':\r\n c = c.toLowerCase();\r\n /* falls through */\r\n case 'm':\r\n case 'd':\r\n case 'y':\r\n case 'h':\r\n case 's':\r\n case 'e':\r\n case 'g':\r\n if (v < 0) return \"\";\r\n if (dt == null) {\r\n dt = parse_date_code(v, opts);\r\n if (dt == null) return \"#####\";\r\n }\r\n o = c;\r\n while (++i < fmt.length && fmt.charAt(i).toLowerCase() === c) o += c;\r\n if (c === 'm' && lst.toLowerCase() === 'h') c = 'M';\r\n if (c === 'h') c = hr;\r\n out[out.length] = {\r\n t: c,\r\n v: o\r\n };\r\n lst = c;\r\n break;\r\n case 'A':\r\n case 'a':\r\n case '上':\r\n var q = {\r\n t: c,\r\n v: c\r\n };\r\n if (dt == null) dt = parse_date_code(v, opts);\r\n if (fmt.substr(i, 3).toUpperCase() === \"A/P\") {\r\n if (dt != null) q.v = dt.H >= 12 ? \"P\" : \"A\";\r\n q.t = 'T';\r\n hr = 'h';\r\n i += 3;\r\n } else if (fmt.substr(i, 5).toUpperCase() === \"AM/PM\") {\r\n if (dt != null) q.v = dt.H >= 12 ? \"PM\" : \"AM\";\r\n q.t = 'T';\r\n i += 5;\r\n hr = 'h';\r\n } else if (fmt.substr(i, 5).toUpperCase() === \"上午/下午\") {\r\n if (dt != null) q.v = dt.H >= 12 ? \"下午\" : \"上午\";\r\n q.t = 'T';\r\n i += 5;\r\n hr = 'h';\r\n } else {\r\n q.t = \"t\";\r\n ++i;\r\n }\r\n if (dt == null && q.t === 'T') return \"\";\r\n out[out.length] = q;\r\n lst = c;\r\n break;\r\n case '[':\r\n o = c;\r\n while (fmt.charAt(i++) !== ']' && i < fmt.length) o += fmt.charAt(i);\r\n if (o.slice(-1) !== ']') throw 'unterminated \"[\" block: |' + o + '|';\r\n if (o.match(abstime)) {\r\n if (dt == null) {\r\n dt = parse_date_code(v, opts);\r\n if (dt == null) return \"\";\r\n }\r\n out[out.length] = {\r\n t: 'Z',\r\n v: o.toLowerCase()\r\n };\r\n lst = o.charAt(1);\r\n } else if (o.indexOf(\"$\") > -1) {\r\n o = (o.match(/\\$([^-\\[\\]]*)/) || [])[1] || \"$\";\r\n if (!fmt_is_date(fmt)) out[out.length] = {\r\n t: 't',\r\n v: o\r\n };\r\n }\r\n break;\r\n /* Numbers */\r\n case '.':\r\n if (dt != null) {\r\n o = c;\r\n while (++i < fmt.length && (c = fmt.charAt(i)) === \"0\") o += c;\r\n out[out.length] = {\r\n t: 's',\r\n v: o\r\n };\r\n break;\r\n }\r\n /* falls through */\r\n case '0':\r\n case '#':\r\n o = c;\r\n while (++i < fmt.length && \"0#?.,E+-%\".indexOf(c = fmt.charAt(i)) > -1) o += c;\r\n out[out.length] = {\r\n t: 'n',\r\n v: o\r\n };\r\n break;\r\n case '?':\r\n o = c;\r\n while (fmt.charAt(++i) === c) o += c;\r\n out[out.length] = {\r\n t: c,\r\n v: o\r\n };\r\n lst = c;\r\n break;\r\n case '*':\r\n ++i;\r\n if (fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i;\r\n break; // **\r\n case '(':\r\n case ')':\r\n out[out.length] = {\r\n t: (flen === 1 ? 't' : c),\r\n v: c\r\n };\r\n ++i;\r\n break;\r\n case '1':\r\n case '2':\r\n case '3':\r\n case '4':\r\n case '5':\r\n case '6':\r\n case '7':\r\n case '8':\r\n case '9':\r\n o = c;\r\n while (i < fmt.length && \"0123456789\".indexOf(fmt.charAt(++i)) > -1) o += fmt.charAt(i);\r\n out[out.length] = {\r\n t: 'D',\r\n v: o\r\n };\r\n break;\r\n case ' ':\r\n out[out.length] = {\r\n t: c,\r\n v: c\r\n };\r\n ++i;\r\n break;\r\n case '$':\r\n out[out.length] = {\r\n t: 't',\r\n v: '$'\r\n };\r\n ++i;\r\n break;\r\n default:\r\n // if (\"¤฿BsBr₵₡₫ƒFtRs.₭kr£₤Lm₥₦₱PQRSkRp৲৳R$S/.〒₮₩¥NT¥zł₴₪៛руб€$,$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP\".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);\r\n if (\"¤฿BsBr₵₡₫ƒFtRs.₭kr£₤Lm₥₦₱PQRSkRp৲৳R$S/.〒₮₩¥NT¥zł₴₪៛руб€$,$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP$¥LekdinAf$dhAflRial?£BirrKzMOPPGKRsGsB/R$ррlevkrKMzBsPNuFBuKPkrRD$NfkCFA?CVEGMDFrCDHTGNAfLFdjKGSFGGHSRielKCFknKshLSLL£LtRFRONArRfMWKRMMURsMROS/KMDLMTnRC$kr€GELCHFSLLSCRDbSZLSDGSOSSomFCFPTShT$VUVQUGXгрнsomWSTNT$FtDramRpZMWFCFA\".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);\r\n out[out.length] = {\r\n t: 't',\r\n v: c\r\n };\r\n ++i;\r\n break;\r\n }\r\n }\r\n /* Scan for date/time parts */\r\n var bt = 0,\r\n ss0 = 0,\r\n ssm;\r\n for (i = out.length - 1, lst = 't'; i >= 0; --i) {\r\n switch (out[i].t) {\r\n case 'h':\r\n case 'H':\r\n out[i].t = hr;\r\n lst = 'h';\r\n if (bt < 1) bt = 1;\r\n break;\r\n case 's':\r\n if ((ssm = out[i].v.match(/\\.0+$/))) ss0 = Math.max(ss0, ssm[0].length - 1);\r\n if (bt < 3) bt = 3;\r\n /* falls through */\r\n case 'd':\r\n case 'y':\r\n case 'M':\r\n case 'e':\r\n lst = out[i].t;\r\n break;\r\n case 'm':\r\n if (lst === 's') {\r\n out[i].t = 'M';\r\n if (bt < 2) bt = 2;\r\n }\r\n break;\r\n case 'X':\r\n /*if(out[i].v === \"B2\");*/ break;\r\n case 'Z':\r\n if (bt < 1 && out[i].v.match(/[Hh]/)) bt = 1;\r\n if (bt < 2 && out[i].v.match(/[Mm]/)) bt = 2;\r\n if (bt < 3 && out[i].v.match(/[Ss]/)) bt = 3;\r\n }\r\n }\r\n /* time rounding depends on presence of minute / second / usec fields */\r\n switch (bt) {\r\n case 0:\r\n break;\r\n case 1:\r\n if (dt.u >= 0.5) {\r\n dt.u = 0;\r\n ++dt.S;\r\n }\r\n if (dt.S >= 60) {\r\n dt.S = 0;\r\n ++dt.M;\r\n }\r\n if (dt.M >= 60) {\r\n dt.M = 0;\r\n ++dt.H;\r\n }\r\n break;\r\n case 2:\r\n if (dt.u >= 0.5) {\r\n dt.u = 0;\r\n ++dt.S;\r\n }\r\n if (dt.S >= 60) {\r\n dt.S = 0;\r\n ++dt.M;\r\n }\r\n break;\r\n }\r\n /* replace fields */\r\n var nstr = \"\",\r\n jj;\r\n for (i = 0; i < out.length; ++i) {\r\n switch (out[i].t) {\r\n case 't':\r\n case 'T':\r\n case ' ':\r\n case 'D':\r\n break;\r\n case 'X':\r\n out[i].v = \"\";\r\n out[i].t = \";\";\r\n break;\r\n case 'd':\r\n case 'm':\r\n case 'y':\r\n case 'h':\r\n case 'H':\r\n case 'M':\r\n case 's':\r\n case 'e':\r\n case 'b':\r\n case 'Z':\r\n out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);\r\n out[i].t = 't';\r\n break;\r\n case 'n':\r\n case '?':\r\n jj = i + 1;\r\n while (out[jj] != null && (\r\n (c = out[jj].t) === \"?\" || c === \"D\" || ((c === \" \" || c === \"t\") && out[jj + 1] != null && (out[jj + 1].t === '?' || out[jj + 1].t === \"t\" && out[jj + 1].v === '/')) || (out[i].t === '(' && (c === ' ' || c === 'n' || c === ')')) || (c === 't' && (out[jj].v === '/' || out[jj].v === ' ' && out[jj + 1] != null && out[jj + 1].t == '?')))) {\r\n out[i].v += out[jj].v;\r\n out[jj] = {\r\n v: \"\",\r\n t: \";\"\r\n };\r\n ++jj;\r\n }\r\n nstr += out[i].v;\r\n i = jj - 1;\r\n break;\r\n case 'G':\r\n out[i].t = 't';\r\n out[i].v = general_fmt(v, opts);\r\n break;\r\n }\r\n }\r\n var vv = \"\",\r\n myv, ostr;\r\n if (nstr.length > 0) {\r\n if (nstr.charCodeAt(0) == 40) /* '(' */ {\r\n myv = (v < 0 && nstr.charCodeAt(0) === 45 ? -v : v);\r\n ostr = write_num('n', nstr, myv);\r\n } else {\r\n myv = (v < 0 && flen > 1 ? -v : v);\r\n ostr = write_num('n', nstr, myv);\r\n if (myv < 0 && out[0] && out[0].t == 't') {\r\n ostr = ostr.substr(1);\r\n out[0].v = \"-\" + out[0].v;\r\n }\r\n }\r\n jj = ostr.length - 1;\r\n var decpt = out.length;\r\n for (i = 0; i < out.length; ++i)\r\n if (out[i] != null && out[i].t != 't' && out[i].v.indexOf(\".\") > -1) {\r\n decpt = i;\r\n break;\r\n }\r\n var lasti = out.length;\r\n if (decpt === out.length && ostr.indexOf(\"E\") === -1) {\r\n for (i = out.length - 1; i >= 0; --i) {\r\n if (out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;\r\n if (jj >= out[i].v.length - 1) {\r\n jj -= out[i].v.length;\r\n out[i].v = ostr.substr(jj + 1, out[i].v.length);\r\n } else if (jj < 0) out[i].v = \"\";\r\n else {\r\n out[i].v = ostr.substr(0, jj + 1);\r\n jj = -1;\r\n }\r\n out[i].t = 't';\r\n lasti = i;\r\n }\r\n if (jj >= 0 && lasti < out.length) out[lasti].v = ostr.substr(0, jj + 1) + out[lasti].v;\r\n } else if (decpt !== out.length && ostr.indexOf(\"E\") === -1) {\r\n jj = ostr.indexOf(\".\") - 1;\r\n for (i = decpt; i >= 0; --i) {\r\n if (out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;\r\n j = out[i].v.indexOf(\".\") > -1 && i === decpt ? out[i].v.indexOf(\".\") - 1 : out[i].v.length - 1;\r\n vv = out[i].v.substr(j + 1);\r\n for (; j >= 0; --j) {\r\n if (jj >= 0 && (out[i].v.charAt(j) === \"0\" || out[i].v.charAt(j) === \"#\")) vv = ostr.charAt(jj--) + vv;\r\n }\r\n out[i].v = vv;\r\n out[i].t = 't';\r\n lasti = i;\r\n }\r\n if (jj >= 0 && lasti < out.length) out[lasti].v = ostr.substr(0, jj + 1) + out[lasti].v;\r\n jj = ostr.indexOf(\".\") + 1;\r\n for (i = decpt; i < out.length; ++i) {\r\n if (out[i] == null || ('n?('.indexOf(out[i].t) === -1 && i !== decpt)) continue;\r\n j = out[i].v.indexOf(\".\") > -1 && i === decpt ? out[i].v.indexOf(\".\") + 1 : 0;\r\n vv = out[i].v.substr(0, j);\r\n for (; j < out[i].v.length; ++j) {\r\n if (jj < ostr.length) vv += ostr.charAt(jj++);\r\n }\r\n out[i].v = vv;\r\n out[i].t = 't';\r\n lasti = i;\r\n }\r\n }\r\n }\r\n for (i = 0; i < out.length; ++i)\r\n if (out[i] != null && 'n?'.indexOf(out[i].t) > -1) {\r\n myv = (flen > 1 && v < 0 && i > 0 && out[i - 1].v === \"-\" ? -v : v);\r\n out[i].v = write_num(out[i].t, out[i].v, myv);\r\n out[i].t = 't';\r\n }\r\n var retval = \"\";\r\n for (i = 0; i !== out.length; ++i)\r\n if (out[i] != null) retval += out[i].v;\r\n return retval;\r\n }\r\n SSF._eval = eval_fmt;\r\n var cfregex = /\\[[=<>]/;\r\n var cfregex2 = /\\[(=|>[=]?|<[>=]?)(-?\\d+(?:\\.\\d*)?)\\]/;\r\n\r\n function chkcond(v, rr) {\r\n if (rr == null) return false;\r\n var thresh = parseFloat(rr[2]);\r\n switch (rr[1]) {\r\n case \"=\":\r\n if (v == thresh) return true;\r\n break;\r\n case \">\":\r\n if (v > thresh) return true;\r\n break;\r\n case \"<\":\r\n if (v < thresh) return true;\r\n break;\r\n case \"<>\":\r\n if (v != thresh) return true;\r\n break;\r\n case \">=\":\r\n if (v >= thresh) return true;\r\n break;\r\n case \"<=\":\r\n if (v <= thresh) return true;\r\n break;\r\n }\r\n return false;\r\n }\r\n\r\n function choose_fmt(f, v) {\r\n var fmt = split_fmt(f);\r\n var l = fmt.length,\r\n lat = fmt[l - 1].indexOf(\"@\");\r\n if (l < 4 && lat > -1) --l;\r\n if (fmt.length > 4) throw new Error(\"cannot find right format for |\" + fmt.join(\"|\") + \"|\");\r\n if (typeof v !== \"number\") return [4, fmt.length === 4 || lat > -1 ? fmt[fmt.length - 1] : \"@\"];\r\n switch (fmt.length) {\r\n case 1:\r\n fmt = lat > -1 ? [\"General\", \"General\", \"General\", fmt[0]] : [fmt[0], fmt[0], fmt[0], \"@\"];\r\n break;\r\n case 2:\r\n fmt = lat > -1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], \"@\"];\r\n break;\r\n case 3:\r\n fmt = lat > -1 ? [fmt[0], fmt[1], fmt[0], fmt[2]] : [fmt[0], fmt[1], fmt[2], \"@\"];\r\n break;\r\n case 4:\r\n break;\r\n }\r\n var ff = v > 0 ? fmt[0] : v < 0 ? fmt[1] : fmt[2];\r\n if (fmt[0].indexOf(\"[\") === -1 && fmt[1].indexOf(\"[\") === -1) return [l, ff];\r\n if (fmt[0].match(cfregex) != null || fmt[1].match(cfregex) != null) {\r\n var m1 = fmt[0].match(cfregex2);\r\n var m2 = fmt[1].match(cfregex2);\r\n return chkcond(v, m1) ? [l, fmt[0]] : chkcond(v, m2) ? [l, fmt[1]] : [l, fmt[m1 != null && m2 != null ? 2 : 1]];\r\n }\r\n return [l, ff];\r\n }\r\n\r\n function format(fmt, v, o) {\r\n if (o == null) o = {};\r\n var sfmt = \"\";\r\n switch (typeof fmt) {\r\n case \"string\":\r\n if (fmt == \"m/d/yy\" && o.dateNF) sfmt = o.dateNF;\r\n else sfmt = fmt;\r\n break;\r\n case \"number\":\r\n if (fmt == 14 && o.dateNF) sfmt = o.dateNF;\r\n else sfmt = (o.table != null ? (o.table) : table_fmt)[fmt];\r\n if (sfmt == null) sfmt = (o.table && o.table[default_map[fmt]]) || table_fmt[default_map[fmt]];\r\n if (sfmt == null) sfmt = default_str[fmt] || \"General\";\r\n break;\r\n }\r\n\r\n //new runze 增加万 亿 格式 \r\n //注:\"w\":2万2500 \"w0\":2万2500 \"w0.0\":2万2500.2 \"w0.00\":2万2500.23......自定义精确度\r\n var reg = /^(w|W)((0?)|(0\\.0+))$/;\r\n if(!!sfmt.match(reg)){\r\n if(isNaN(v)){\r\n return v;\r\n }\r\n\r\n //var v =300101886.436;\r\n var acc = sfmt.slice(1); //取得0/0.0/0.00\r\n var isNegative = false;\r\n if(!isNaN(v) && Number(v) < 0){\r\n isNegative = true;\r\n v = Math.abs(v);\r\n }\r\n var vInt = parseInt(v);\r\n \r\n var vlength = vInt.toString().length;\r\n if( vlength> 4){\r\n if(vlength > 8){\r\n var y =parseInt (v / 100000000); //亿\r\n var w = parseInt(parseFloat(v).subtract(y*100000000) / 10000); //万\r\n var q = parseFloat(v).subtract(y*100000000 + w*10000); //千以后\r\n if(acc != \"\"){\r\n q = numeral(q).format(acc); //处理精确度\r\n }\r\n v = y + \"亿\" + w + \"万\" + q;\r\n }else{\r\n var w = parseInt(v / 10000); //万\r\n var q = parseFloat(v).subtract(w*10000) //千以后\r\n if(acc != \"\"){\r\n q = numeral(q).format(acc); //处理精确度\r\n }\r\n v = w + \"万\" + q;\r\n }\r\n \r\n\r\n if(v.indexOf(\"亿0万0\") != -1){\r\n v = v.replace(\"0万0\",\"\");\r\n }else if(v.indexOf(\"亿0万\") != -1){\r\n v = v.replace(\"0万\",\"\");\r\n }else if(v.indexOf(\"万0\") != -1){\r\n v = v.replace(\"万0\",\"万\");\r\n }\r\n\r\n //舍弃正则后顾断言写法,旧浏览器不识别(360 V9)\r\n if (v.indexOf(\"亿\") != -1 && v.indexOf(\"万\") == -1) { //1亿/1亿111 => 1亿/1亿0111\r\n var afterYi = v.substring(v.indexOf(\"亿\") + 1);\r\n if (afterYi.substring(0, 1) !== \".\" && afterYi != \"\") {\r\n switch ((parseInt(afterYi) + \"\").length) {\r\n case 1:\r\n afterYi = \"000\" + afterYi;\r\n break;\r\n case 2:\r\n afterYi = \"00\" + afterYi;\r\n break;\r\n case 3:\r\n afterYi = \"0\" + afterYi;\r\n break;\r\n }\r\n v = v.substring(0, v.indexOf(\"亿\") + 1) + afterYi;\r\n }\r\n } else if (v.indexOf(\"亿\") == -1 && v.indexOf(\"万\") != -1) { //3万0011\r\n var afterWan = v.substring(v.indexOf(\"万\") + 1);\r\n if (afterWan.substring(0, 1) !== \".\" && afterWan != \"\") {\r\n switch ((parseInt(afterWan) + \"\").length) {\r\n case 1:\r\n afterWan = \"000\" + afterWan;\r\n break;\r\n case 2:\r\n afterWan = \"00\" + afterWan;\r\n break;\r\n case 3:\r\n afterWan = \"0\" + afterWan;\r\n break;\r\n }\r\n v = v.substring(0, v.indexOf(\"万\") + 1) + afterWan;\r\n }\r\n } else if (v.indexOf(\"亿\") != -1 && v.indexOf(\"万\") != -1) { //1亿0053万0611\r\n var afterYi = v.substring(v.indexOf(\"亿\") + 1,v.indexOf(\"万\")),\r\n afterWan = v.substring(v.indexOf(\"万\") + 1);\r\n\r\n switch ((parseInt(afterYi) + \"\").length) {\r\n case 1:\r\n afterYi = \"000\" + afterYi;\r\n break;\r\n case 2:\r\n afterYi = \"00\" + afterYi;\r\n break;\r\n case 3:\r\n afterYi = \"0\" + afterYi;\r\n break;\r\n }\r\n v = v.substring(0, v.indexOf(\"亿\") + 1) + afterYi + v.substring(v.indexOf(\"万\"))\r\n \r\n\r\n if (afterWan.substring(0, 1) !== \".\" && afterWan != \"\") {\r\n switch ((parseInt(afterWan) + \"\").length) {\r\n case 1:\r\n afterWan = \"000\" + afterWan;\r\n break;\r\n case 2:\r\n afterWan = \"00\" + afterWan;\r\n break;\r\n case 3:\r\n afterWan = \"0\" + afterWan;\r\n break;\r\n }\r\n v = v.substring(0, v.indexOf(\"万\") + 1) + afterWan\r\n }\r\n }\r\n\r\n }else{\r\n if(acc != \"\"){\r\n v = numeral(v).format(acc); //处理精确度\r\n }\r\n }\r\n if(isNegative){\r\n return '-' + v;\r\n }else{\r\n return v;\r\n }\r\n \r\n }\r\n\r\n\r\n if (isgeneral(sfmt, 0)) return general_fmt(v, o);\r\n if (v instanceof Date) v = datenum_local(v, o.date1904);\r\n var f = choose_fmt(sfmt, v);\r\n if (isgeneral(f[1])) return general_fmt(v, o);\r\n if (v === true) v = \"TRUE\";\r\n else if (v === false) v = \"FALSE\";\r\n else if (v === \"\" || v == null) return \"\";\r\n return eval_fmt(f[1], v, o, f[0]);\r\n }\r\n\r\n function load_entry(fmt, idx) {\r\n if (typeof idx != 'number') {\r\n idx = +idx || -1;\r\n for (var i = 0; i < 0x0188; ++i) {\r\n if (table_fmt[i] == undefined) {\r\n if (idx < 0) idx = i;\r\n continue;\r\n }\r\n if (table_fmt[i] == fmt) {\r\n idx = i;\r\n break;\r\n }\r\n }\r\n if (idx < 0) idx = 0x187;\r\n }\r\n table_fmt[idx] = fmt;\r\n return idx;\r\n }\r\n SSF.load = load_entry;\r\n SSF._table = table_fmt;\r\n SSF.get_table = function get_table() {\r\n return table_fmt;\r\n };\r\n SSF.load_table = function load_table(tbl) {\r\n for (var i = 0; i != 0x0188; ++i)\r\n if (tbl[i] !== undefined) load_entry(tbl[i], i);\r\n };\r\n SSF.init_table = init_table;\r\n SSF.format = format;\r\n};\r\nmake_ssf(SSF);\r\n\r\nvar XLMLFormatMap /*{[string]:string}*/ = ({\r\n \"General Number\": \"General\",\r\n \"General Date\": SSF._table[22],\r\n \"Long Date\": \"dddd, mmmm dd, yyyy\",\r\n \"Medium Date\": SSF._table[15],\r\n \"Short Date\": SSF._table[14],\r\n \"Long Time\": SSF._table[19],\r\n \"Medium Time\": SSF._table[18],\r\n \"Short Time\": SSF._table[20],\r\n \"Currency\": '\"$\"#,##0.00_);[Red]\\\\(\"$\"#,##0.00\\\\)',\r\n \"Fixed\": SSF._table[2],\r\n \"Standard\": SSF._table[4],\r\n \"Percent\": SSF._table[10],\r\n \"Scientific\": SSF._table[11],\r\n \"Yes/No\": '\"Yes\";\"Yes\";\"No\";@',\r\n \"True/False\": '\"True\";\"True\";\"False\";@',\r\n \"On/Off\": '\"Yes\";\"Yes\";\"No\";@'\r\n});\r\n\r\nvar unescapexml = (function() {\r\n /* 22.4.2.4 bstr (Basic String) */\r\n var encregex = /&(?:quot|apos|gt|lt|amp|#x?([\\da-fA-F]+));/g,\r\n coderegex = /_x([\\da-fA-F]{4})_/g;\r\n return function unescapexml(text) {\r\n var s = text + '',\r\n i = s.indexOf(\" -1 ? 16 : 10)) || $$;\r\n }).replace(coderegex, function(m, c) {\r\n return String.fromCharCode(parseInt(c, 16));\r\n });\r\n var j = s.indexOf(\"]]>\");\r\n return unescapexml(s.slice(0, i)) + s.slice(i + 9, j) + unescapexml(s.slice(j + 3));\r\n };\r\n})();\r\n\r\nfunction xlml_format(format, value) {\r\n var fmt = XLMLFormatMap[format] || unescapexml(format);\r\n if (fmt === \"General\") return SSF._general(value);\r\n return SSF.format(fmt, value);\r\n}\r\n\r\nvar basedate = new Date(1899, 11, 31, 0, 0, 0);\r\nvar dnthresh = basedate.getTime();\r\nvar base1904 = new Date(1900, 2, 1, 0, 0, 0);\r\n\r\nfunction datenum(v, date1904) {\r\n var epoch = v.getTime();\r\n if (date1904) epoch -= 1462 * 24 * 60 * 60 * 1000;\r\n return (epoch - dnthresh) / (24 * 60 * 60 * 1000);\r\n}\r\n\r\nexport function datenum_local(v, date1904) {\r\n var epoch = Date.UTC(v.getFullYear(), v.getMonth(), v.getDate(), v.getHours(), v.getMinutes(), v.getSeconds());\r\n var dnthresh_utc = Date.UTC(1899, 11, 31, 0, 0, 0);\r\n\r\n if (date1904) epoch -= 1461 * 24 * 60 * 60 * 1000;\r\n else if (v >= base1904) epoch += 24 * 60 * 60 * 1000;\r\n return (epoch - dnthresh_utc) / (24 * 60 * 60 * 1000);\r\n}\r\n\r\nfunction numdate(v) {\r\n var out = new Date();\r\n out.setTime(v * 24 * 60 * 60 * 1000 + dnthresh);\r\n return out;\r\n}\r\n/* ISO 8601 Duration */\r\nfunction parse_isodur(s) {\r\n var sec = 0,\r\n mt = 0,\r\n time = false;\r\n var m = s.match(/P([0-9\\.]+Y)?([0-9\\.]+M)?([0-9\\.]+D)?T([0-9\\.]+H)?([0-9\\.]+M)?([0-9\\.]+S)?/);\r\n if (!m) throw new Error(\"|\" + s + \"| is not an ISO8601 Duration\");\r\n for (var i = 1; i != m.length; ++i) {\r\n if (!m[i]) continue;\r\n mt = 1;\r\n if (i > 3) time = true;\r\n switch (m[i].slice(m[i].length - 1)) {\r\n case 'Y':\r\n throw new Error(\"Unsupported ISO Duration Field: \" + m[i].slice(m[i].length - 1));\r\n case 'D':\r\n mt *= 24;\r\n /* falls through */\r\n case 'H':\r\n mt *= 60;\r\n /* falls through */\r\n case 'M':\r\n if (!time) throw new Error(\"Unsupported ISO Duration Field: M\");\r\n else mt *= 60;\r\n /* falls through */\r\n case 'S':\r\n break;\r\n }\r\n sec += mt * parseInt(m[i], 10);\r\n }\r\n return sec;\r\n}\r\nvar good_pd_date = new Date('2017-02-19T19:06:09.000Z');\r\nif (isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');\r\nvar good_pd = good_pd_date.getFullYear() == 2017;\r\n/* parses a date as a local date */\r\nfunction parseDate(str, fixdate) {\r\n var d = new Date(str);\r\n //console.log(d);\r\n if (good_pd) {\r\n if (fixdate > 0) d.setTime(d.getTime() + d.getTimezoneOffset() * 60 * 1000);\r\n else if (fixdate < 0) d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000);\r\n return d;\r\n }\r\n if (str instanceof Date) return str;\r\n if (good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {\r\n var s = d.getFullYear();\r\n if (str.indexOf(\"\" + s) > -1) return d;\r\n d.setFullYear(d.getFullYear() + 100);\r\n return d;\r\n }\r\n var n = str.match(/\\d+/g) || [\"2017\", \"2\", \"19\", \"0\", \"0\", \"0\"];\r\n var out = new Date(+n[0], +n[1] - 1, +n[2], (+n[3] || 0), (+n[4] || 0), (+n[5] || 0));\r\n if (str.indexOf(\"Z\") > -1) out = new Date(out.getTime() - out.getTimezoneOffset() * 60 * 1000);\r\n return out;\r\n}\r\n\r\n/* TODO: stress test */\r\nfunction fuzzynum(s) {\r\n var v = Number(s);\r\n if(typeof s == \"number\"){\r\n return s;\r\n }\r\n if (!isNaN(v)) return v;\r\n var wt = 1;\r\n var ss = s.replace(/([\\d]),([\\d])/g, \"$1$2\").replace(/[$]/g, \"\").replace(/[%]/g, function() {\r\n wt *= 100;\r\n return \"\";\r\n });\r\n if (!isNaN(v = Number(ss))) return v / wt;\r\n ss = ss.replace(/[(](.*)[)]/, function($$, $1) {\r\n wt = -wt;\r\n return $1;\r\n });\r\n if (!isNaN(v = Number(ss))) return v / wt;\r\n return v;\r\n}\r\n\r\nfunction fuzzydate(s) {\r\n var o = new Date(s),\r\n n = new Date(NaN);\r\n var y = o.getYear(),\r\n m = o.getMonth(),\r\n d = o.getDate();\r\n if (isNaN(d)) return n;\r\n if (y < 0 || y > 8099) return n;\r\n if ((m > 0 || d > 1) && y != 101) return o;\r\n if (s.toLowerCase().match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) return o;\r\n if (s.match(/[^-0-9:,\\/\\\\]/)) return n;\r\n return o;\r\n}\r\n\r\nexport function genarate(value) {//万 单位格式增加!!!\r\n var ret = [];\r\n var m = null, ct = {}, v = value;\r\n \r\n if(value == null){\r\n return null;\r\n }\r\n\r\n if(value.toString().substr(0, 1) === \"'\"){\r\n m = value.toString().substr(1);\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n else if(value.toString().toUpperCase() === \"TRUE\"){\r\n m = \"TRUE\";\r\n ct = { \"fa\": \"General\", \"t\": \"b\" };\r\n v = true;\r\n }\r\n else if(value.toString().toUpperCase() === \"FALSE\"){\r\n m = \"FALSE\";\r\n ct = { \"fa\": \"General\", \"t\": \"b\" };\r\n v = false;\r\n }\r\n else if(valueIsError(value)){\r\n m = value.toString();\r\n ct = { \"fa\": \"General\", \"t\": \"e\" };\r\n }\r\n else if(/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(value)){\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n else if(isRealNum(value) && Math.abs(parseFloat(value)) > 0 && (Math.abs(parseFloat(value)) >= 1e+11 || Math.abs(parseFloat(value)) < 1e-9)){\r\n v = numeral(value).value();\r\n\r\n var str = v.toExponential();\r\n if(str.indexOf(\".\") > -1){\r\n var strlen = str.split(\".\")[1].split(\"e\")[0].length;\r\n if(strlen > 5){\r\n strlen = 5;\r\n }\r\n\r\n ct = { \"fa\": \"#0.\"+ new Array(strlen + 1).join(\"0\") +\"E+00\", \"t\": \"n\" }; \r\n }\r\n else{\r\n ct = { \"fa\": \"#0.E+00\", \"t\": \"n\" };\r\n }\r\n\r\n m = SSF.format(ct.fa, v);\r\n }\r\n else if(value.toString().indexOf(\"%\") > -1){\r\n var index = value.toString().indexOf(\"%\");\r\n var value2 = value.toString().substr(0, index);\r\n var value3 = value2.replace(/,/g, \"\");\r\n\r\n if(index == value.toString().length - 1 && isRealNum(value3)){\r\n if(value2.indexOf(\".\") > -1){\r\n if(value2.indexOf(\".\") == value2.lastIndexOf(\".\")){\r\n var value4 = value2.split(\".\")[0];\r\n var value5 = value2.split(\".\")[1];\r\n\r\n var len = value5.length;\r\n if(len > 9){\r\n len = 9;\r\n }\r\n\r\n if(value4.indexOf(\",\") > -1){\r\n var isThousands = true;\r\n var ThousandsArr = value4.split(\",\");\r\n\r\n for(var i = 1; i < ThousandsArr.length; i++){\r\n if(ThousandsArr[i].length < 3){\r\n isThousands = false;\r\n break;\r\n }\r\n }\r\n\r\n if(isThousands){\r\n ct = { \"fa\": \"#,##0.\" + new Array(len + 1).join(\"0\") + \"%\", \"t\": \"n\" };\r\n v = numeral(value).value();\r\n m = SSF.format(ct.fa, v);\r\n }\r\n else{\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n }\r\n else{\r\n ct = { \"fa\": \"0.\" + new Array(len + 1).join(\"0\") + \"%\", \"t\": \"n\" };\r\n v = numeral(value).value();\r\n m = SSF.format(ct.fa, v);\r\n }\r\n }\r\n else{\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n }\r\n else if(value2.indexOf(\",\") > -1){\r\n var isThousands = true;\r\n var ThousandsArr = value2.split(\",\");\r\n\r\n for(var i = 1; i < ThousandsArr.length; i++){\r\n if(ThousandsArr[i].length < 3){\r\n isThousands = false;\r\n break;\r\n }\r\n }\r\n\r\n if(isThousands){\r\n ct = { \"fa\": \"#,##0%\", \"t\": \"n\" };\r\n v = numeral(value).value();\r\n m = SSF.format(ct.fa, v);\r\n }\r\n else{\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n }\r\n else{\r\n ct = { \"fa\": \"0%\", \"t\": \"n\" };\r\n v = numeral(value).value();\r\n m = SSF.format(ct.fa, v);\r\n }\r\n }\r\n else{\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n }\r\n else if(value.toString().indexOf(\".\") > -1){\r\n if(value.toString().indexOf(\".\") == value.toString().lastIndexOf(\".\")){\r\n var value1 = value.toString().split(\".\")[0];\r\n var value2 = value.toString().split(\".\")[1];\r\n\r\n var len = value2.length;\r\n if(len > 9){\r\n len = 9;\r\n }\r\n\r\n if(value1.indexOf(\",\") > -1){\r\n var isThousands = true;\r\n var ThousandsArr = value1.split(\",\");\r\n\r\n for(var i = 1; i < ThousandsArr.length; i++){\r\n if(!isRealNum(ThousandsArr[i]) || ThousandsArr[i].length < 3){\r\n isThousands = false;\r\n break;\r\n }\r\n }\r\n\r\n if(isThousands){\r\n ct = { \"fa\": \"#,##0.\" + new Array(len + 1).join(\"0\"), \"t\": \"n\" };\r\n v = numeral(value).value();\r\n m = SSF.format(ct.fa, v);\r\n }\r\n else{\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n }\r\n else{\r\n if(isRealNum(value1) && isRealNum(value2)){\r\n ct = { \"fa\": \"0.\" + new Array(len + 1).join(\"0\"), \"t\": \"n\" };\r\n v = numeral(value).value();\r\n m = SSF.format(ct.fa, v);\r\n }\r\n else{\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n }\r\n }\r\n else{\r\n m = value.toString();\r\n ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n }\r\n }\r\n else if(isRealNum(value)){\r\n m = value.toString();\r\n ct = { \"fa\": \"General\", \"t\": \"n\" };\r\n v = parseFloat(value);\r\n }\r\n else if (isdatetime(value) && (value.toString().indexOf(\".\") > -1 || value.toString().indexOf(\":\") > -1 || value.toString().length < 16)){\r\n v = datenum_local(parseDate(value.toString().replace(/-/g, \"/\")));\r\n\r\n if(v.toString().indexOf(\".\") > -1){\r\n if(value.toString().length > 18){\r\n ct.fa = \"yyyy-MM-dd hh:mm:ss\";\r\n }\r\n else if(value.toString().length > 11){\r\n ct.fa = \"yyyy-MM-dd hh:mm\";\r\n }\r\n else{\r\n ct.fa = \"yyyy-MM-dd\";\r\n }\r\n }\r\n else{\r\n ct.fa = \"yyyy-MM-dd\";\r\n }\r\n \r\n ct.t = \"d\";\r\n m = SSF.format(ct.fa, v);\r\n }\r\n else{\r\n m = value;\r\n ct.fa = \"General\";\r\n ct.t = \"g\";\r\n }\r\n\r\n return [m, ct, v];\r\n}\r\n\r\nexport function update(fmt, v) {\r\n return SSF.format(fmt, v);\r\n}\r\n\r\nexport function is_date(fmt, v) {\r\n return SSF.is_date(fmt, v);\r\n}\r\n\r\nexport function valueShowEs(r, c, d) {\r\n var value = getcellvalue(r, c, d, \"m\");\r\n if(value == null){\r\n value = getcellvalue(r, c, d, \"v\");\r\n }\r\n else{\r\n if (!isNaN(fuzzynum(value))){\r\n if(typeof(value) == \"string\" && value.indexOf(\"%\") > -1){\r\n \r\n }\r\n else{\r\n value = getcellvalue(r, c, d, \"v\");\r\n }\r\n }\r\n // else if (!isNaN(parseDate(value).getDate())){\r\n else if (d[r][c].ct != null && d[r][c].ct.t == \"d\"){\r\n\r\n }\r\n else if (d[r][c].ct != null && d[r][c].ct.t == \"b\"){\r\n\r\n }\r\n else{\r\n value = getcellvalue(r, c, d, \"v\");\r\n }\r\n }\r\n return value;\r\n}\r\n","import { getObjType } from '../utils/util';\r\nimport { isRealNull, isRealNum, valueIsError } from './validate';\r\nimport { genarate, update } from './format';\r\nimport server from '../controllers/server';\r\nimport luckysheetConfigsetting from '../controllers/luckysheetConfigsetting';\r\nimport Store from '../store/index'\r\n\r\n//Set cell value\r\nfunction setcellvalue(r, c, d, v) {\r\n if(d == null){\r\n d = Store.flowdata;\r\n }\r\n // 若采用深拷贝,初始化时的单元格属性丢失\r\n // let cell = $.extend(true, {}, d[r][c]);\r\n let cell = d[r][c];\r\n\r\n let vupdate;\r\n\r\n if(getObjType(v) == \"object\"){\r\n if(cell == null){\r\n cell = v;\r\n }\r\n else{\r\n if(v.f != null){\r\n cell.f = v.f;\r\n }\r\n // else{\r\n // delete cell.f;\r\n // }\r\n \r\n if(v.spl != null){\r\n cell.spl = v.spl;\r\n }\r\n\r\n if(v.ct != null){\r\n cell.ct = v.ct;\r\n }\r\n }\r\n \r\n\r\n if(getObjType(v.v) == \"object\"){\r\n vupdate = v.v.v;\r\n }\r\n else{\r\n vupdate = v.v;\r\n }\r\n }\r\n else{\r\n vupdate = v;\r\n }\r\n\r\n if(isRealNull(vupdate)){\r\n if(getObjType(cell) == \"object\"){\r\n delete cell.m;\r\n delete cell.v;\r\n }\r\n else{\r\n cell = null;\r\n }\r\n\r\n d[r][c] = cell;\r\n\r\n return;\r\n }\r\n\r\n // 1.为null\r\n // 2.数据透视表的数据,flowdata的每个数据可能为字符串,结果就是cell == v == 一个字符串或者数字数据\r\n if(isRealNull(cell) || (getObjType(cell) === 'string' || getObjType(cell) === 'number') && cell === v){\r\n cell = {};\r\n }\r\n \r\n if(vupdate.toString().substr(0, 1) == \"'\"){\r\n cell.m = vupdate.toString().substr(1);\r\n cell.ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n cell.v = vupdate.toString().substr(1);\r\n cell.qp = 1;\r\n }\r\n else if(cell.qp == 1){\r\n cell.m = vupdate.toString();\r\n cell.ct = { \"fa\": \"@\", \"t\": \"s\" };\r\n cell.v = vupdate.toString();\r\n }\r\n else if(vupdate.toString().toUpperCase() === \"TRUE\"){\r\n cell.m = \"TRUE\";\r\n cell.ct = { \"fa\": \"General\", \"t\": \"b\" };\r\n cell.v = true;\r\n }\r\n else if(vupdate.toString().toUpperCase() === \"FALSE\"){\r\n cell.m = \"FALSE\";\r\n cell.ct = { \"fa\": \"General\", \"t\": \"b\" };\r\n cell.v = false;\r\n }\r\n else if(valueIsError(vupdate)){\r\n cell.m = vupdate.toString();\r\n // cell.ct = { \"fa\": \"General\", \"t\": \"e\" };\r\n if(cell.ct!=null){\r\n cell.ct.t = \"e\";\r\n }\r\n else{\r\n cell.ct = { \"fa\": \"General\", \"t\": \"e\" };\r\n }\r\n cell.v = vupdate;\r\n }\r\n else{\r\n if(cell.f != null && isRealNum(vupdate) && !/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(vupdate)){\r\n cell.v = parseFloat(vupdate);\r\n if(cell.ct==null){\r\n cell.ct = { \"fa\": \"General\", \"t\": \"n\" };\r\n }\r\n\r\n if(cell.v == Infinity || cell.v == -Infinity){\r\n cell.m = cell.v.toString();\r\n }\r\n else{\r\n if(cell.v.toString().indexOf(\"e\") > -1){\r\n let len;\r\n if(cell.v.toString().split(\".\").length==1){\r\n len = 0;\r\n }\r\n else{\r\n len = cell.v.toString().split(\".\")[1].split(\"e\")[0].length;\r\n }\r\n if(len > 5){\r\n len = 5;\r\n }\r\n\r\n cell.m = cell.v.toExponential(len).toString();\r\n }\r\n else{\r\n let v_p = Math.round(cell.v * 1000000000) / 1000000000;\r\n if(cell.ct==null){\r\n let mask = genarate(v_p);\r\n cell.m = mask[0].toString(); \r\n }\r\n else{\r\n let mask = update(cell.ct.fa, v_p);\r\n cell.m = mask.toString();\r\n }\r\n\r\n // cell.m = mask[0].toString();\r\n }\r\n }\r\n }\r\n else if(cell.ct != null && cell.ct.fa == \"@\"){\r\n cell.m = vupdate.toString();\r\n cell.v = vupdate;\r\n }\r\n else if(cell.ct != null && cell.ct.fa != null && cell.ct.fa != \"General\"){\r\n if(isRealNum(vupdate)){\r\n vupdate = parseFloat(vupdate);\r\n }\r\n\r\n let mask = update(cell.ct.fa, vupdate);\r\n\r\n if(mask === vupdate){ //若原来单元格格式 应用不了 要更新的值,则获取更新值的 格式\r\n mask = genarate(vupdate);\r\n\r\n cell.m = mask[0].toString();\r\n cell.ct = mask[1];\r\n cell.v = mask[2];\r\n }\r\n else{\r\n cell.m = mask.toString();\r\n cell.v = vupdate;\r\n }\r\n }\r\n else{\r\n if(isRealNum(vupdate) && !/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(vupdate)){\r\n vupdate = parseFloat(vupdate);\r\n\r\n cell.v = parseFloat(vupdate);\r\n cell.ct = { \"fa\": \"General\", \"t\": \"n\" };\r\n\r\n if(cell.v == Infinity || cell.v == -Infinity){\r\n cell.m = cell.v.toString();\r\n }\r\n else{\r\n let mask = genarate(cell.v);\r\n\r\n cell.m = mask[0].toString();\r\n }\r\n }\r\n else{\r\n let mask = genarate(vupdate);\r\n\r\n cell.m = mask[0].toString();\r\n cell.ct = mask[1];\r\n cell.v = mask[2];\r\n }\r\n }\r\n }\r\n\r\n if(!server.allowUpdate && !luckysheetConfigsetting.pointEdit){\r\n if(cell.ct != null && /^(w|W)((0?)|(0\\.0+))$/.test(cell.ct.fa) == false && cell.ct.t == \"n\" && cell.v != null && parseInt(cell.v).toString().length > 4){\r\n let autoFormatw = luckysheetConfigsetting.autoFormatw.toString().toUpperCase();\r\n let accuracy = luckysheetConfigsetting.accuracy;\r\n \r\n let sfmt = setAccuracy(autoFormatw, accuracy);\r\n\r\n if(sfmt != \"General\") {\r\n cell.ct.fa = sfmt;\r\n cell.m = update(sfmt, cell.v);\r\n }\r\n }\r\n }\r\n\r\n d[r][c] = cell;\r\n}\r\n\r\n//new runze 根据亿万格式autoFormatw和精确度accuracy 转换成 w/w0/w0.00 or 0/0.0格式 \r\nfunction setAccuracy(autoFormatw, accuracy) {\r\n let acc = \"0.\";\r\n let fmt;\r\n \r\n if(autoFormatw == \"TRUE\"){\r\n if(accuracy == undefined){\r\n return \"w\";\r\n }\r\n else{\r\n let alength = parseInt(accuracy);\r\n \r\n if(alength == 0){\r\n return \"w0\";\r\n }\r\n else{\r\n acc = \"w0.\";\r\n\r\n for(let i = 0; i < alength; i++){\r\n acc += \"0\";\r\n }\r\n\r\n fmt = acc;\r\n }\r\n }\r\n }\r\n else{\r\n if(accuracy == undefined){\r\n return \"General\";\r\n }\r\n else{\r\n let alength = parseInt(accuracy);\r\n \r\n if(alength == 0){\r\n return \"0\";\r\n }\r\n else{\r\n for(let i = 0; i < alength; i++){\r\n acc += \"0\";\r\n }\r\n\r\n fmt = acc;\r\n }\r\n \r\n }\r\n }\r\n\r\n return fmt.toString(); \r\n}\r\n\r\nexport {\r\n setcellvalue,\r\n setAccuracy,\r\n}","function luckysheetbinary_search(arr, key) {\r\n let low = 0, high = arr.length - 1;\r\n \r\n while (low <= high) {\r\n let mid = parseInt((high + low) / 2);\r\n \r\n if (key < arr[mid] && (mid == 0 || key >= arr[mid - 1])) {\r\n return mid;\r\n } \r\n else if (key >= arr[mid]) {\r\n low = mid + 1;\r\n } \r\n else if (key < arr[mid]) {\r\n high = mid - 1;\r\n }\r\n else {\r\n return -1;\r\n }\r\n }\r\n}\r\n\r\nfunction luckysheetorder_search(arr, y) {\r\n let i = 0, \r\n row = 0, \r\n row_pre = 0, \r\n row_index = -1, \r\n i_ed = arr.length - 1;\r\n\r\n while (i < arr.length && i_ed >= 0 && i_ed >= i) {\r\n row = arr[i_ed];\r\n\r\n if (i_ed == 0) {\r\n row_pre = 0;\r\n }\r\n else {\r\n row_pre = arr[i_ed - 1];\r\n }\r\n\r\n if (y >= row_pre && y < row) {\r\n row_index = i_ed;\r\n break;\r\n }\r\n\r\n row = arr[i];\r\n\r\n if (i == 0) {\r\n row_pre = 0;\r\n }\r\n else {\r\n row_pre = arr[i - 1];\r\n }\r\n\r\n if (y >= row_pre && y < row) {\r\n row_index = i;\r\n break;\r\n }\r\n\r\n i++;\r\n i_ed--;\r\n }\r\n\r\n return row_index;\r\n}\r\n\r\nfunction luckysheet_searcharray(arr, y) {\r\n let index = arr.length - 1;\r\n\r\n if (arr.length < 40 || y <= arr[20] || y >= arr[index - 20]) {\r\n index = luckysheetorder_search(arr, y);\r\n }\r\n else {\r\n index = luckysheetbinary_search(arr, y);\r\n }\r\n\r\n return index;\r\n}\r\n\r\nexport {\r\n luckysheet_searcharray,\r\n}","import { luckysheet_searcharray } from '../controllers/sheetSearch';\r\nimport Store from '../store';\r\n\r\nfunction rowLocationByIndex(row_index) {\r\n let row = 0, row_pre = 0;\r\n row = Store.visibledatarow[row_index];\r\n\r\n if (row_index == 0) {\r\n row_pre = 0;\r\n }\r\n else {\r\n row_pre = Store.visibledatarow[row_index - 1];\r\n }\r\n\r\n return [row_pre, row, row_index];\r\n}\r\n\r\nfunction rowLocation(y) {\r\n let row_index = luckysheet_searcharray(Store.visibledatarow, y);\r\n\r\n if (row_index == -1 && y > 0) {\r\n row_index = Store.visibledatarow.length - 1;\r\n }\r\n else if (row_index == -1 && y <= 0) {\r\n row_index = 0;\r\n }\r\n \r\n return rowLocationByIndex(row_index);\r\n}\r\n\r\nfunction colLocationByIndex(col_index){\r\n let col = 0, col_pre = 0; \r\n col = Store.visibledatacolumn[col_index];\r\n\r\n if (col_index == 0) {\r\n col_pre = 0;\r\n }\r\n else {\r\n col_pre = Store.visibledatacolumn[col_index - 1];\r\n }\r\n\r\n return [col_pre, col, col_index];\r\n}\r\n\r\nfunction colLocation(x) {\r\n let col_index = luckysheet_searcharray(Store.visibledatacolumn, x);\r\n\r\n if (col_index == -1 && x > 0) {\r\n col_index = Store.visibledatacolumn.length - 1;\r\n }\r\n else if (col_index == -1 && x <= 0) {\r\n col_index = 0;\r\n }\r\n\r\n return colLocationByIndex(col_index);\r\n}\r\n\r\nfunction mouseposition(x, y) {\r\n let container_offset = $(\"#\" + Store.container).offset();\r\n \r\n let newX = x - container_offset.left - Store.rowHeaderWidth,\r\n newY = y - container_offset.top - Store.infobarHeight - Store.toolbarHeight - Store.calculatebarHeight - Store.columnHeaderHeight;\r\n\r\n return [newX, newY];\r\n}\r\n\r\nexport {\r\n rowLocationByIndex,\r\n rowLocation,\r\n colLocationByIndex,\r\n colLocation,\r\n mouseposition,\r\n}","import { luckysheetfontformat } from '../utils/util';\r\nimport menuButton from '../controllers/menuButton';\r\nimport { getcellvalue,checkstatusByCell } from './getdata';\r\nimport { colLocationByIndex } from './location';\r\nimport { hasChinaword, isRealNull,checkWordByteLength } from './validate';\r\nimport { isInlineStringCell } from '../controllers/inlineString';\r\nimport Store from '../store';\r\n\r\n//计算范围行高\r\nfunction rowlenByRange(d, r1, r2, cfg) {\r\n let cfg_clone = $.extend(true, {}, cfg);\r\n if(cfg_clone[\"rowlen\"] == null){\r\n cfg_clone[\"rowlen\"] = {};\r\n }\r\n\r\n if(cfg_clone[\"customHeight\"] == null){\r\n cfg_clone[\"customHeight\"] = {};\r\n }\r\n\r\n let canvas = $(\"#luckysheetTableContent\").get(0).getContext(\"2d\");\r\n canvas.textBaseline = 'top'; //textBaseline以top计算\r\n\r\n for(let r = r1; r <= r2; r++){\r\n if (cfg_clone[\"rowhidden\"] != null && cfg_clone[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n let currentRowLen = Store.defaultrowlen;\r\n\r\n if(cfg_clone[\"customHeight\"][r]==1){\r\n continue;\r\n }\r\n\r\n delete cfg_clone[\"rowlen\"][r];\r\n\r\n for(let c = 0; c < d[r].length; c++){\r\n let cell = d[r][c];\r\n\r\n if(cell == null || cell.mc != null){\r\n continue;\r\n }\r\n\r\n if(cell != null && (cell.v != null || isInlineStringCell(cell)) ){\r\n let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 2;\r\n\r\n let textInfo = getCellTextInfo(cell, canvas,{\r\n r:r,\r\n c:c,\r\n cellWidth:cellWidth\r\n });\r\n\r\n let computeRowlen = 0;\r\n\r\n if(textInfo!=null){\r\n computeRowlen = textInfo.textHeightAll+2;\r\n }\r\n\r\n //比较计算高度和当前高度取最大高度\r\n if(computeRowlen > currentRowLen){\r\n currentRowLen = computeRowlen;\r\n }\r\n }\r\n }\r\n\r\n currentRowLen = currentRowLen/Store.zoomRatio;\r\n\r\n if(currentRowLen != Store.defaultrowlen){\r\n cfg_clone[\"rowlen\"][r] = currentRowLen;\r\n }\r\n }\r\n\r\n return cfg_clone;\r\n}\r\n\r\n//计算表格行高数组\r\nfunction computeRowlenArr(rowHeight, cfg) {\r\n let rowlenArr = [];\r\n let rh_height = 0;\r\n\r\n for (let i = 0; i < rowHeight; i++) {\r\n let rowlen = Store.defaultrowlen;\r\n\r\n if (cfg[\"rowlen\"] != null && cfg[\"rowlen\"][i] != null) {\r\n rowlen = cfg[\"rowlen\"][i];\r\n }\r\n\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][i] != null) {\r\n rowlen = cfg[\"rowhidden\"][i];\r\n rowlenArr.push(rh_height);\r\n continue;\r\n }\r\n else {\r\n rh_height += rowlen + 1;\r\n }\r\n\r\n rowlenArr.push(rh_height);//行的临时长度分布\r\n }\r\n\r\n return rowlenArr;\r\n}\r\n\r\n//获取换行单元格截断数组\r\nfunction getCellTextSplitArr(strValue, strArr, cellWidth, canvas){\r\n for(let strI = 1; strI <= strValue.length; strI++){\r\n let strV = strValue.substring(0, strI);\r\n let strtextMetrics = getMeasureText(strV, canvas).width;\r\n\r\n if(strtextMetrics > cellWidth){\r\n if(strI - 1 <= 0){\r\n return strArr;\r\n }\r\n else{\r\n strArr.push(strValue.substring(0, strI - 1));\r\n return getCellTextSplitArr(strValue.substring(strI - 1), strArr, cellWidth, canvas);\r\n }\r\n }\r\n else if(strI == strValue.length){\r\n strArr.push(strV);\r\n }\r\n }\r\n\r\n return strArr;\r\n}\r\n\r\n//获取有值单元格文本大小\r\n// let measureTextCache = {}, measureTextCacheTimeOut = null;\r\nfunction getMeasureText(value, ctx, fontset){\r\n\r\n let mtc = Store.measureTextCache[value + \"_\" + ctx.font];\r\n if(fontset!=null){\r\n mtc = Store.measureTextCache[value + \"_\" + fontset];\r\n }\r\n\r\n if(mtc != null){\r\n return mtc;\r\n }\r\n else{\r\n if(fontset!=null){\r\n let preFont = ctx.font;\r\n ctx.font = fontset;\r\n }\r\n\r\n let measureText = ctx.measureText(value), cache = {};\r\n // var regu = \"^[ ]+$\";\r\n // var re = new RegExp(regu);\r\n // if(measureText.actualBoundingBoxRight==null || re.test(value)){\r\n // cache.width = measureText.width;\r\n // }\r\n // else{\r\n // //measureText.actualBoundingBoxLeft +\r\n // cache.width = measureText.actualBoundingBoxRight;\r\n // }\r\n\r\n cache.width = measureText.width;\r\n\r\n if(fontset!=null){\r\n ctx.font = fontset;\r\n }\r\n\r\n cache.actualBoundingBoxDescent = measureText.actualBoundingBoxDescent;\r\n cache.actualBoundingBoxAscent = measureText.actualBoundingBoxAscent;\r\n if(cache.actualBoundingBoxDescent==null || cache.actualBoundingBoxAscent==null || isNaN(cache.actualBoundingBoxDescent) || isNaN(cache.actualBoundingBoxAscent)){\r\n let commonWord = \"M\"\r\n if(hasChinaword(value)){\r\n commonWord = \"田\";\r\n }\r\n let oneLineTextHeight = menuButton.getTextSize(commonWord, ctx.font)[1]*0.8;\r\n if(ctx.textBaseline==\"top\"){\r\n cache.actualBoundingBoxDescent = oneLineTextHeight;\r\n cache.actualBoundingBoxAscent = 0;\r\n }\r\n else if(ctx.textBaseline==\"middle\"){\r\n cache.actualBoundingBoxDescent = oneLineTextHeight/2;\r\n cache.actualBoundingBoxAscent = oneLineTextHeight/2;\r\n }\r\n else{\r\n cache.actualBoundingBoxDescent = 0;\r\n cache.actualBoundingBoxAscent = oneLineTextHeight;\r\n }\r\n\r\n //console.log(value, oneLineTextHeight, measureText.actualBoundingBoxDescent+measureText.actualBoundingBoxAscent,ctx.font);\r\n }\r\n\r\n if(ctx.textBaseline == 'alphabetic'){\r\n let descText = \"gjpqy\", matchText=\"abcdABCD\";\r\n let descTextMeasure = Store.measureTextCache[descText + \"_\" + ctx.font];\r\n if(fontset!=null){\r\n descTextMeasure = Store.measureTextCache[descText + \"_\" + fontset];\r\n }\r\n\r\n let matchTextMeasure = Store.measureTextCache[matchText + \"_\" + ctx.font];\r\n if(fontset!=null){\r\n matchTextMeasure = Store.measureTextCache[matchText + \"_\" + fontset];\r\n }\r\n\r\n if(descTextMeasure == null){\r\n descTextMeasure = ctx.measureText(descText);\r\n }\r\n\r\n if(matchTextMeasure == null){\r\n matchTextMeasure = ctx.measureText(matchText);\r\n }\r\n\r\n if(cache.actualBoundingBoxDescent<=matchTextMeasure.actualBoundingBoxDescent){\r\n cache.actualBoundingBoxDescent = descTextMeasure.actualBoundingBoxDescent;\r\n if(cache.actualBoundingBoxDescent==null){\r\n cache.actualBoundingBoxDescent = 0;\r\n }\r\n }\r\n\r\n\r\n }\r\n\r\n cache.width *= Store.zoomRatio;\r\n cache.actualBoundingBoxDescent *= Store.zoomRatio;\r\n cache.actualBoundingBoxAscent *= Store.zoomRatio;\r\n Store.measureTextCache[value + \"_\" + Store.zoomRatio + \"_\" + ctx.font] = cache;\r\n // console.log(measureText, value);\r\n return cache;\r\n }\r\n}\r\n\r\nfunction isSupportBoundingBox(ctx){\r\n let measureText = ctx.measureText(\"田\");\r\n if(measureText.actualBoundingBoxAscent==null){\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n\r\n//获取单元格文本内容的渲染信息\r\n// let measureTextCache = {}, measureTextCacheTimeOut = null;\r\n// option {cellWidth,cellHeight,space_width,space_height}\r\nfunction getCellTextInfo(cell , ctx, option){\r\n let cellWidth = option.cellWidth;\r\n let cellHeight = option.cellHeight;\r\n let isMode = \"\", isModeSplit = \"\";\r\n // console.log(\"initialinfo\", cell, option);\r\n if(cellWidth==null){\r\n isMode = \"onlyWidth\";\r\n isModeSplit = \"_\";\r\n }\r\n let textInfo = Store.measureTextCellInfoCache[option.r + \"_\" + option.c + isModeSplit + isMode];\r\n if(textInfo != null){\r\n return textInfo;\r\n }\r\n\r\n // let cell = Store.flowdata[r][c];\r\n let space_width = option.space_width, space_height = option.space_height; //宽高方向 间隙\r\n\r\n if(space_width==null){\r\n space_width = 2;\r\n }\r\n\r\n if(space_height==null){\r\n space_height = 2;\r\n }\r\n\r\n //水平对齐\r\n let horizonAlign = checkstatusByCell(cell, \"ht\");\r\n //垂直对齐\r\n let verticalAlign = checkstatusByCell(cell, \"vt\");\r\n\r\n let tb = checkstatusByCell(cell ,\"tb\");//wrap overflow\r\n let tr = checkstatusByCell(cell ,\"tr\");//rotate\r\n let rt = checkstatusByCell(cell ,\"rt\");//rotate angle\r\n\r\n let isRotateUp = 1, isRotateDown=0;\r\n\r\n if(rt==null){\r\n if(tr==\"0\"){\r\n rt = 0;\r\n }\r\n else if(tr==\"1\"){\r\n rt = 45;\r\n }\r\n else if(tr==\"4\"){\r\n rt = 90;\r\n }\r\n else if(tr==\"2\"){\r\n rt = 135;\r\n }\r\n else if(tr==\"5\"){\r\n rt = 180;\r\n }\r\n\r\n if(rt==null){\r\n rt = 0;\r\n }\r\n }\r\n\r\n if(rt>180 || rt<0){\r\n rt = 0;\r\n }\r\n\r\n rt = parseInt(rt);\r\n if(rt>90){\r\n rt = 90 -rt;\r\n isRotateUp = 0;\r\n isRotateDown = 1;\r\n }\r\n\r\n ctx.textAlign=\"start\";\r\n\r\n let textContent = {};\r\n textContent.values = [];\r\n\r\n let fontset, cancelLine=\"0\", underLine=\"0\", fontSize=11, isInline=false, value, inlineStringArr=[];\r\n if(isInlineStringCell(cell)){\r\n let sharedStrings = cell.ct.s, similarIndex = 0;\r\n for(let i=0;icellHeight && textH_all_Column[colIndex]!=null){\r\n // textW_all += textW;\r\n // textH_all = Math.max(textH_all,textH_all_cache);\r\n // console.log(\">\",i,colIndex);\r\n textH_all_ColumnHeight.push(textH_all_cache-textH);\r\n textH_all_cache = textH;\r\n colIndex +=1;\r\n }\r\n }\r\n\r\n if(i== inlineStringArr.length-1){\r\n textH_all_ColumnHeight.push(textH_all_cache);\r\n }\r\n\r\n if(textH_all_Column[colIndex]==null){\r\n textH_all_Column[colIndex]= [];\r\n }\r\n\r\n let item = {\r\n content:showValue,\r\n style:shareCell,\r\n width:textW,\r\n height:textH,\r\n left:0,\r\n top:0,\r\n colIndex:colIndex,\r\n asc:measureText.actualBoundingBoxAscent,\r\n desc:measureText.actualBoundingBoxDescent,\r\n inline:true,\r\n }\r\n\r\n if(shareCell.wrap===true){\r\n item.wrap=true;\r\n }\r\n\r\n textH_all_Column[colIndex].push(item);\r\n console.log(\"normal\",i,colIndex,shareCell, preShareCell, textH_all_Column);\r\n preShareCell = shareCell;\r\n\r\n }\r\n }\r\n else{\r\n let measureText = getMeasureText(value, ctx);\r\n let textHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;\r\n\r\n value = value.toString();\r\n\r\n let vArr = [];\r\n if(value.length > 1){\r\n vArr = value.split(\"\");\r\n }\r\n else{\r\n vArr.push(value);\r\n }\r\n let oneWordWidth = getMeasureText(vArr[0], ctx).width;\r\n\r\n for(let i = 0; i < vArr.length; i++){\r\n let textW = oneWordWidth + space_width;\r\n let textH = textHeight + space_height;\r\n\r\n // textW_all += textW;\r\n textH_all_cache += textH;\r\n\r\n\r\n if(tb==\"2\"){\r\n if(textH_all_cache>cellHeight && textH_all_Column[colIndex]!=null){\r\n // textW_all += textW;\r\n // textH_all = Math.max(textH_all,textH_all_cache);\r\n textH_all_ColumnHeight.push(textH_all_cache-textH);\r\n textH_all_cache = textH;\r\n colIndex +=1;\r\n }\r\n }\r\n\r\n if(i== vArr.length-1){\r\n textH_all_ColumnHeight.push(textH_all_cache);\r\n }\r\n\r\n if(textH_all_Column[colIndex]==null){\r\n textH_all_Column[colIndex]= [];\r\n }\r\n\r\n textH_all_Column[colIndex].push({\r\n content:vArr[i],\r\n style:fontset,\r\n width:textW,\r\n height:textH,\r\n left:0,\r\n top:0,\r\n colIndex:colIndex,\r\n asc:measureText.actualBoundingBoxAscent,\r\n desc:measureText.actualBoundingBoxDescent\r\n });\r\n\r\n }\r\n }\r\n\r\n let textH_all_ColumWidth = [];\r\n for(let i = 0; i < textH_all_ColumnHeight.length; i++){\r\n let columnHeight = textH_all_ColumnHeight[i];\r\n let col = textH_all_Column[i], colMaxW=0;\r\n for(let c=0;c1){\r\n for(let s=0;scellHeight);\r\n if((height+space_height)>cellHeight && text_all_split[splitIndex]!=null && tb==\"2\" && i!= inlineStringArr.length){\r\n // console.log(\"cut\",anchor, i , str);\r\n\r\n if(spaceOrTwoByteIndex!=null && spaceOrTwoByteIndexcellWidth && text_all_split[splitIndex]!=null && tb==\"2\" && i!= inlineStringArr.length){\r\n\r\n\r\n if(spaceOrTwoByteIndex!=null && spaceOrTwoByteIndexcellHeight && text_all_split[splitIndex]!=null && i!= value.length){\r\n // console.log(\"cut\",anchor, i , str);\r\n\r\n if(spaceOrTwoByte!=null && spaceOrTwoByte.indexcellWidth && text_all_split[splitIndex]!=null && i!= value.length){\r\n // console.log(spaceOrTwoByte, i, anchor);\r\n if(spaceOrTwoByte!=null && spaceOrTwoByte.index=0;c--){\r\n let wordGroup = splitLists[c];\r\n let left, top;\r\n if(rt!=0){//rotate\r\n let x, y = cumWordHeight+size.asc;\r\n\r\n x = (cumWordHeight)/Math.tan(rtPI) - cumColumnWidth + textW_all_inner;\r\n if(horizonAlign == \"0\"){//center\r\n let sh = textH_all/Math.sin(rtPI);\r\n if(verticalAlign == \"0\"){//mid\r\n\r\n left = x + cellWidth/2 - (textW_all/2) + lastLineSpaceHeight*Math.cos(rtPI)/2;\r\n top = y + cellHeight/2 - textH_all/2 - lastLineSpaceHeight*Math.cos(rtPI)/2;\r\n }\r\n else if(verticalAlign == \"1\"){//top\r\n left = x + cellWidth/2 - textW_all/2;\r\n top = y - (textH_all/2 - rh/2);\r\n }\r\n else if(verticalAlign == \"2\"){//bottom\r\n left = x + cellWidth/2 - (textW_all/2)+lastLineSpaceHeight*Math.cos(rtPI);\r\n top = y + cellHeight - rh/2 - textH_all/2 - lastLineSpaceHeight*Math.cos(rtPI);\r\n }\r\n }\r\n else if(horizonAlign == \"1\"){//left\r\n if(verticalAlign == \"0\"){//mid\r\n left = x - rh*Math.sin(rtPI)/2 + lastLineSpaceHeight*Math.cos(rtPI)/2;\r\n top = y + cellHeight/2 + rh*Math.cos(rtPI)/2 - lastLineSpaceHeight*Math.cos(rtPI)/2;\r\n }\r\n else if(verticalAlign == \"1\"){//top\r\n left = x - rh*Math.sin(rtPI);\r\n top = y + rh*Math.cos(rtPI);\r\n }\r\n else if(verticalAlign == \"2\"){//bottom\r\n left = x + lastLineSpaceHeight*Math.cos(rtPI);\r\n top = y + cellHeight - lastLineSpaceHeight*Math.cos(rtPI);\r\n }\r\n }\r\n else if(horizonAlign == \"2\"){//right\r\n if(verticalAlign == \"0\"){//mid\r\n left = x + cellWidth - rw/2 - (textW_all_inner/2+(textH_all/2)/Math.tan(rtPI))+ lastLineSpaceHeight*Math.cos(rtPI)/2;\r\n top = y + cellHeight/2 - textH_all/2 - lastLineSpaceHeight*Math.cos(rtPI)/2;\r\n }\r\n else if(verticalAlign == \"1\"){//top fixOneLineLeft\r\n left = x + cellWidth - textW_all + fixOneLineLeft;\r\n top = y - textH_all;\r\n }\r\n else if(verticalAlign == \"2\"){//bottom\r\n left = x + cellWidth - rw*Math.cos(rtPI) + lastLineSpaceHeight*Math.cos(rtPI);\r\n top = y + cellHeight - rw*Math.sin(rtPI) - lastLineSpaceHeight*Math.cos(rtPI);\r\n }\r\n }\r\n\r\n }\r\n\r\n wordGroup.left = left;\r\n wordGroup.top = top;\r\n\r\n // console.log(left, top, cumWordHeight, size.height);\r\n\r\n drawLineInfo(wordGroup, cancelLine, underLine,{\r\n width:wordGroup.width,\r\n height:wordGroup.height,\r\n left:left-wordGroup.width,\r\n top:top,\r\n asc:size.asc,\r\n desc:size.desc,\r\n fs:wordGroup.fs\r\n });\r\n\r\n textContent.values.push(wordGroup);\r\n\r\n cumColumnWidth += wordGroup.width;\r\n }\r\n\r\n\r\n cumWordHeight += size.height;\r\n\r\n\r\n }\r\n }\r\n else{\r\n for(let i = 0; i < splitLen; i++){\r\n let splitLists = text_all_split[i];\r\n if(splitLists==null){\r\n continue;\r\n }\r\n let size = split_all_size[i];\r\n\r\n cumColumnWidth = 0;\r\n\r\n for(let c=0;c 1 ? arguments[1] : undefined, length);\n var end = argumentsLength > 2 ? arguments[2] : undefined;\n var endPos = end === undefined ? length : toAbsoluteIndex(end, length);\n while (endPos > index) O[index++] = value;\n return O;\n};\n","var $ = require('../internals/export');\nvar fill = require('../internals/array-fill');\nvar addToUnscopables = require('../internals/add-to-unscopables');\n\n// `Array.prototype.fill` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.fill\n$({ target: 'Array', proto: true }, {\n fill: fill\n});\n\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables('fill');\n","module.exports = {};\n","'use strict';\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar has = require('../internals/has');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar IS_PURE = require('../internals/is-pure');\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar BUGGY_SAFARI_ITERATORS = false;\n\nvar returnThis = function () { return this; };\n\n// `%IteratorPrototype%` object\n// https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object\nvar IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;\n\nif ([].keys) {\n arrayIterator = [].keys();\n // Safari 8 has buggy iterators w/o `next`\n if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;\n else {\n PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator));\n if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;\n }\n}\n\nif (IteratorPrototype == undefined) IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nif (!IS_PURE && !has(IteratorPrototype, ITERATOR)) {\n createNonEnumerableProperty(IteratorPrototype, ITERATOR, returnThis);\n}\n\nmodule.exports = {\n IteratorPrototype: IteratorPrototype,\n BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS\n};\n","var defineProperty = require('../internals/object-define-property').f;\nvar has = require('../internals/has');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\n\nmodule.exports = function (it, TAG, STATIC) {\n if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {\n defineProperty(it, TO_STRING_TAG, { configurable: true, value: TAG });\n }\n};\n","'use strict';\nvar IteratorPrototype = require('../internals/iterators-core').IteratorPrototype;\nvar create = require('../internals/object-create');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar Iterators = require('../internals/iterators');\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (IteratorConstructor, NAME, next) {\n var TO_STRING_TAG = NAME + ' Iterator';\n IteratorConstructor.prototype = create(IteratorPrototype, { next: createPropertyDescriptor(1, next) });\n setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true);\n Iterators[TO_STRING_TAG] = returnThis;\n return IteratorConstructor;\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar createIteratorConstructor = require('../internals/create-iterator-constructor');\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\nvar setPrototypeOf = require('../internals/object-set-prototype-of');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar redefine = require('../internals/redefine');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar IS_PURE = require('../internals/is-pure');\nvar Iterators = require('../internals/iterators');\nvar IteratorsCore = require('../internals/iterators-core');\n\nvar IteratorPrototype = IteratorsCore.IteratorPrototype;\nvar BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;\nvar ITERATOR = wellKnownSymbol('iterator');\nvar KEYS = 'keys';\nvar VALUES = 'values';\nvar ENTRIES = 'entries';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {\n createIteratorConstructor(IteratorConstructor, NAME, next);\n\n var getIterationMethod = function (KIND) {\n if (KIND === DEFAULT && defaultIterator) return defaultIterator;\n if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) return IterablePrototype[KIND];\n switch (KIND) {\n case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };\n case VALUES: return function values() { return new IteratorConstructor(this, KIND); };\n case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };\n } return function () { return new IteratorConstructor(this); };\n };\n\n var TO_STRING_TAG = NAME + ' Iterator';\n var INCORRECT_VALUES_NAME = false;\n var IterablePrototype = Iterable.prototype;\n var nativeIterator = IterablePrototype[ITERATOR]\n || IterablePrototype['@@iterator']\n || DEFAULT && IterablePrototype[DEFAULT];\n var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);\n var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;\n var CurrentIteratorPrototype, methods, KEY;\n\n // fix native\n if (anyNativeIterator) {\n CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable()));\n if (IteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {\n if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) {\n if (setPrototypeOf) {\n setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype);\n } else if (typeof CurrentIteratorPrototype[ITERATOR] != 'function') {\n createNonEnumerableProperty(CurrentIteratorPrototype, ITERATOR, returnThis);\n }\n }\n // Set @@toStringTag to native iterators\n setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true);\n if (IS_PURE) Iterators[TO_STRING_TAG] = returnThis;\n }\n }\n\n // fix Array#{values, @@iterator}.name in V8 / FF\n if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {\n INCORRECT_VALUES_NAME = true;\n defaultIterator = function values() { return nativeIterator.call(this); };\n }\n\n // define iterator\n if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) {\n createNonEnumerableProperty(IterablePrototype, ITERATOR, defaultIterator);\n }\n Iterators[NAME] = defaultIterator;\n\n // export additional methods\n if (DEFAULT) {\n methods = {\n values: getIterationMethod(VALUES),\n keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),\n entries: getIterationMethod(ENTRIES)\n };\n if (FORCED) for (KEY in methods) {\n if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {\n redefine(IterablePrototype, KEY, methods[KEY]);\n }\n } else $({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);\n }\n\n return methods;\n};\n","'use strict';\nvar toIndexedObject = require('../internals/to-indexed-object');\nvar addToUnscopables = require('../internals/add-to-unscopables');\nvar Iterators = require('../internals/iterators');\nvar InternalStateModule = require('../internals/internal-state');\nvar defineIterator = require('../internals/define-iterator');\n\nvar ARRAY_ITERATOR = 'Array Iterator';\nvar setInternalState = InternalStateModule.set;\nvar getInternalState = InternalStateModule.getterFor(ARRAY_ITERATOR);\n\n// `Array.prototype.entries` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.entries\n// `Array.prototype.keys` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.keys\n// `Array.prototype.values` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.values\n// `Array.prototype[@@iterator]` method\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@iterator\n// `CreateArrayIterator` internal method\n// https://tc39.github.io/ecma262/#sec-createarrayiterator\nmodule.exports = defineIterator(Array, 'Array', function (iterated, kind) {\n setInternalState(this, {\n type: ARRAY_ITERATOR,\n target: toIndexedObject(iterated), // target\n index: 0, // next index\n kind: kind // kind\n });\n// `%ArrayIteratorPrototype%.next` method\n// https://tc39.github.io/ecma262/#sec-%arrayiteratorprototype%.next\n}, function () {\n var state = getInternalState(this);\n var target = state.target;\n var kind = state.kind;\n var index = state.index++;\n if (!target || index >= target.length) {\n state.target = undefined;\n return { value: undefined, done: true };\n }\n if (kind == 'keys') return { value: index, done: false };\n if (kind == 'values') return { value: target[index], done: false };\n return { value: [index, target[index]], done: false };\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values%\n// https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject\n// https://tc39.github.io/ecma262/#sec-createmappedargumentsobject\nIterators.Arguments = Iterators.Array;\n\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n","var global = require('../internals/global');\nvar DOMIterables = require('../internals/dom-iterables');\nvar ArrayIteratorMethods = require('../modules/es.array.iterator');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar ArrayValues = ArrayIteratorMethods.values;\n\nfor (var COLLECTION_NAME in DOMIterables) {\n var Collection = global[COLLECTION_NAME];\n var CollectionPrototype = Collection && Collection.prototype;\n if (CollectionPrototype) {\n // some Chrome versions have non-configurable methods on DOMTokenList\n if (CollectionPrototype[ITERATOR] !== ArrayValues) try {\n createNonEnumerableProperty(CollectionPrototype, ITERATOR, ArrayValues);\n } catch (error) {\n CollectionPrototype[ITERATOR] = ArrayValues;\n }\n if (!CollectionPrototype[TO_STRING_TAG]) {\n createNonEnumerableProperty(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME);\n }\n if (DOMIterables[COLLECTION_NAME]) for (var METHOD_NAME in ArrayIteratorMethods) {\n // some Chrome versions have non-configurable methods on DOMTokenList\n if (CollectionPrototype[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try {\n createNonEnumerableProperty(CollectionPrototype, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]);\n } catch (error) {\n CollectionPrototype[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME];\n }\n }\n }\n}\n","import Store from '../store';\r\nimport { getdatabyselectionNoCopy } from './getdata';\r\nimport { isRealNull, isRealNum } from './validate';\r\nimport { update } from './format';\r\nimport locale from '../locale/locale';\r\n\r\n//表格计数栏\r\nexport function countfunc() {\r\n if(Store.luckysheet_select_save.length == 0){\r\n return;\r\n }\r\n\r\n let min = Infinity, //最小值\r\n \tmax = -Infinity, //最大值\r\n \tsum = 0, //求和 \r\n \tcount = 0, //计数(非空单元格)\r\n \tmean = 0; //平均值\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let data = getdatabyselectionNoCopy(Store.luckysheet_select_save[s]);\r\n\r\n for (let r = 0; r < data.length; r++) {\r\n for (let c = 0; c < data[0].length; c++) {\r\n if(isRealNull(data[r][c])){\r\n continue;\r\n }\r\n\r\n count++;\r\n\r\n if(data[r][c].ct != null && data[r][c].ct.t == \"d\"){\r\n continue;\r\n }\r\n\r\n let value = data[r][c].v;\r\n\r\n if(!isRealNum(value)){\r\n continue;\r\n }\r\n\r\n value = parseFloat(value);\r\n\r\n sum += value;\r\n\r\n if(value < min){\r\n min = value;\r\n }\r\n\r\n if(value > max){\r\n max = value;\r\n }\r\n }\r\n }\r\n }\r\n\r\n let locale_formula = locale().formula;\r\n\r\n let ret = \"\";\r\n ret += \"\"+locale_formula.count+\":\" + count + \"\";\r\n\r\n //处理成亿万格式\r\n if (isFinite(max) || isFinite(min)) {\r\n ret += \"\"+locale_formula.sum+\":\" + update(\"w\", sum) + \"\";\r\n ret += \"\"+locale_formula.average+\":\" + update(\"w\", Math.round(sum / count * 10000) / 10000) + \"\";\r\n }\r\n\r\n if (isFinite(max)) {\r\n ret += \"\"+locale_formula.max+\":\" + update(\"w\", max) + \"\";\r\n }\r\n\r\n if (isFinite(min)) {\r\n ret += \"\"+locale_formula.min+\":\" + update(\"w\", min) + \"\";\r\n }\r\n\r\n $(\"#luckysheet-sta-content\").html(ret);\r\n}\r\n","import { getObjType } from '../utils/util';\r\nimport formula from '../global/formula';\r\nimport { isRealNull } from '../global/validate';\r\nimport { countfunc } from '../global/count';\r\nimport menuButton from './menuButton';\r\nimport { selectHightlightShow } from './select';\r\nimport pivotTable from './pivotTable';\r\nimport Store from '../store';\r\nimport server from './server';\r\n\r\nfunction luckysheetMoveEndCell(postion, type, isScroll, terminal, onlyvalue) {\r\n if (isScroll == null) {\r\n isScroll = true;\r\n }\r\n\r\n if (!postion) {\r\n postion = \"down\";\r\n }\r\n\r\n if (!type) {\r\n type = \"cell\";\r\n }\r\n\r\n if (onlyvalue == null) {\r\n onlyvalue = false;\r\n }\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n\r\n let curR = last[\"row\"] == null ? 0 : last[\"row\"][0];\r\n let curC = last[\"column\"] == null ? 0 : last[\"column\"][0];\r\n\r\n let startR = last[\"row\"] == null ? 0 : last[\"row\"][0];\r\n let startC = last[\"column\"] == null ? 0 : last[\"column\"][0];\r\n\r\n let endR = last[\"row\"] == null ? 0 : last[\"row\"][1];\r\n let endC = last[\"column\"] == null ? 0 : last[\"column\"][1];\r\n\r\n formula.fucntionboxshow(curR, curC);\r\n\r\n if (type == \"range\") {\r\n // need var\r\n var p_startR = Store.luckysheet_shiftpositon[\"row\"][0];\r\n var p_startC = Store.luckysheet_shiftpositon[\"column\"][0];\r\n\r\n let p_endR = Store.luckysheet_shiftpositon[\"row\"][1];\r\n let p_endC = Store.luckysheet_shiftpositon[\"column\"][1];\r\n\r\n if (postion == \"down\" || postion == \"up\") {\r\n if (p_endR < endR) {\r\n curR = last[\"row\"] == null ? 0 : last[\"row\"][1];\r\n }\r\n else if (p_startR > startR) {\r\n curR = last[\"row\"] == null ? 0 : last[\"row\"][0];\r\n }\r\n else if (p_endR == endR && p_startR == startR) {\r\n if (postion == \"down\") {\r\n curR = last[\"row\"] == null ? 0 : last[\"row\"][1];\r\n }\r\n else {\r\n curR = last[\"row\"] == null ? 0 : last[\"row\"][0];\r\n }\r\n }\r\n }\r\n else if (postion == \"right\" || postion == \"left\") {\r\n if (p_endC < endC) {\r\n curC = last[\"column\"] == null ? 0 : last[\"column\"][1];\r\n }\r\n else if (p_startC > startC) {\r\n curC = last[\"column\"] == null ? 0 : last[\"column\"][0];\r\n }\r\n else if (p_endC == endC && p_startC == startC) {\r\n if (postion == \"right\") {\r\n curC = last[\"column\"] == null ? 0 : last[\"column\"][1];\r\n }\r\n else {\r\n curC = last[\"column\"] == null ? 0 : last[\"column\"][0];\r\n }\r\n }\r\n }\r\n }\r\n\r\n let datarowlen = Store.flowdata.length, \r\n datacolumnlen = Store.flowdata[0].length;\r\n\r\n let data = Store.flowdata, moveP = \"\", moveV = 0;\r\n\r\n if (postion == \"up\") {\r\n if (curR == 0) {\r\n return;\r\n }\r\n else {\r\n let stvalue = [], p = null, i = 0, p_pre = null;\r\n for (let c = startC; c <= endC; c++) {\r\n stvalue = [];\r\n i = 0;\r\n\r\n for (let r = curR - 1; r >= 0; r--) {\r\n let cell = data[r][c];\r\n\r\n if (getObjType(cell) == \"object\" && isRealNull(cell.v)) {\r\n stvalue.push(false);\r\n }\r\n else if (isRealNull(cell)) {\r\n stvalue.push(false);\r\n }\r\n else {\r\n stvalue.push(true);\r\n }\r\n\r\n if (stvalue.length > 1) {\r\n if (stvalue[i] == true && stvalue[i - 1] == false) {\r\n p = r;\r\n break\r\n }\r\n else if (stvalue[i] == false && stvalue[i - 1] == true) {\r\n p = r + 1;\r\n break\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n if(p == null){\r\n p = 0;\r\n }\r\n\r\n if (p_pre == null || p < p_pre) {\r\n p_pre = p;\r\n }\r\n }\r\n \r\n moveP = \"down\";\r\n moveV = p_pre - curR;\r\n }\r\n }\r\n else if (postion == \"down\") {\r\n if (curR == datarowlen - 1) {\r\n return;\r\n }\r\n else {\r\n let stvalue = [], p = null, i = 0, p_pre = null;\r\n for (let c = startC; c <= endC; c++) {\r\n stvalue = [];\r\n i = 0;\r\n\r\n for (let r = curR + 1; r < data.length; r++) {\r\n let cell = data[r][c];\r\n\r\n if (getObjType(cell) == \"object\" && isRealNull(cell.v)) {\r\n stvalue.push(false);\r\n }\r\n else if (isRealNull(cell)) {\r\n stvalue.push(false);\r\n }\r\n else {\r\n stvalue.push(true);\r\n }\r\n \r\n if (stvalue.length > 1) {\r\n if (stvalue[i] == true && stvalue[i - 1] == false) {\r\n p = r;\r\n break\r\n }\r\n else if (stvalue[i] == false && stvalue[i - 1] == true) {\r\n p = r - 1;\r\n break\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n if(p == null){\r\n p = data.length - 1;\r\n }\r\n\r\n if (p_pre == null || p > p_pre) {\r\n p_pre = p;\r\n }\r\n }\r\n \r\n moveP = \"down\";\r\n moveV = p_pre - curR;\r\n }\r\n }\r\n else if (postion == \"left\") {\r\n if (curC == 0) {\r\n return;\r\n }\r\n else {\r\n let stvalue = [], p = null, i = 0, p_pre = null;\r\n for (let r = startR; r <= endR; r++) {\r\n stvalue = [];\r\n i = 0;\r\n for (let c = curC - 1; c >= 0; c--) {\r\n let cell = data[r][c];\r\n\r\n if (getObjType(cell) == \"object\" && isRealNull(cell.v)) {\r\n stvalue.push(false);\r\n }\r\n else if (isRealNull(cell)) {\r\n stvalue.push(false);\r\n }\r\n else {\r\n stvalue.push(true);\r\n }\r\n\r\n if (stvalue.length > 1) {\r\n if (stvalue[i] == true && stvalue[i - 1] == false) {\r\n p = c;\r\n break\r\n }\r\n else if (stvalue[i] == false && stvalue[i - 1] == true) {\r\n p = c + 1;\r\n break\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n if(p == null){\r\n p = 0;\r\n }\r\n\r\n if (p_pre == null || p < p_pre) {\r\n p_pre = p;\r\n }\r\n }\r\n \r\n moveP = \"right\";\r\n moveV = p_pre - curC;\r\n }\r\n }\r\n else if (postion == \"right\") {\r\n if (curC == datacolumnlen - 1) {\r\n return;\r\n }\r\n else {\r\n let stvalue = [], p = null, i = 0, p_pre = null;\r\n for (let r = startR; r <= endR; r++) {\r\n stvalue = [];\r\n i = 0;\r\n\r\n for (let c = curC + 1; c < data[0].length; c++) {\r\n let cell = data[r][c];\r\n\r\n if (getObjType(cell) == \"object\" && isRealNull(cell.v)) {\r\n stvalue.push(false);\r\n }\r\n else if (isRealNull(cell)) {\r\n stvalue.push(false);\r\n }\r\n else {\r\n stvalue.push(true);\r\n }\r\n\r\n if (stvalue.length > 1) {\r\n if (stvalue[i] == true && stvalue[i - 1] == false) {\r\n p = c;\r\n break\r\n }\r\n else if (stvalue[i] == false && stvalue[i - 1] == true) {\r\n p = c - 1;\r\n break\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n if(p == null){\r\n p = data[0].length - 1;\r\n }\r\n\r\n if (p_pre == null || p > p_pre) {\r\n p_pre = p;\r\n }\r\n }\r\n\r\n moveP = \"right\";\r\n moveV = p_pre - curC;\r\n }\r\n }\r\n\r\n if (type == \"range\") {\r\n if (postion == \"up\") {\r\n if (p_endR < endR) {\r\n if (moveV + curR < p_endR) {\r\n moveV = p_endR - curR;\r\n }\r\n }\r\n }\r\n else if (postion == \"down\") {\r\n if (p_startR > startR) {\r\n if (moveV + curR > p_startR) {\r\n moveV = p_startR - curR;\r\n }\r\n }\r\n }\r\n else if (postion == \"left\") {\r\n if (p_endC < endC) {\r\n if (moveV + curC < p_endC) {\r\n moveV = p_endC - curC;\r\n }\r\n }\r\n }\r\n else if (postion == \"right\") {\r\n if (p_startC > startC) {\r\n if (moveV + curC > p_startC) {\r\n moveV = p_startC - curC;\r\n }\r\n }\r\n }\r\n\r\n if (terminal != null && Math.abs(moveV) > Math.abs(terminal)) {\r\n moveV = terminal;\r\n }\r\n }\r\n\r\n if (!onlyvalue) {\r\n if (type == \"cell\") {\r\n luckysheetMoveHighlightCell(moveP, moveV, \"rangeOfSelect\", isScroll);\r\n }\r\n else if (type == \"range\") {\r\n luckysheetMoveHighlightRange(moveP, moveV, \"rangeOfSelect\", isScroll);\r\n }\r\n }\r\n else {\r\n return moveV;\r\n }\r\n}\r\n\r\n//方向键 调整单元格\r\nfunction luckysheetMoveHighlightCell(postion, index, type, isScroll) {\r\n if (isScroll == null) {\r\n isScroll = true;\r\n }\r\n\r\n if (!postion) {\r\n postion == \"down\";\r\n }\r\n\r\n let datarowlen = Store.flowdata.length, \r\n datacolumnlen = Store.flowdata[0].length;\r\n\r\n let row, row_pre, row_index, row_index_ed;\r\n let col, col_pre, col_index, col_index_ed;\r\n\r\n if(type == \"rangeOfSelect\"){\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n \r\n let curR;\r\n if(last[\"row_focus\"] == null){\r\n curR = last[\"row\"][0]; \r\n }\r\n else{\r\n curR = last[\"row_focus\"]; \r\n }\r\n\r\n let curC;\r\n if(last[\"column_focus\"] == null){\r\n curC = last[\"column\"][0];\r\n }\r\n else{\r\n curC = last[\"column_focus\"]; \r\n }\r\n \r\n //focus单元格 是否是合并单元格\r\n let margeset = menuButton.mergeborer(Store.flowdata, curR, curC);\r\n if(!!margeset){\r\n let str_r = margeset.row[2];\r\n let end_r = margeset.row[3];\r\n\r\n let str_c = margeset.column[2];\r\n let end_c = margeset.column[3];\r\n\r\n if(index > 0){\r\n if(postion == \"down\"){\r\n curR = end_r;\r\n curC = str_c;\r\n }\r\n else if(postion == \"right\"){\r\n curR = str_r;\r\n curC = end_c;\r\n }\r\n }\r\n else{\r\n curR = str_r;\r\n curC = str_c;\r\n }\r\n }\r\n\r\n let moveX = last[\"moveXY\"] == null ? curR : last[\"moveXY\"].x;\r\n let moveY = last[\"moveXY\"] == null ? curC : last[\"moveXY\"].y;\r\n\r\n if (postion == \"down\") {\r\n curR += index;\r\n moveX = curR;\r\n }\r\n else if (postion == \"right\") {\r\n curC += index;\r\n moveY = curC;\r\n }\r\n\r\n if (curR >= datarowlen) {\r\n curR = datarowlen - 1;\r\n moveX = curR;\r\n }\r\n\r\n if (curR < 0) {\r\n curR = 0;\r\n moveX = curR;\r\n }\r\n\r\n if (curC >= datacolumnlen) {\r\n curC = datacolumnlen - 1;\r\n moveY = curC;\r\n }\r\n\r\n if (curC < 0) {\r\n curC = 0;\r\n moveY = curC;\r\n }\r\n\r\n //移动的下一个单元格是否是合并的单元格\r\n let margeset2 = menuButton.mergeborer(Store.flowdata, curR, curC);\r\n if(!!margeset2){\r\n row = margeset2.row[1];\r\n row_pre = margeset2.row[0];\r\n row_index = margeset2.row[2];\r\n row_index_ed = margeset2.row[3];\r\n\r\n col = margeset2.column[1];\r\n col_pre = margeset2.column[0];\r\n col_index = margeset2.column[2];\r\n col_index_ed = margeset2.column[3];\r\n }\r\n else{\r\n row = Store.visibledatarow[moveX]; \r\n row_pre = moveX - 1 == -1 ? 0 : Store.visibledatarow[moveX - 1];\r\n row_index = moveX;\r\n row_index_ed = moveX;\r\n\r\n col = Store.visibledatacolumn[moveY]; \r\n col_pre = moveY - 1 == -1 ? 0 : Store.visibledatacolumn[moveY - 1];\r\n col_index = moveY;\r\n col_index_ed = moveY;\r\n }\r\n\r\n last[\"row\"] = [row_index, row_index_ed];\r\n last[\"column\"] = [col_index, col_index_ed];\r\n last[\"row_focus\"] = row_index;\r\n last[\"column_focus\"] = col_index;\r\n last[\"moveXY\"] = {\"x\": moveX,\"y\": moveY};\r\n\r\n selectHightlightShow();\r\n pivotTable.pivotclick(row_index, col_index);\r\n formula.fucntionboxshow(row_index, col_index);\r\n }\r\n else if(type == \"rangeOfFormula\"){\r\n let last = formula.func_selectedrange;\r\n \r\n let curR;\r\n if(last[\"row_focus\"] == null){\r\n curR = last[\"row\"][0]; \r\n }\r\n else{\r\n curR = last[\"row_focus\"]; \r\n }\r\n\r\n let curC;\r\n if(last[\"column_focus\"] == null){\r\n curC = last[\"column\"][0];\r\n }\r\n else{\r\n curC = last[\"column_focus\"]; \r\n }\r\n \r\n //focus单元格 是否是合并单元格\r\n let margeset = menuButton.mergeborer(Store.flowdata, curR, curC);\r\n if(!!margeset){\r\n let str_r = margeset.row[2];\r\n let end_r = margeset.row[3];\r\n\r\n let str_c = margeset.column[2];\r\n let end_c = margeset.column[3];\r\n\r\n if(index > 0){\r\n if(postion == \"down\"){\r\n curR = end_r;\r\n curC = str_c;\r\n }\r\n else if(postion == \"right\"){\r\n curR = str_r;\r\n curC = end_c;\r\n }\r\n }\r\n else{\r\n curR = str_r;\r\n curC = str_c;\r\n }\r\n }\r\n\r\n let moveX = last[\"moveXY\"] == null ? curR : last[\"moveXY\"].x;\r\n let moveY = last[\"moveXY\"] == null ? curC : last[\"moveXY\"].y;\r\n\r\n if (postion == \"down\") {\r\n curR += index;\r\n moveX = curR;\r\n }\r\n else if (postion == \"right\") {\r\n curC += index;\r\n moveY = curC;\r\n }\r\n\r\n if (curR >= datarowlen) {\r\n curR = datarowlen - 1;\r\n moveX = curR;\r\n }\r\n\r\n if (curR < 0) {\r\n curR = 0;\r\n moveX = curR;\r\n }\r\n\r\n if (curC >= datacolumnlen) {\r\n curC = datacolumnlen - 1;\r\n moveY = curC;\r\n }\r\n\r\n if (curC < 0) {\r\n curC = 0;\r\n moveY = curC;\r\n }\r\n\r\n //移动的下一个单元格是否是合并的单元格\r\n let margeset2 = menuButton.mergeborer(Store.flowdata, curR, curC);\r\n if(!!margeset2){\r\n row = margeset2.row[1];\r\n row_pre = margeset2.row[0];\r\n row_index = margeset2.row[2];\r\n row_index_ed = margeset2.row[3];\r\n\r\n col = margeset2.column[1];\r\n col_pre = margeset2.column[0];\r\n col_index = margeset2.column[2];\r\n col_index_ed = margeset2.column[3];\r\n }\r\n else{\r\n row = Store.visibledatarow[moveX]; \r\n row_pre = moveX - 1 == -1 ? 0 : Store.visibledatarow[moveX - 1];\r\n row_index = moveX;\r\n row_index_ed = moveX;\r\n\r\n col = Store.visibledatacolumn[moveY];\r\n col_pre = moveY - 1 == -1 ? 0 : Store.visibledatacolumn[moveY - 1];\r\n col_index = moveY;\r\n col_index_ed = moveY;\r\n }\r\n\r\n formula.func_selectedrange = {\r\n \"left\": col_pre,\r\n \"width\": col - col_pre - 1,\r\n \"top\": row_pre,\r\n \"height\": row - row_pre - 1,\r\n \"left_move\": col_pre,\r\n \"width_move\": col - col_pre - 1,\r\n \"top_move\": row_pre,\r\n \"height_move\": row - row_pre - 1,\r\n \"row\": [row_index, row_index_ed],\r\n \"column\": [col_index, col_index_ed],\r\n \"row_focus\": row_index,\r\n \"column_focus\": col_index,\r\n \"moveXY\": {\"x\": moveX, \"y\": moveY}\r\n };\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({\r\n \"left\": col_pre,\r\n \"width\": col - col_pre - 1,\r\n \"top\": row_pre,\r\n \"height\": row - row_pre - 1\r\n }).show();\r\n\r\n formula.rangeSetValue({\r\n \"row\": [row_index, row_index_ed],\r\n \"column\": [col_index, col_index_ed]\r\n });\r\n }\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let sleft = 0, stop = 0;\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n sleft = col - winW + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n sleft = col_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n stop = row - winH + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n stop = row_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n\r\n clearTimeout(Store.countfuncTimeout);\r\n countfunc();\r\n \r\n // 移动单元格通知后台\r\n server.saveParam(\"mv\", Store.currentSheetIndex, Store.luckysheet_select_save);\r\n}\r\n\r\n//ctrl + 方向键 调整单元格\r\nfunction luckysheetMoveHighlightCell2(postion, type, isScroll) {\r\n if(!isScroll){\r\n isScroll = true;\r\n }\r\n\r\n let row, row_pre;\r\n let col, col_pre;\r\n\r\n if(type == \"rangeOfSelect\"){\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rf = last[\"row_focus\"], cf = last[\"column_focus\"];\r\n\r\n let focusIsMerge = false, mc = {};\r\n if(Store.config[\"merge\"] != null && (rf + \"_\" + cf) in Store.config[\"merge\"]){\r\n focusIsMerge = true;\r\n mc = Store.config[\"merge\"][rf + \"_\" + cf];\r\n }\r\n\r\n if(postion == \"down\"){\r\n if(rf == Store.flowdata.length - 1){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n rf = getNextIndex(\"down\", cf, mc.r + mc.rs - 1, Store.flowdata.length - 1);\r\n }\r\n else{\r\n rf = getNextIndex(\"down\", cf, rf, Store.flowdata.length - 1);\r\n }\r\n }\r\n else if(postion == \"up\"){\r\n if(rf == 0){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n rf = getNextIndex(\"up\", cf, 0, mc.r);\r\n }\r\n else{\r\n rf = getNextIndex(\"up\", cf, 0, rf);\r\n }\r\n }\r\n else if(postion == \"right\"){\r\n if(cf == Store.flowdata[0].length - 1){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n cf = getNextIndex(\"right\", rf, mc.c + mc.cs - 1, Store.flowdata[0].length - 1);\r\n }\r\n else{\r\n cf = getNextIndex(\"right\", rf, cf, Store.flowdata[0].length - 1);\r\n }\r\n }\r\n else if(postion == \"left\"){\r\n if(cf == 0){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n cf = getNextIndex(\"left\", rf, 0, mc.c);\r\n }\r\n else{\r\n cf = getNextIndex(\"left\", rf, 0, cf);\r\n }\r\n }\r\n\r\n let rowseleted = [rf, rf];\r\n let columnseleted = [cf, cf];\r\n\r\n row = Store.visibledatarow[rf];\r\n row_pre = rf - 1 == -1 ? 0 : Store.visibledatarow[rf - 1];\r\n col = Store.visibledatacolumn[cf];\r\n col_pre = cf - 1 == -1 ? 0 : Store.visibledatacolumn[cf - 1];\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, row_pre, row - row_pre - 1, col_pre, col - col_pre - 1);\r\n if(changeparam != null){\r\n columnseleted = changeparam[0];\r\n rowseleted= changeparam[1];\r\n // top = changeparam[2];\r\n // height = changeparam[3];\r\n // left = changeparam[4];\r\n // width = changeparam[5];\r\n }\r\n\r\n Store.luckysheet_select_save = [{\"row\": rowseleted, \"column\": columnseleted}];\r\n selectHightlightShow();\r\n pivotTable.pivotclick(rf, cf);\r\n formula.fucntionboxshow(rf, cf);\r\n }\r\n else if(type == \"rangeOfFormula\"){\r\n let last = formula.func_selectedrange;\r\n let rf = last[\"row_focus\"], cf = last[\"column_focus\"];\r\n\r\n let focusIsMerge = false, mc = {};\r\n if(Store.config[\"merge\"] != null && (rf + \"_\" + cf) in Store.config[\"merge\"]){\r\n focusIsMerge = true;\r\n mc = Store.config[\"merge\"][rf + \"_\" + cf];\r\n }\r\n\r\n if(postion == \"down\"){\r\n if(rf == Store.flowdata.length - 1){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n rf = getNextIndex(\"down\", cf, mc.r + mc.rs - 1, Store.flowdata.length - 1);\r\n }\r\n else{\r\n rf = getNextIndex(\"down\", cf, rf, Store.flowdata.length - 1);\r\n }\r\n }\r\n else if(postion == \"up\"){\r\n if(rf == 0){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n rf = getNextIndex(\"up\", cf, 0, mc.r);\r\n }\r\n else{\r\n rf = getNextIndex(\"up\", cf, 0, rf);\r\n }\r\n }\r\n else if(postion == \"right\"){\r\n if(cf == Store.flowdata[0].length - 1){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n cf = getNextIndex(\"right\", rf, mc.c + mc.cs - 1, Store.flowdata[0].length - 1);\r\n }\r\n else{\r\n cf = getNextIndex(\"right\", rf, cf, Store.flowdata[0].length - 1);\r\n }\r\n }\r\n else if(postion == \"left\"){\r\n if(cf == 0){\r\n return;\r\n }\r\n\r\n if(focusIsMerge){\r\n cf = getNextIndex(\"left\", rf, 0, mc.c);\r\n }\r\n else{\r\n cf = getNextIndex(\"left\", rf, 0, cf);\r\n }\r\n }\r\n\r\n let rowseleted = [rf, rf];\r\n let columnseleted = [cf, cf];\r\n\r\n row = Store.visibledatarow[rf];\r\n row_pre = rf - 1 == -1 ? 0 : Store.visibledatarow[rf - 1];\r\n col = Store.visibledatacolumn[cf]; \r\n col_pre = cf - 1 == -1 ? 0 : Store.visibledatacolumn[cf - 1];\r\n\r\n let top = row_pre, height = row - row_pre - 1;\r\n let left = col_pre, width = col - col_pre - 1;\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, top, height, left, width);\r\n if(changeparam != null){\r\n columnseleted = changeparam[0];\r\n rowseleted= changeparam[1];\r\n top = changeparam[2];\r\n height = changeparam[3];\r\n left = changeparam[4];\r\n width = changeparam[5];\r\n }\r\n\r\n formula.func_selectedrange = {\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": top,\r\n \"height\": height,\r\n \"left_move\": left,\r\n \"width_move\": width,\r\n \"top_move\": top,\r\n \"height_move\": height,\r\n \"row\": rowseleted,\r\n \"column\": columnseleted,\r\n \"row_focus\": rf,\r\n \"column_focus\": cf\r\n };\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": top,\r\n \"height\": height\r\n }).show();\r\n\r\n formula.rangeSetValue({\r\n \"row\": rowseleted,\r\n \"column\": columnseleted\r\n });\r\n }\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let sleft = 0, stop = 0;\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n sleft = col - winW + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n sleft = col_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n stop = row - winH + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n stop = row_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n\r\n clearTimeout(Store.countfuncTimeout);\r\n countfunc();\r\n}\r\n\r\n//shift + 方向键 调整选区\r\nfunction luckysheetMoveHighlightRange(postion, index, type, isScroll) {\r\n if (isScroll == null) {\r\n isScroll = true;\r\n }\r\n\r\n if (!postion) {\r\n postion == \"down\";\r\n }\r\n\r\n let row, row_pre;\r\n let col, col_pre;\r\n\r\n if(type == \"rangeOfSelect\"){\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n\r\n let curR = last[\"row\"][0], endR = last[\"row\"][1];\r\n let curC = last[\"column\"][0], endC = last[\"column\"][1];\r\n let rf = last[\"row_focus\"], cf = last[\"column_focus\"];\r\n\r\n let datarowlen = Store.flowdata.length, \r\n datacolumnlen = Store.flowdata[0].length;\r\n\r\n if(postion == \"down\"){ //选区上下变动\r\n if(rowHasMerge(rf, curC, endC)){ //focus单元格所在行有合并单元格\r\n let rfMerge = getRowMerge(rf, curC, endC);\r\n let rf_str = rfMerge[0], rf_end = rfMerge[1];\r\n\r\n if(rf_str > curR && rf_end == endR){\r\n if(index > 0 && rowHasMerge(curR, curC, endC)){\r\n curR = getRowMerge(curR, curC, endC)[1];\r\n }\r\n\r\n curR += index;\r\n }\r\n else if(rf_end < endR && rf_str == curR){\r\n if(index < 0 && rowHasMerge(endR, curC, endC)){\r\n endR = getRowMerge(endR, curC, endC)[0];\r\n }\r\n\r\n endR += index;\r\n }\r\n else{\r\n if(index > 0){\r\n endR += index;\r\n }\r\n else{\r\n curR += index;\r\n }\r\n }\r\n }\r\n else{\r\n if(rf > curR && rf == endR){\r\n if(index > 0 && rowHasMerge(curR, curC, endC)){\r\n curR = getRowMerge(curR, curC, endC)[1];\r\n }\r\n\r\n curR += index;\r\n }\r\n else if(rf < endR && rf == curR){\r\n if(index < 0 && rowHasMerge(endR, curC, endC)){\r\n endR = getRowMerge(endR, curC, endC)[0];\r\n }\r\n\r\n endR += index;\r\n }\r\n else if(rf == curR && rf == endR){\r\n if(index > 0){\r\n endR += index;\r\n }\r\n else{\r\n curR += index;\r\n }\r\n }\r\n }\r\n\r\n if (endR >= datarowlen) {\r\n endR = datarowlen - 1;\r\n }\r\n\r\n if (endR < 0) {\r\n endR = 0;\r\n }\r\n\r\n if (curR >= datarowlen) {\r\n curR = datarowlen - 1;\r\n }\r\n\r\n if (curR < 0) {\r\n curR = 0;\r\n }\r\n }\r\n else{\r\n if(colHasMerge(cf, curR, endR)){ //focus单元格所在列有合并单元格\r\n let cfMerge = getColMerge(cf, curR, endR);\r\n let cf_str = cfMerge[0], cf_end = cfMerge[1];\r\n\r\n if(cf_str > curC && cf_end == endC){\r\n if(index > 0 && colHasMerge(curC, curR, endR)){\r\n curC = getColMerge(curC, curR, endR)[1];\r\n }\r\n\r\n curC += index;\r\n }\r\n else if(cf_end < endC && cf_str == curC){\r\n if(index < 0 && colHasMerge(endC, curR, endR)){\r\n endC = getColMerge(endC, curR, endR)[0];\r\n }\r\n\r\n endC += index;\r\n }\r\n else{\r\n if(index > 0){\r\n endC += index;\r\n }\r\n else{\r\n curC += index;\r\n }\r\n }\r\n }\r\n else{\r\n if(cf > curC && cf == endC){\r\n if(index > 0 && colHasMerge(curC, curR, endR)){\r\n curC = getColMerge(curC, curR, endR)[1];\r\n }\r\n\r\n curC += index;\r\n }\r\n else if(cf < endC && cf == curC){\r\n if(index < 0 && colHasMerge(endC, curR, endR)){\r\n endC = getColMerge(endC, curR, endR)[0];\r\n }\r\n\r\n endC += index;\r\n }\r\n else if(cf == curC && cf == endC){\r\n if(index > 0){\r\n endC += index;\r\n }\r\n else{\r\n curC += index;\r\n }\r\n }\r\n } \r\n\r\n if (endC >= datacolumnlen) {\r\n endC = datacolumnlen - 1;\r\n }\r\n\r\n if (endC < 0) {\r\n endC = 0;\r\n }\r\n\r\n if (curC >= datacolumnlen) {\r\n curC = datacolumnlen - 1;\r\n }\r\n\r\n if (curC < 0) {\r\n curC = 0;\r\n }\r\n }\r\n\r\n let rowseleted = [curR, endR];\r\n let columnseleted = [curC, endC];\r\n\r\n row = Store.visibledatarow[endR]; \r\n row_pre = curR - 1 == -1 ? 0 : Store.visibledatarow[curR - 1];\r\n col = Store.visibledatacolumn[endC]; \r\n col_pre = curC - 1 == -1 ? 0 : Store.visibledatacolumn[curC - 1];\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, row_pre, row - row_pre - 1, col_pre, col - col_pre - 1);\r\n if(changeparam != null){\r\n columnseleted = changeparam[0];\r\n rowseleted= changeparam[1];\r\n // top = changeparam[2];\r\n // height = changeparam[3];\r\n // left = changeparam[4];\r\n // width = changeparam[5];\r\n }\r\n\r\n last[\"row\"] = rowseleted;\r\n last[\"column\"] = columnseleted;\r\n\r\n selectHightlightShow();\r\n }\r\n else if(type == \"rangeOfFormula\"){\r\n let last = formula.func_selectedrange;\r\n\r\n let curR = last[\"row\"][0], endR = last[\"row\"][1];\r\n let curC = last[\"column\"][0], endC = last[\"column\"][1];\r\n let rf = last[\"row_focus\"], cf = last[\"column_focus\"];\r\n\r\n let datarowlen = Store.flowdata.length, \r\n datacolumnlen = Store.flowdata[0].length;\r\n\r\n if(postion == \"down\"){ //选区上下变动\r\n if(rowHasMerge(rf, curC, endC)){ //focus单元格所在行有合并单元格\r\n let rfMerge = getRowMerge(rf, curC, endC);\r\n let rf_str = rfMerge[0], rf_end = rfMerge[1];\r\n\r\n if(rf_str > curR && rf_end == endR){\r\n if(index > 0 && rowHasMerge(curR, curC, endC)){\r\n curR = getRowMerge(curR, curC, endC)[1];\r\n }\r\n\r\n curR += index;\r\n }\r\n else if(rf_end < endR && rf_str == curR){\r\n if(index < 0 && rowHasMerge(endR, curC, endC)){\r\n endR = getRowMerge(endR, curC, endC)[0];\r\n }\r\n\r\n endR += index;\r\n }\r\n else{\r\n if(index > 0){\r\n endR += index;\r\n }\r\n else{\r\n curR += index;\r\n }\r\n }\r\n }\r\n else{\r\n if(rf > curR && rf == endR){\r\n if(index > 0 && rowHasMerge(curR, curC, endC)){\r\n curR = getRowMerge(curR, curC, endC)[1];\r\n }\r\n\r\n curR += index;\r\n }\r\n else if(rf < endR && rf == curR){\r\n if(index < 0 && rowHasMerge(endR, curC, endC)){\r\n endR = getRowMerge(endR, curC, endC)[0];\r\n }\r\n\r\n endR += index;\r\n }\r\n else if(rf == curR && rf == endR){\r\n if(index > 0){\r\n endR += index;\r\n }\r\n else{\r\n curR += index;\r\n }\r\n }\r\n }\r\n\r\n if (endR >= datarowlen) {\r\n endR = datarowlen - 1;\r\n }\r\n\r\n if (endR < 0) {\r\n endR = 0;\r\n }\r\n\r\n if (curR >= datarowlen) {\r\n curR = datarowlen - 1;\r\n }\r\n\r\n if (curR < 0) {\r\n curR = 0;\r\n }\r\n }\r\n else{\r\n if(colHasMerge(cf, curR, endR)){ //focus单元格所在列有合并单元格\r\n let cfMerge = getColMerge(cf, curR, endR);\r\n let cf_str = cfMerge[0], cf_end = cfMerge[1];\r\n\r\n if(cf_str > curC && cf_end == endC){\r\n if(index > 0 && colHasMerge(curC, curR, endR)){\r\n curC = getColMerge(curC, curR, endR)[1];\r\n }\r\n\r\n curC += index;\r\n }\r\n else if(cf_end < endC && cf_str == curC){\r\n if(index < 0 && colHasMerge(endC, curR, endR)){\r\n endC = getColMerge(endC, curR, endR)[0];\r\n }\r\n\r\n endC += index;\r\n }\r\n else{\r\n if(index > 0){\r\n endC += index;\r\n }\r\n else{\r\n curC += index;\r\n }\r\n }\r\n }\r\n else{\r\n if(cf > curC && cf == endC){\r\n if(index > 0 && colHasMerge(curC, curR, endR)){\r\n curC = getColMerge(curC, curR, endR)[1];\r\n }\r\n\r\n curC += index;\r\n }\r\n else if(cf < endC && cf == curC){\r\n if(index < 0 && colHasMerge(endC, curR, endR)){\r\n endC = getColMerge(endC, curR, endR)[0];\r\n }\r\n\r\n endC += index;\r\n }\r\n else if(cf == curC && cf == endC){\r\n if(index > 0){\r\n endC += index;\r\n }\r\n else{\r\n curC += index;\r\n }\r\n }\r\n } \r\n\r\n if (endC >= datacolumnlen) {\r\n endC = datacolumnlen - 1;\r\n }\r\n\r\n if (endC < 0) {\r\n endC = 0;\r\n }\r\n\r\n if (curC >= datacolumnlen) {\r\n curC = datacolumnlen - 1;\r\n }\r\n\r\n if (curC < 0) {\r\n curC = 0;\r\n }\r\n }\r\n\r\n let rowseleted = [curR, endR];\r\n let columnseleted = [curC, endC];\r\n\r\n row = Store.visibledatarow[endR]; \r\n row_pre = curR - 1 == -1 ? 0 : Store.visibledatarow[curR - 1];\r\n col = Store.visibledatacolumn[endC]; \r\n col_pre = curC - 1 == -1 ? 0 : Store.visibledatacolumn[curC - 1];\r\n\r\n let top = row_pre, height = row - row_pre - 1;\r\n let left = col_pre, width = col - col_pre - 1;\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, top, height, left, width);\r\n if(changeparam != null){\r\n columnseleted = changeparam[0];\r\n rowseleted= changeparam[1];\r\n top = changeparam[2];\r\n height = changeparam[3];\r\n left = changeparam[4];\r\n width = changeparam[5];\r\n }\r\n\r\n formula.func_selectedrange = {\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": top,\r\n \"height\": height,\r\n \"left_move\": left,\r\n \"width_move\": width,\r\n \"top_move\": top,\r\n \"height_move\": height,\r\n \"row\": rowseleted,\r\n \"column\": columnseleted,\r\n \"row_focus\": rf,\r\n \"column_focus\": cf\r\n };\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": top,\r\n \"height\": height\r\n }).show();\r\n\r\n formula.rangeSetValue({\r\n \"row\": rowseleted,\r\n \"column\": columnseleted\r\n });\r\n }\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let sleft = 0, stop = 0;\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n sleft = col - winW + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n sleft = col_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n stop = row - winH + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n stop = row_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n\r\n clearTimeout(Store.countfuncTimeout);\r\n countfunc();\r\n}\r\n\r\n//ctrl + shift + 方向键 调整选区\r\nfunction luckysheetMoveHighlightRange2(postion, type, isScroll) {\r\n if(!isScroll){\r\n isScroll = true;\r\n }\r\n\r\n let row, row_pre;\r\n let col, col_pre;\r\n\r\n if(type == \"rangeOfSelect\"){\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rf = last[\"row_focus\"], cf = last[\"column_focus\"];\r\n\r\n let r1 = last[\"row\"][0], r2 = last[\"row\"][1];\r\n let c1 = last[\"column\"][0], c2 = last[\"column\"][1];\r\n\r\n if(postion == \"down\"){\r\n if(r2 == Store.flowdata.length - 1){\r\n return;\r\n }\r\n\r\n if(rowHasMerge(rf, c1, c2)){ //focus所在行有合并单元格\r\n let rfMerge = getRowMerge(rf, c1, c2);\r\n let rf_str = rfMerge[0], rf_end = rfMerge[1];\r\n\r\n if(rf_str > r1 && rf_end == r2){\r\n r1 = getNextIndex(\"down\", cf, r1, r2);\r\n }\r\n else{\r\n r2 = getNextIndex(\"down\", cf, r2, Store.flowdata.length - 1);\r\n }\r\n }\r\n else{\r\n if(rf > r1 && rf == r2){\r\n r1 = getNextIndex(\"down\", cf, r1, r2);\r\n }\r\n else{\r\n r2 = getNextIndex(\"down\", cf, r2, Store.flowdata.length - 1);\r\n }\r\n }\r\n }\r\n else if(postion == \"up\"){\r\n if(r1 == 0){\r\n return;\r\n }\r\n\r\n if(rowHasMerge(rf, c1, c2)){ //focus所在行有合并单元格\r\n let rfMerge = getRowMerge(rf, c1, c2);\r\n let rf_str = rfMerge[0], rf_end = rfMerge[1];\r\n\r\n if(rf_end < r2 && rf_str == r1){\r\n r2 = getNextIndex(\"up\", cf, r1, r2);\r\n }\r\n else{\r\n r1 = getNextIndex(\"up\", cf, 0, r1);\r\n }\r\n }\r\n else{\r\n if(rf < r2 && rf == r1){\r\n r2 = getNextIndex(\"up\", cf, r1, r2);\r\n }\r\n else{\r\n r1 = getNextIndex(\"up\", cf, 0, r1);\r\n }\r\n }\r\n }\r\n else if(postion == \"right\"){\r\n if(c2 == Store.flowdata[0].length - 1){\r\n return;\r\n }\r\n\r\n if(colHasMerge(cf, r1, r2)){ //focus所在行有合并单元格\r\n let cfMerge = getColMerge(cf, r1, r2);\r\n let cf_str = cfMerge[0], cf_end = cfMerge[1];\r\n\r\n if(cf_str > c1 && cf_end == c2){\r\n c1 = getNextIndex(\"right\", rf, c1, c2);\r\n }\r\n else{\r\n c2 = getNextIndex(\"right\", rf, c2, Store.flowdata[0].length - 1);\r\n }\r\n }\r\n else{\r\n if(cf > c1 && cf == c2){\r\n c1 = getNextIndex(\"right\", rf, c1, c2);\r\n }\r\n else{\r\n c2 = getNextIndex(\"right\", rf, c2, Store.flowdata[0].length - 1);\r\n }\r\n }\r\n }\r\n else if(postion == \"left\"){\r\n if(c1 == 0){\r\n return;\r\n }\r\n\r\n if(colHasMerge(cf, r1, r2)){ //focus所在行有合并单元格\r\n let cfMerge = getColMerge(cf, r1, r2);\r\n let cf_str = cfMerge[0], cf_end = cfMerge[1];\r\n\r\n if(cf_end < c2 && cf_str == c1){\r\n c2 = getNextIndex(\"left\", rf, c1, c2);\r\n }\r\n else{\r\n c1 = getNextIndex(\"left\", rf, 0, c1);\r\n }\r\n }\r\n else{\r\n if(cf < c2 && cf == c1){\r\n c2 = getNextIndex(\"left\", rf, c1, c2);\r\n }\r\n else{\r\n c1 = getNextIndex(\"left\", rf, 0, c1);\r\n }\r\n }\r\n }\r\n\r\n let rowseleted = [r1, r2];\r\n let columnseleted = [c1, c2];\r\n\r\n row = Store.visibledatarow[r2]; \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n col = Store.visibledatacolumn[c2]; \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, row_pre, row - row_pre - 1, col_pre, col - col_pre - 1);\r\n if(changeparam != null){\r\n columnseleted = changeparam[0];\r\n rowseleted= changeparam[1];\r\n // top = changeparam[2];\r\n // height = changeparam[3];\r\n // left = changeparam[4];\r\n // width = changeparam[5];\r\n }\r\n\r\n last[\"row\"] = rowseleted;\r\n last[\"column\"] = columnseleted;\r\n\r\n selectHightlightShow();\r\n }\r\n else if(type == \"rangeOfFormula\"){\r\n let last = formula.func_selectedrange;\r\n let rf = last[\"row_focus\"], cf = last[\"column_focus\"];\r\n\r\n let r1 = last[\"row\"][0], r2 = last[\"row\"][1];\r\n let c1 = last[\"column\"][0], c2 = last[\"column\"][1];\r\n\r\n if(postion == \"down\"){\r\n if(r2 == Store.flowdata.length - 1){\r\n return;\r\n }\r\n\r\n if(rowHasMerge(rf, c1, c2)){ //focus所在行有合并单元格\r\n let rfMerge = getRowMerge(rf, c1, c2);\r\n let rf_str = rfMerge[0], rf_end = rfMerge[1];\r\n\r\n if(rf_str > r1 && rf_end == r2){\r\n r1 = getNextIndex(\"down\", cf, r1, r2);\r\n }\r\n else{\r\n r2 = getNextIndex(\"down\", cf, r2, Store.flowdata.length - 1);\r\n }\r\n }\r\n else{\r\n if(rf > r1 && rf == r2){\r\n r1 = getNextIndex(\"down\", cf, r1, r2);\r\n }\r\n else{\r\n r2 = getNextIndex(\"down\", cf, r2, Store.flowdata.length - 1);\r\n }\r\n }\r\n }\r\n else if(postion == \"up\"){\r\n if(r1 == 0){\r\n return;\r\n }\r\n\r\n if(rowHasMerge(rf, c1, c2)){ //focus所在行有合并单元格\r\n let rfMerge = getRowMerge(rf, c1, c2);\r\n let rf_str = rfMerge[0], rf_end = rfMerge[1];\r\n\r\n if(rf_end < r2 && rf_str == r1){\r\n r2 = getNextIndex(\"up\", cf, r1, r2);\r\n }\r\n else{\r\n r1 = getNextIndex(\"up\", cf, 0, r1);\r\n }\r\n }\r\n else{\r\n if(rf < r2 && rf == r1){\r\n r2 = getNextIndex(\"up\", cf, r1, r2);\r\n }\r\n else{\r\n r1 = getNextIndex(\"up\", cf, 0, r1);\r\n }\r\n }\r\n }\r\n else if(postion == \"right\"){\r\n if(c2 == Store.flowdata[0].length - 1){\r\n return;\r\n }\r\n\r\n if(colHasMerge(cf, r1, r2)){ //focus所在行有合并单元格\r\n let cfMerge = getColMerge(cf, r1, r2);\r\n let cf_str = cfMerge[0], cf_end = cfMerge[1];\r\n\r\n if(cf_str > c1 && cf_end == c2){\r\n c1 = getNextIndex(\"right\", rf, c1, c2);\r\n }\r\n else{\r\n c2 = getNextIndex(\"right\", rf, c2, Store.flowdata[0].length - 1);\r\n }\r\n }\r\n else{\r\n if(cf > c1 && cf == c2){\r\n c1 = getNextIndex(\"right\", rf, c1, c2);\r\n }\r\n else{\r\n c2 = getNextIndex(\"right\", rf, c2, Store.flowdata[0].length - 1);\r\n }\r\n }\r\n }\r\n else if(postion == \"left\"){\r\n if(c1 == 0){\r\n return;\r\n }\r\n\r\n if(colHasMerge(cf, r1, r2)){ //focus所在行有合并单元格\r\n let cfMerge = getColMerge(cf, r1, r2);\r\n let cf_str = cfMerge[0], cf_end = cfMerge[1];\r\n\r\n if(cf_end < c2 && cf_str == c1){\r\n c2 = getNextIndex(\"left\", rf, c1, c2);\r\n }\r\n else{\r\n c1 = getNextIndex(\"left\", rf, 0, c1);\r\n }\r\n }\r\n else{\r\n if(cf < c2 && cf == c1){\r\n c2 = getNextIndex(\"left\", rf, c1, c2);\r\n }\r\n else{\r\n c1 = getNextIndex(\"left\", rf, 0, c1);\r\n }\r\n }\r\n }\r\n\r\n let rowseleted = [r1, r2];\r\n let columnseleted = [c1, c2];\r\n\r\n row = Store.visibledatarow[r2]; \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n col = Store.visibledatacolumn[c2]; \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n let top = row_pre, height = row - row_pre - 1;\r\n let left = col_pre, width = col - col_pre - 1;\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, last, top, height, left, width);\r\n if(changeparam != null){\r\n columnseleted = changeparam[0];\r\n rowseleted= changeparam[1];\r\n top = changeparam[2];\r\n height = changeparam[3];\r\n left = changeparam[4];\r\n width = changeparam[5];\r\n }\r\n\r\n formula.func_selectedrange = {\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": top,\r\n \"height\": height,\r\n \"left_move\": left,\r\n \"width_move\": width,\r\n \"top_move\": top,\r\n \"height_move\": height,\r\n \"row\": rowseleted,\r\n \"column\": columnseleted,\r\n \"row_focus\": rf,\r\n \"column_focus\": cf\r\n };\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": top,\r\n \"height\": height\r\n }).show();\r\n\r\n formula.rangeSetValue({\r\n \"row\": rowseleted,\r\n \"column\": columnseleted\r\n });\r\n }\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let sleft = 0, stop = 0;\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n sleft = col - winW + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n sleft = col_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(sleft);\r\n }\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n stop = row - winH + 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n stop = row_pre - 20;\r\n if (isScroll) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(stop);\r\n }\r\n }\r\n\r\n clearTimeout(Store.countfuncTimeout);\r\n countfunc();\r\n}\r\n\r\n//shift + 方向键 / ctrl + shift + 方向键 功能\r\nfunction rowHasMerge(r, c1, c2){\r\n let rowHasMerge = false;\r\n\r\n for(let c = c1; c <= c2; c++){\r\n let cell = Store.flowdata[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n rowHasMerge = true;\r\n break;\r\n }\r\n }\r\n\r\n return rowHasMerge;\r\n}\r\nfunction colHasMerge(c, r1, r2){\r\n let colHasMerge = false;\r\n\r\n for(let r = r1; r <= r2; r++){\r\n let cell = Store.flowdata[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n colHasMerge = true;\r\n break;\r\n }\r\n }\r\n\r\n return colHasMerge;\r\n}\r\nfunction getRowMerge(rIndex, c1, c2){\r\n let r1 = 0, r2 = Store.flowdata.length - 1;\r\n\r\n let str = null;\r\n if(rIndex > r1){\r\n for(let r = rIndex; r >= r1; r--){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = Store.flowdata[r][c];\r\n \r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n let mc = Store.config[\"merge\"][cell[\"mc\"].r + \"_\" + cell[\"mc\"].c];\r\n\r\n if(str == null || mc.r < str){\r\n str = mc.r;\r\n }\r\n } \r\n }\r\n\r\n if(rowHasMerge(str - 1, c1, c2) && str > r1){\r\n r = str - 1;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n }\r\n else{\r\n str = r1;\r\n }\r\n\r\n let end = null;\r\n if(rIndex < r2){\r\n for(let r = rIndex; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = Store.flowdata[r][c];\r\n \r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n let mc = Store.config[\"merge\"][cell[\"mc\"].r + \"_\" + cell[\"mc\"].c];\r\n\r\n if(end == null || (mc.r + mc.rs - 1) > end){\r\n end = mc.r + mc.rs - 1;\r\n }\r\n }\r\n }\r\n\r\n if(rowHasMerge(end + 1, c1, c2) && end < r2){\r\n r = end + 1;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n }\r\n else{\r\n end = r2;\r\n }\r\n\r\n return [str, end];\r\n}\r\nfunction getColMerge(cIndex, r1, r2){\r\n let c1 = 0, c2 = Store.flowdata[0].length - 1;\r\n\r\n let str = null;\r\n if(cIndex > c1){\r\n for(let c = cIndex; c >= c1; c--){\r\n for(let r = r1; r <= r2; r++){\r\n let cell = Store.flowdata[r][c];\r\n \r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n let mc = Store.config[\"merge\"][cell[\"mc\"].r + \"_\" + cell[\"mc\"].c];\r\n\r\n if(str == null || mc.c < str){\r\n str = mc.c;\r\n }\r\n } \r\n }\r\n\r\n if(colHasMerge(str - 1, r1, r2) && str > c1){\r\n c = str - 1;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n }\r\n else{\r\n str = c1;\r\n }\r\n\r\n let end = null;\r\n if(cIndex < c2){\r\n for(let c = cIndex; c <= c2; c++){\r\n for(let r = r1; r <= r2; r++){\r\n let cell = Store.flowdata[r][c];\r\n \r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n let mc = Store.config[\"merge\"][cell[\"mc\"].r + \"_\" + cell[\"mc\"].c];\r\n\r\n if(end == null || (mc.c + mc.cs - 1) > end){\r\n end = mc.c + mc.cs - 1;\r\n }\r\n }\r\n }\r\n\r\n if(colHasMerge(end + 1, r1, r2) && end < c2){\r\n c = end + 1;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n }\r\n else{\r\n end = c2;\r\n }\r\n\r\n return [str, end];\r\n}\r\nfunction getNextIndex(direction, focusIndex, strIndex, endIndex) {\r\n let index = null;\r\n\r\n let stNull;\r\n if(direction == \"down\"){\r\n let stValue = Store.flowdata[strIndex][focusIndex];\r\n\r\n if(getObjType(stValue) == \"object\" && isRealNull(stValue.v)){\r\n stNull = true;\r\n }\r\n else if(isRealNull(stValue)){\r\n stNull = true;\r\n }\r\n else{\r\n stNull = false;\r\n }\r\n\r\n console.log(stNull, \"stNull\");\r\n\r\n let cellNull = [], i = 0;\r\n for(let r = strIndex + 1; r <= endIndex; r++){\r\n let cell = Store.flowdata[r][focusIndex];\r\n\r\n if(getObjType(cell) == \"object\" && isRealNull(cell.v)){\r\n cellNull.push(true);\r\n }\r\n else if(isRealNull(cell)){\r\n cellNull.push(true);\r\n }\r\n else{\r\n cellNull.push(false);\r\n }\r\n\r\n if(cellNull.length == 1 && stNull==true && cellNull[i] == false){\r\n index = strIndex + i + 1;\r\n break;\r\n }\r\n else if(cellNull.length > 1){\r\n if(stNull && cellNull[i] == false){ //起始是空,找第一个有值的位置\r\n index = strIndex + i + 1;\r\n break;\r\n }\r\n else if(!stNull){ //起始有值,找一个有值的位置\r\n if(cellNull[i] == false && cellNull[i - 1] == true){ //前面为空\r\n index = strIndex + i + 1;\r\n break;\r\n }\r\n else if(cellNull[i] == true && cellNull[i - 1] == false){ //后面为空\r\n index = strIndex + i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(r == endIndex){\r\n index = endIndex;\r\n }\r\n\r\n i++;\r\n }\r\n }\r\n else if(direction == \"up\"){\r\n let stValue = Store.flowdata[endIndex][focusIndex];\r\n\r\n if(getObjType(stValue) == \"object\" && isRealNull(stValue.v)){\r\n stNull = true;\r\n }\r\n else if(isRealNull(stValue)){\r\n stNull = true;\r\n }\r\n else{\r\n stNull = false;\r\n }\r\n\r\n let cellNull = [], i = 0;\r\n for(let r = endIndex - 1; r >= strIndex; r--){\r\n let cell = Store.flowdata[r][focusIndex];\r\n\r\n if(getObjType(cell) == \"object\" && isRealNull(cell.v)){\r\n cellNull.push(true);\r\n }\r\n else if(isRealNull(cell)){\r\n cellNull.push(true);\r\n }\r\n else{\r\n cellNull.push(false);\r\n }\r\n\r\n if(cellNull.length == 1 && stNull && cellNull[i] == false){\r\n index = endIndex - (i + 1);\r\n break;\r\n }\r\n else if(cellNull.length > 1){\r\n if(stNull && cellNull[i] == false){ //起始是空,找第一个有值的位置\r\n index = endIndex - (i + 1);\r\n break;\r\n }\r\n else if(!stNull){ //起始有值,找一个有值的位置\r\n if(cellNull[i] == false && cellNull[i - 1] == true){ //前面为空\r\n index = endIndex - (i + 1);\r\n break;\r\n }\r\n else if(cellNull[i] == true && cellNull[i - 1] == false){ //后面为空\r\n index = endIndex - i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(r == strIndex){\r\n index = strIndex;\r\n }\r\n\r\n i++;\r\n }\r\n }\r\n else if(direction == \"right\"){\r\n let stValue = Store.flowdata[focusIndex][strIndex];\r\n\r\n if(getObjType(stValue) == \"object\" && isRealNull(stValue.v)){\r\n stNull = true;\r\n }\r\n else if(isRealNull(stValue)){\r\n stNull = true;\r\n }\r\n else{\r\n stNull = false;\r\n }\r\n\r\n let cellNull = [], i = 0;\r\n for(let c = strIndex + 1; c <= endIndex; c++){\r\n let cell = Store.flowdata[focusIndex][c];\r\n\r\n if(getObjType(cell) == \"object\" && isRealNull(cell.v)){\r\n cellNull.push(true);\r\n }\r\n else if(isRealNull(cell)){\r\n cellNull.push(true);\r\n }\r\n else{\r\n cellNull.push(false);\r\n }\r\n\r\n if(cellNull.length == 1 && stNull && cellNull[i] == false){\r\n index = strIndex + i + 1;\r\n break;\r\n }\r\n else if(cellNull.length > 1){\r\n if(stNull && cellNull[i] == false){ //起始是空,找第一个有值的位置\r\n index = strIndex + i + 1;\r\n break;\r\n }\r\n else if(!stNull){ //起始有值,找一个有值的位置\r\n if(cellNull[i] == false && cellNull[i - 1] == true){ //前面为空\r\n index = strIndex + i + 1;\r\n break;\r\n }\r\n else if(cellNull[i] == true && cellNull[i - 1] == false){ //后面为空\r\n index = strIndex + i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(c == endIndex){\r\n index = endIndex;\r\n }\r\n\r\n i++;\r\n }\r\n }\r\n else if(direction == \"left\"){\r\n let stValue = Store.flowdata[focusIndex][endIndex];\r\n\r\n if(getObjType(stValue) == \"object\" && isRealNull(stValue.v)){\r\n stNull = true;\r\n }\r\n else if(isRealNull(stValue)){\r\n stNull = true;\r\n }\r\n else{\r\n stNull = false;\r\n }\r\n\r\n let cellNull = [], i = 0;\r\n for(let c = endIndex - 1; c >= strIndex; c--){\r\n let cell = Store.flowdata[focusIndex][c];\r\n\r\n if(getObjType(cell) == \"object\" && isRealNull(cell.v)){\r\n cellNull.push(true);\r\n }\r\n else if(isRealNull(cell)){\r\n cellNull.push(true);\r\n }\r\n else{\r\n cellNull.push(false);\r\n }\r\n\r\n if(cellNull.length == 1 && stNull && cellNull[i] == false){\r\n index = endIndex - (i + 1);\r\n break;\r\n }\r\n else if(cellNull.length > 1){\r\n if(stNull && cellNull[i] == false){ //起始是空,找第一个有值的位置\r\n index = endIndex - (i + 1);\r\n break;\r\n }\r\n else if(!stNull){ //起始有值,找一个有值的位置\r\n if(cellNull[i] == false && cellNull[i - 1] == true){ //前面为空\r\n index = endIndex - (i + 1);\r\n break;\r\n }\r\n else if(cellNull[i] == true && cellNull[i - 1] == false){ //后面为空\r\n index = endIndex - i;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(c == strIndex){\r\n index = strIndex;\r\n }\r\n\r\n i++;\r\n }\r\n }\r\n\r\n return index;\r\n}\r\n\r\nexport {\r\n luckysheetMoveEndCell,\r\n luckysheetMoveHighlightCell,\r\n luckysheetMoveHighlightCell2,\r\n luckysheetMoveHighlightRange,\r\n luckysheetMoveHighlightRange2,\r\n}","\r\nimport { getSheetIndex, getRangetxt } from '../methods/get';\r\nimport { replaceHtml } from '../utils/util';\r\nimport formula from '../global/formula';\r\nimport { isEditMode } from '../global/validate';\r\nimport tooltip from '../global/tooltip';\r\nimport { luckysheetrefreshgrid } from '../global/refresh';\r\nimport { luckysheetAlternateformatHtml, modelHTML } from './constant';\r\nimport luckysheetsizeauto from './resize';\r\nimport server from './server';\r\nimport { selectHightlightShow } from './select';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\n//交替颜色\r\nconst alternateformat = {\r\n rangefocus: false,\r\n modelfocusIndex: null,\r\n FixedModelColor: [\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#bfbdbe\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f8f3f7\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#dde2de\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#4bd4e7\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#eaf7ff\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#aae9f8\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#5ed593\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#e5fbee\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#a5efcc\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#f6cb4b\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#fff9e7\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#ffebac\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#f96420\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#ffe5d9\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#ffcfba\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#5599fc\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#ecf2fe\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#afcbfa\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#22a69b\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#dff2f8\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#8dd4d0\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#7a939a\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f0eff7\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#bdcad0\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#d7a270\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#fdf3f1\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#ead2b6\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#89c54b\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f1f7e9\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#c5e3a7\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#8f88f0\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f0e5ff\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#c6c4f6\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#fd1664\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#feddee\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#f98ab5\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#da96d3\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#fce8fb\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#f2caee\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#b49191\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f5ebe8\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#d8c3c3\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#91b493\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f0fbf0\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#b4cfb6\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#b4a891\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f8f6f1\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#d3cab8\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#91abb4\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#eff7fa\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#b7cbd3\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#b7ba82\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#fafbeb\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#dadcb4\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#df3e3e\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#fde9e9\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#f89292\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#f2711c\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#fef0d7\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#fbb335\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#b5cc18\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f9fbd4\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#e2ed2a\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#00b5ad\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#ccfaf9\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#00e4df\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#2185d0\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#d8f3fc\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#3cc4f0\" }\r\n },\r\n {\r\n \"head\": { \"fc\": \"#000\", \"bc\": \"#a5673f\" },\r\n \"one\": { \"fc\": \"#000\", \"bc\": \"#ffffff\" },\r\n \"two\": { \"fc\": \"#000\", \"bc\": \"#f6ede5\" },\r\n \"foot\": { \"fc\": \"#000\", \"bc\": \"#d3a47c\" }\r\n } \r\n ],\r\n getModelBox: function(hasRowHeader, hasRowFooter){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-modelList\").empty();\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-modelCustom\").empty();\r\n\r\n //格式样式 模板\r\n let modelListHtml = '';\r\n\r\n for(let i = 0; i < _this.FixedModelColor.length; i++){\r\n let obj = _this.FixedModelColor[i];\r\n\r\n let color1, color2, color3, color4;\r\n\r\n if(hasRowHeader && hasRowFooter){\r\n color1 = obj[\"head\"];\r\n color2 = obj[\"one\"];\r\n color3 = obj[\"two\"];\r\n color4 = obj[\"foot\"];\r\n }\r\n else if(hasRowHeader){\r\n color1 = obj[\"head\"];\r\n color2 = obj[\"one\"];\r\n color3 = obj[\"two\"];\r\n color4 = obj[\"one\"];\r\n }\r\n else if(hasRowFooter){\r\n color1 = obj[\"one\"];\r\n color2 = obj[\"two\"];\r\n color3 = obj[\"one\"];\r\n color4 = obj[\"foot\"];\r\n }\r\n else{\r\n color1 = obj[\"one\"];\r\n color2 = obj[\"two\"];\r\n color3 = obj[\"one\"];\r\n color4 = obj[\"two\"];\r\n }\r\n\r\n modelListHtml += '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n ''+\r\n ''+\r\n '
'+\r\n '
';\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-modelList\").append(modelListHtml);\r\n\r\n //自定义 模板\r\n let modelCustom = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_alternateformat_save_modelCustom\"];\r\n if(modelCustom != null && modelCustom.length > 0){\r\n let modelCustomHtml = '';\r\n\r\n for(let i = 0; i < modelCustom.length; i++){\r\n let obj = modelCustom[i];\r\n\r\n let color1, color2, color3, color4;\r\n\r\n if(hasRowHeader && hasRowFooter){\r\n color1 = obj[\"head\"];\r\n color2 = obj[\"one\"];\r\n color3 = obj[\"two\"];\r\n color4 = obj[\"foot\"];\r\n }\r\n else if(hasRowHeader){\r\n color1 = obj[\"head\"];\r\n color2 = obj[\"one\"];\r\n color3 = obj[\"two\"];\r\n color4 = obj[\"one\"];\r\n }\r\n else if(hasRowFooter){\r\n color1 = obj[\"one\"];\r\n color2 = obj[\"two\"];\r\n color3 = obj[\"one\"];\r\n color4 = obj[\"foot\"];\r\n }\r\n else{\r\n color1 = obj[\"one\"];\r\n color2 = obj[\"two\"];\r\n color3 = obj[\"one\"];\r\n color4 = obj[\"two\"];\r\n }\r\n\r\n modelCustomHtml += '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n ''+\r\n ''+\r\n '
'+\r\n '
';\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-modelCustom\").append(modelCustomHtml);\r\n }\r\n },\r\n init: function(){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat\").remove();\r\n $(\"body\").append(luckysheetAlternateformatHtml());\r\n luckysheetsizeauto();\r\n\r\n //关闭\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat .luckysheet-model-close-btn\").click(function () {\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat\").hide();\r\n luckysheetsizeauto();\r\n });\r\n\r\n //应用范围\r\n $(document).off(\"focus.AFrangeInput\").on(\"focus.AFrangeInput\", \"#luckysheet-alternateformat-range input\", function(){\r\n _this.rangefocus = true;\r\n });\r\n $(document).off(\"blur.AFrangeInput\").on(\"blur.AFrangeInput\", \"#luckysheet-alternateformat-range input\", function(){\r\n _this.rangefocus = false;\r\n });\r\n\r\n $(document).off(\"keydown.AFrangeInput\").on(\"keydown.AFrangeInput\", \"#luckysheet-alternateformat-range input\", function(e){\r\n let rangeValue = $(this).val().trim();\r\n if(e.keyCode == 13){\r\n _this.update();\r\n }\r\n });\r\n $(document).off(\"click.AFrangeIcon\").on(\"click.AFrangeIcon\", \"#luckysheet-alternateformat-range .fa-table\", function(){\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat\").hide();\r\n luckysheetsizeauto();\r\n\r\n let rangeValue = $(this).parents(\"#luckysheet-alternateformat-range\").find(\"input\").val().trim();\r\n _this.rangeDialog(rangeValue);\r\n });\r\n $(document).off(\"click.AFrDCf\").on(\"click.AFrDCf\", \"#luckysheet-alternateformat-rangeDialog-confirm\", function(){\r\n let rangeValue = $(this).parents(\"#luckysheet-alternateformat-rangeDialog\").find(\"input\").val().trim();\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-range input\").val(rangeValue);\r\n\r\n $(this).parents(\"#luckysheet-alternateformat-rangeDialog\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat\").show();\r\n luckysheetsizeauto();\r\n\r\n _this.update();\r\n });\r\n $(document).off(\"click.AFrDCl\").on(\"click.AFrDCl\", \"#luckysheet-alternateformat-rangeDialog-close\", function(){\r\n $(this).parents(\"#luckysheet-alternateformat-rangeDialog\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat\").show();\r\n luckysheetsizeauto();\r\n });\r\n $(document).off(\"click.AFrDTitle\").on(\"click.AFrDTitle\", \"#luckysheet-alternateformat-rangeDialog .luckysheet-modal-dialog-title-close\", function(){\r\n $(this).parents(\"#luckysheet-alternateformat-rangeDialog\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat\").show();\r\n luckysheetsizeauto();\r\n });\r\n\r\n //页眉、页脚选中\r\n $(document).off(\"change.AFrowHeader\").on(\"change.AFrowHeader\", \"#luckysheet-alternateformat-rowHeader\", function(){\r\n let hasRowHeader;\r\n if($(this).is(\":checked\")){\r\n hasRowHeader = true;\r\n }\r\n else{\r\n hasRowHeader = false; \r\n }\r\n\r\n let hasRowFooter;\r\n if($(\"#luckysheet-alternateformat-rowFooter\").is(\":checked\")){\r\n hasRowFooter = true;\r\n }\r\n else{\r\n hasRowFooter = false; \r\n }\r\n\r\n _this.checkboxChange(hasRowHeader, hasRowFooter);\r\n _this.modelboxOn();\r\n _this.update();\r\n });\r\n $(document).off(\"change.AFrowFooter\").on(\"change.AFrowFooter\", \"#luckysheet-alternateformat-rowFooter\", function(){\r\n let hasRowHeader;\r\n if($(\"#luckysheet-alternateformat-rowHeader\").is(\":checked\")){\r\n hasRowHeader = true;\r\n }\r\n else{\r\n hasRowHeader = false; \r\n }\r\n\r\n let hasRowFooter;\r\n if($(this).is(\":checked\")){\r\n hasRowFooter = true;\r\n }\r\n else{\r\n hasRowFooter = false; \r\n }\r\n\r\n _this.checkboxChange(hasRowHeader, hasRowFooter);\r\n _this.modelboxOn();\r\n _this.update();\r\n });\r\n\r\n //点击样式模板\r\n $(document).off(\"click.AFmodelbox\").on(\"click.AFmodelbox\", \"#luckysheet-modal-dialog-slider-alternateformat .modelbox\", function(){\r\n let index = $(this).index();\r\n let $id = $(this).parents(\".cf\").attr(\"id\");\r\n\r\n if($id == \"luckysheet-alternateformat-modelList\"){\r\n _this.modelfocusIndex = index;\r\n }\r\n else if($id == \"luckysheet-alternateformat-modelCustom\"){\r\n let len = _this.FixedModelColor.length;\r\n _this.modelfocusIndex = index + len;\r\n }\r\n\r\n _this.modelboxOn();\r\n _this.update();\r\n });\r\n\r\n //点击选择文本/单元格颜色\r\n $(document).off(\"click.AFselectColor\").on(\"click.AFselectColor\", \"#luckysheet-modal-dialog-slider-alternateformat .luckysheet-color-menu-button-indicator\", function(){\r\n let $parent = $(this).closest(\".toningbox\");\r\n\r\n let colorType, currenColor;\r\n if($(this).find(\".luckysheet-icon-img\").hasClass(\"luckysheet-icon-text-color\")){\r\n colorType = \"fc\";\r\n currenColor = $parent.find(\".toningShow\").data(\"fc\");\r\n }\r\n else if($(this).find(\".luckysheet-icon-img\").hasClass(\"luckysheet-icon-cell-color\")){\r\n colorType = \"bc\";\r\n currenColor = $parent.find(\".toningShow\").data(\"bc\");\r\n }\r\n\r\n //source\r\n let source;\r\n if($parent.hasClass(\"header\")){\r\n source = \"0\";\r\n }\r\n else if($parent.hasClass(\"ctOne\")){\r\n source = \"1\";\r\n }\r\n else if($parent.hasClass(\"ctTwo\")){\r\n source = \"2\";\r\n }\r\n else if($parent.hasClass(\"footer\")){\r\n source = \"3\";\r\n }\r\n\r\n _this.colorSelectDialog(currenColor, colorType, source);\r\n });\r\n\r\n //选择颜色 确定 添加自定义模板\r\n $(document).off(\"click.AFselectColorConfirm\").on(\"click.AFselectColorConfirm\", \"#luckysheet-alternateformat-colorSelect-dialog-confirm\", function(){\r\n let $parent = $(this).parents(\"#luckysheet-alternateformat-colorSelect-dialog\");\r\n const _locale = locale()\r\n const alternatingColors =_locale.alternatingColors;\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $parent.hide();\r\n\r\n //获取currenColor colorType source\r\n let currenColor = $parent.find(\".currenColor span\").attr(\"title\");\r\n\r\n let colorType;\r\n if($parent.find(\".luckysheet-modal-dialog-title-text\").text() == alternatingColors.selectionTextColor){\r\n colorType = \"fc\";\r\n }\r\n else if($parent.find(\".luckysheet-modal-dialog-title-text\").text() == alternatingColors.selectionCellColor){\r\n colorType = \"bc\";\r\n }\r\n\r\n let source = $parent.find(\".currenColor\").attr(\"data-source\");\r\n \r\n //赋给颜色\r\n if(source == \"0\"){\r\n if(colorType == \"fc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .header .toningShow\").css(\"color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .header .toningShow\").data(\"fc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .header .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n if(colorType == \"bc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .header .toningShow\").css(\"background-color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .header .toningShow\").data(\"bc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .header .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n }\r\n else if(source == \"1\"){\r\n if(colorType == \"fc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .toningShow\").css(\"color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .toningShow\").data(\"fc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n if(colorType == \"bc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .toningShow\").css(\"background-color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .toningShow\").data(\"bc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n }\r\n else if(source == \"2\"){\r\n if(colorType == \"fc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .toningShow\").css(\"color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .toningShow\").data(\"fc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n if(colorType == \"bc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .toningShow\").css(\"background-color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .toningShow\").data(\"bc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n }\r\n else if(source == \"3\"){\r\n if(colorType == \"fc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .footer .toningShow\").css(\"color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .footer .toningShow\").data(\"fc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .footer .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n if(colorType == \"bc\"){\r\n $(\"#luckysheet-alternateformat-modelToning .footer .toningShow\").css(\"background-color\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .footer .toningShow\").data(\"bc\", currenColor);\r\n $(\"#luckysheet-alternateformat-modelToning .footer .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", currenColor);\r\n }\r\n }\r\n \r\n //若模板聚焦在固有模板,则新加模板;若模板聚焦在自定义模板,则修改该模板\r\n let hasRowHeader;\r\n if($(\"#luckysheet-alternateformat-rowHeader\").is(\":checked\")){\r\n hasRowHeader = true;\r\n }\r\n else{\r\n hasRowHeader = false; \r\n }\r\n\r\n let hasRowFooter;\r\n if($(\"#luckysheet-alternateformat-rowFooter\").is(\":checked\")){\r\n hasRowFooter = true;\r\n }\r\n else{\r\n hasRowFooter = false; \r\n }\r\n\r\n let index = _this.modelfocusIndex;\r\n let len = _this.FixedModelColor.length;\r\n\r\n let format, file;\r\n if(index < len){\r\n format = $.extend(true, {}, _this.getFormatByIndex());\r\n }\r\n else{\r\n file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n let modelCustom = file[\"luckysheet_alternateformat_save_modelCustom\"];\r\n\r\n format = $.extend(true, {}, modelCustom[index - len]);\r\n }\r\n\r\n if(source == \"0\"){\r\n if(colorType == \"fc\"){\r\n format[\"head\"][\"fc\"] = currenColor;\r\n }\r\n else if(colorType == \"bc\"){\r\n format[\"head\"][\"bc\"] = currenColor;\r\n }\r\n }\r\n else if(source == \"1\"){\r\n if(colorType == \"fc\"){\r\n format[\"one\"][\"fc\"] = currenColor;\r\n }\r\n else if(colorType == \"bc\"){\r\n format[\"one\"][\"bc\"] = currenColor;\r\n }\r\n }\r\n else if(source == \"2\"){\r\n if(colorType == \"fc\"){\r\n format[\"two\"][\"fc\"] = currenColor;\r\n }\r\n else if(colorType == \"bc\"){\r\n format[\"two\"][\"bc\"] = currenColor;\r\n }\r\n }\r\n else if(source == \"3\"){\r\n if(colorType == \"fc\"){\r\n format[\"foot\"][\"fc\"] = currenColor;\r\n }\r\n if(colorType == \"bc\"){\r\n format[\"foot\"][\"bc\"] = currenColor;\r\n }\r\n }\r\n\r\n if(_this.modelfocusIndex < len){\r\n _this.addCustomModel(format);\r\n _this.modelfocusIndex = _this.getIndexByFormat(format);\r\n }\r\n else{\r\n file[\"luckysheet_alternateformat_save_modelCustom\"][index - len] = format;\r\n\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, file[\"luckysheet_alternateformat_save_modelCustom\"], { \"k\": \"luckysheet_alternateformat_save_modelCustom\" });\r\n }\r\n }\r\n\r\n _this.getModelBox(hasRowHeader, hasRowFooter);\r\n _this.modelboxOn();\r\n _this.update();\r\n });\r\n \r\n //点击 移除交替颜色 按钮\r\n $(document).off(\"click.AFremove\").on(\"click.AFremove\", \"#luckysheet-alternateformat-remove\", function(){\r\n let dataIndex = $(this).data(\"index\");\r\n\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n\r\n let ruleArr = file[\"luckysheet_alternateformat_save\"];\r\n\r\n //保存之前的规则\r\n let historyRules = $.extend(true, [], ruleArr);\r\n\r\n //保存当前的规则\r\n if(ruleArr.length > 1){\r\n ruleArr.splice(dataIndex, 1);\r\n }\r\n else{\r\n ruleArr = [];\r\n }\r\n\r\n let currentRules = $.extend(true, [], ruleArr);\r\n \r\n //刷新一次表格\r\n _this.ref(historyRules, currentRules);\r\n\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, ruleArr, { \"k\": \"luckysheet_alternateformat_save\" });\r\n }\r\n\r\n //隐藏一些dom\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat\").hide();\r\n\r\n luckysheetsizeauto();\r\n });\r\n },\r\n perfect: function(){\r\n let _this = this;\r\n\r\n let range = $.extend(true, {}, Store.luckysheet_select_save[0]);\r\n let existsIndex = _this.rangeIsExists(range)[1];\r\n \r\n let obj = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_alternateformat_save\"][existsIndex]);\r\n \r\n //应用范围\r\n let cellrange = obj[\"cellrange\"];\r\n $(\"#luckysheet-alternateformat-range input\").val(getRangetxt(Store.currentSheetIndex, { \"row\": cellrange[\"row\"], \"column\": cellrange[\"column\"] }, Store.currentSheetIndex));\r\n \r\n Store.luckysheet_select_save = [{ \"row\": cellrange[\"row\"], \"column\": cellrange[\"column\"] }];\r\n selectHightlightShow();\r\n\r\n //页眉、页脚\r\n let hasRowHeader = obj[\"hasRowHeader\"];\r\n let hasRowFooter = obj[\"hasRowFooter\"];\r\n \r\n //模板聚焦\r\n let format = obj[\"format\"];\r\n _this.modelfocusIndex = _this.getIndexByFormat(format);\r\n\r\n if(_this.modelfocusIndex == null){\r\n _this.addCustomModel(format);\r\n _this.modelfocusIndex = _this.getIndexByFormat(format);\r\n }\r\n\r\n _this.checkboxChange(hasRowHeader, hasRowFooter);\r\n _this.modelboxOn();\r\n\r\n //标识 交替颜色的index\r\n $(\"#luckysheet-alternateformat-remove\").data(\"index\", existsIndex);\r\n },\r\n checkboxChange: function(hasRowHeader, hasRowFooter){\r\n if(hasRowHeader){\r\n $(\"#luckysheet-alternateformat-rowHeader\").prop(\"checked\", true);\r\n $(\"#luckysheet-alternateformat-modelToning .header\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-alternateformat-rowHeader\").removeAttr(\"checked\"); \r\n $(\"#luckysheet-alternateformat-modelToning .header\").hide(); \r\n }\r\n\r\n if(hasRowFooter){\r\n $(\"#luckysheet-alternateformat-rowFooter\").prop(\"checked\", true);\r\n $(\"#luckysheet-alternateformat-modelToning .footer\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-alternateformat-rowFooter\").removeAttr(\"checked\"); \r\n $(\"#luckysheet-alternateformat-modelToning .footer\").hide(); \r\n }\r\n\r\n this.getModelBox(hasRowHeader, hasRowFooter);\r\n },\r\n modelboxOn: function(){\r\n let _this = this;\r\n\r\n //模板 foucs\r\n $(\"#luckysheet-modal-dialog-slider-alternateformat .modelbox\").removeClass(\"on\");\r\n\r\n let index = _this.modelfocusIndex;\r\n let len = _this.FixedModelColor.length;\r\n \r\n if(index < len){\r\n $(\"#luckysheet-alternateformat-modelList .modelbox\").eq(index).addClass(\"on\");\r\n }\r\n else{\r\n $(\"#luckysheet-alternateformat-modelCustom .modelbox\").eq(index - len).addClass(\"on\");\r\n }\r\n\r\n //编辑 对应颜色改变\r\n _this.modelToningColor();\r\n },\r\n modelToningColor: function(){\r\n let format = this.getFormatByIndex();\r\n\r\n //页眉\r\n $(\"#luckysheet-alternateformat-modelToning .header .toningShow\").css({\"color\": format[\"head\"].fc, \"background-color\": format[\"head\"].bc});\r\n $(\"#luckysheet-alternateformat-modelToning .header .toningShow\").data(\"fc\", format[\"head\"].fc).data(\"bc\", format[\"head\"].bc);\r\n $(\"#luckysheet-alternateformat-modelToning .header .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"head\"].fc);\r\n $(\"#luckysheet-alternateformat-modelToning .header .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"head\"].bc);\r\n\r\n //颜色1\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .toningShow\").css({\"color\": format[\"one\"].fc, \"background-color\": format[\"one\"].bc});\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .toningShow\").data(\"fc\", format[\"one\"].fc).data(\"bc\", format[\"one\"].bc);\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"one\"].fc);\r\n $(\"#luckysheet-alternateformat-modelToning .ctOne .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"one\"].bc);\r\n\r\n //颜色2\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .toningShow\").css({\"color\": format[\"two\"].fc, \"background-color\": format[\"two\"].bc});\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .toningShow\").data(\"fc\", format[\"two\"].fc).data(\"bc\", format[\"two\"].bc);\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"two\"].fc);\r\n $(\"#luckysheet-alternateformat-modelToning .ctTwo .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"two\"].bc);\r\n\r\n //页脚\r\n $(\"#luckysheet-alternateformat-modelToning .footer .toningShow\").css({\"color\": format[\"foot\"].fc, \"background-color\": format[\"foot\"].bc});\r\n $(\"#luckysheet-alternateformat-modelToning .footer .toningShow\").data(\"fc\", format[\"foot\"].fc).data(\"bc\", format[\"foot\"].bc);\r\n $(\"#luckysheet-alternateformat-modelToning .footer .luckysheet-icon-text-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"foot\"].fc);\r\n $(\"#luckysheet-alternateformat-modelToning .footer .luckysheet-icon-cell-color\").parents(\".luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", format[\"foot\"].bc);\r\n },\r\n addCustomModel: function(format){\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n\r\n if(file[\"luckysheet_alternateformat_save_modelCustom\"] == null){\r\n file[\"luckysheet_alternateformat_save_modelCustom\"] = [];\r\n }\r\n\r\n file[\"luckysheet_alternateformat_save_modelCustom\"].push(format);\r\n\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, file[\"luckysheet_alternateformat_save_modelCustom\"], { \"k\": \"luckysheet_alternateformat_save_modelCustom\" });\r\n }\r\n },\r\n colorSelectDialog: function(currenColor, colorType, source){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-alternateformat-colorSelect-dialog\").remove();\r\n\r\n const _locale = locale()\r\n const alternatingColors =_locale.alternatingColors;\r\n const locale_button = _locale.button;\r\n const locale_toolbar = _locale.toolbar;\r\n\r\n let title;\r\n if(colorType == \"fc\"){\r\n title = alternatingColors.selectionTextColor;\r\n }\r\n else if(colorType == \"bc\"){\r\n title = alternatingColors.selectionCellColor;\r\n }\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-alternateformat-colorSelect-dialog\", \r\n \"addclass\": \"luckysheet-alternateformat-colorSelect-dialog\", \r\n \"title\": title, \r\n \"content\": \"
\"+ alternatingColors.currentColor +\":
\", \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-alternateformat-colorSelect-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-alternateformat-colorSelect-dialog\").css({ \r\n \"left\": (winw + scrollLeft - myw) / 2, \r\n \"top\": (winh + scrollTop - myh) / 3 \r\n }).show();\r\n \r\n //初始化选择颜色插件\r\n $(\"#luckysheet-alternateformat-colorSelect-dialog\").find(\".colorshowbox\").spectrum({\r\n showPalette: true,\r\n showPaletteOnly: true,\r\n preferredFormat: \"hex\",\r\n clickoutFiresChange: false,\r\n showInitial: true,\r\n showInput: true,\r\n flat: true,\r\n hideAfterPaletteSelect: true,\r\n showSelectionPalette: true,\r\n showButtons: false,//隐藏选择取消按钮\r\n maxPaletteSize: 8,\r\n maxSelectionSize: 8,\r\n color: currenColor,\r\n cancelText: locale_button.cancel,\r\n chooseText: locale_toolbar.confirmColor,\r\n togglePaletteMoreText: locale_toolbar.customColor,\r\n togglePaletteLessText: locale_toolbar.collapse,\r\n togglePaletteOnly: true,\r\n clearText: locale_toolbar.clearText,\r\n noColorSelectedText: locale_toolbar.noColorSelectedText,\r\n localStorageKey: \"spectrum.textcolor\" + server.gridKey,\r\n palette: [\r\n [\"#000\", \"#444\", \"#666\", \"#999\", \"#ccc\", \"#eee\", \"#f3f3f3\", \"#fff\"],\r\n [\"#f00\", \"#f90\", \"#ff0\", \"#0f0\", \"#0ff\", \"#00f\", \"#90f\", \"#f0f\"],\r\n [\"#f4cccc\", \"#fce5cd\", \"#fff2cc\", \"#d9ead3\", \"#d0e0e3\", \"#cfe2f3\", \"#d9d2e9\", \"#ead1dc\"],\r\n [\"#ea9999\", \"#f9cb9c\", \"#ffe599\", \"#b6d7a8\", \"#a2c4c9\", \"#9fc5e8\", \"#b4a7d6\", \"#d5a6bd\"],\r\n [\"#e06666\", \"#f6b26b\", \"#ffd966\", \"#93c47d\", \"#76a5af\", \"#6fa8dc\", \"#8e7cc3\", \"#c27ba0\"],\r\n [\"#c00\", \"#e69138\", \"#f1c232\", \"#6aa84f\", \"#45818e\", \"#3d85c6\", \"#674ea7\", \"#a64d79\"],\r\n [\"#900\", \"#b45f06\", \"#bf9000\", \"#38761d\", \"#134f5c\", \"#0b5394\", \"#351c75\", \"#741b47\"],\r\n [\"#600\", \"#783f04\", \"#7f6000\", \"#274e13\", \"#0c343d\", \"#073763\", \"#20124d\", \"#4c1130\"]\r\n ],\r\n move: function(color){\r\n if (color != null) {\r\n color = color.toHexString();\r\n }\r\n else {\r\n color = \"#000\";\r\n }\r\n\r\n $(\"#luckysheet-alternateformat-colorSelect-dialog .currenColor span\").css(\"background-color\", color).attr(\"title\", color);\r\n }\r\n });\r\n },\r\n rangeDialog: function(value){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-alternateformat-rangeDialog\").remove();\r\n\r\n const _locale = locale()\r\n const alternatingColors =_locale.alternatingColors;\r\n const locale_button = _locale.button;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-alternateformat-rangeDialog\", \r\n \"addclass\": \"luckysheet-alternateformat-rangeDialog\", \r\n \"title\": alternatingColors.selectRange, \r\n \"content\": '', \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-alternateformat-rangeDialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-alternateformat-rangeDialog\").css({ \r\n \"left\": (winw + scrollLeft - myw) / 2, \r\n \"top\": (winh + scrollTop - myh) / 3 \r\n }).show();\r\n },\r\n rangeIsExists: function(range, index){\r\n let _this = this;\r\n\r\n let isExists = false;\r\n let existsIndex = null;\r\n\r\n //获取已有交替颜色所有应用范围\r\n let AFarr = $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_alternateformat_save\"]);\r\n\r\n if(index != undefined && index != null){\r\n if(AFarr.length > 1){\r\n AFarr.splice(index, 1);\r\n }\r\n else{\r\n AFarr = [];\r\n }\r\n }\r\n\r\n if(AFarr.length > 0){\r\n let arr = [];\r\n for(let i = 0; i < AFarr.length; i++){\r\n let obj = {\r\n \"index\": i,\r\n \"map\": _this.getRangeMap(AFarr[i][\"cellrange\"][\"row\"], AFarr[i][\"cellrange\"][\"column\"])\r\n }\r\n\r\n arr.push(obj);\r\n }\r\n \r\n //获取当前选区\r\n let rangeMap = _this.getRangeMap(range[\"row\"], range[\"column\"]);\r\n \r\n //遍历\r\n for(let x in rangeMap){\r\n if(isExists){\r\n break;\r\n } \r\n\r\n for(let j = 0; j < arr.length; j++){\r\n if(x in arr[j][\"map\"]){\r\n isExists = true;\r\n existsIndex = arr[j][\"index\"];\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return [isExists, existsIndex];\r\n },\r\n getRangeMap: function(row, column){\r\n let map = {};\r\n let st_r = row[0], ed_r = row[1], st_c = column[0], ed_c = column[1];\r\n \r\n for(let r = st_r; r <= ed_r; r++){\r\n for(let c = st_c; c <= ed_c; c++){\r\n map[r + \"_\" + c] = 0;\r\n }\r\n }\r\n \r\n return map;\r\n },\r\n getIndexByFormat: function(format){\r\n let _this = this;\r\n let index = null;\r\n\r\n //格式样式 模板\r\n let modelList = _this.FixedModelColor;\r\n for(let i = 0; i < modelList.length; i++){\r\n let obj = modelList[i];\r\n\r\n if(format[\"head\"].fc == obj[\"head\"].fc && format[\"head\"].bc == obj[\"head\"].bc){\r\n if(format[\"one\"].fc == obj[\"one\"].fc && format[\"one\"].bc == obj[\"one\"].bc){\r\n if(format[\"two\"].fc == obj[\"two\"].fc && format[\"two\"].bc == obj[\"two\"].bc){\r\n if(format[\"foot\"].fc == obj[\"foot\"].fc && format[\"foot\"].bc == obj[\"foot\"].bc){\r\n index = i;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n \r\n //自定义 模板\r\n let modelCustom = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_alternateformat_save_modelCustom\"];\r\n if(modelCustom != null && modelCustom.length > 0){\r\n for(let j = 0; j < modelCustom.length; j++){\r\n let obj = modelCustom[j];\r\n\r\n if(format[\"head\"].fc == obj[\"head\"].fc && format[\"head\"].bc == obj[\"head\"].bc){\r\n if(format[\"one\"].fc == obj[\"one\"].fc && format[\"one\"].bc == obj[\"one\"].bc){\r\n if(format[\"two\"].fc == obj[\"two\"].fc && format[\"two\"].bc == obj[\"two\"].bc){\r\n if(format[\"foot\"].fc == obj[\"foot\"].fc && format[\"foot\"].bc == obj[\"foot\"].bc){\r\n index = modelList.length + j;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n \r\n return index;\r\n },\r\n getFormatByIndex: function(){\r\n let _this = this;\r\n\r\n let index = _this.modelfocusIndex;\r\n let len = _this.FixedModelColor.length;\r\n\r\n let format = {};\r\n\r\n if(index < len){\r\n format = _this.FixedModelColor[index];\r\n }\r\n else{\r\n format = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_alternateformat_save_modelCustom\"][index - len];\r\n }\r\n\r\n return format;\r\n },\r\n new: function(cellrange){\r\n let _this = this;\r\n\r\n let format = _this.getFormatByIndex();\r\n\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n let ruleArr = file[\"luckysheet_alternateformat_save\"];\r\n \r\n if(ruleArr == null){\r\n ruleArr = [];\r\n }\r\n\r\n //保存之前的规则\r\n let historyRules = $.extend(true, [], ruleArr);\r\n \r\n //保存当前的规则\r\n let obj = {\r\n \"cellrange\": {\r\n \"row\": cellrange[\"row\"],\r\n \"column\": cellrange[\"column\"]\r\n },\r\n \"format\": format,\r\n \"hasRowHeader\": true,\r\n \"hasRowFooter\": false\r\n }\r\n\r\n ruleArr.push(obj);\r\n\r\n let currentRules = $.extend(true, [], ruleArr);\r\n \r\n //刷新一次表格\r\n _this.ref(historyRules, currentRules);\r\n\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, ruleArr, { \"k\": \"luckysheet_alternateformat_save\" });\r\n }\r\n },\r\n update: function(){\r\n let _this = this;\r\n const _locale = locale()\r\n const alternatingColors =_locale.alternatingColors;\r\n //获取标识\r\n let dataIndex = $(\"#luckysheet-alternateformat-remove\").data(\"index\");\r\n \r\n //应用范围\r\n let rangeValue = $(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-range input\").val().trim();\r\n \r\n if(!formula.iscelldata(rangeValue)){\r\n if(isEditMode()){\r\n alert(alternatingColors.errorNoRange);\r\n }\r\n else{\r\n tooltip.info(alternatingColors.errorNoRange, \"\");\r\n }\r\n\r\n return;\r\n }\r\n \r\n let cellrange = formula.getcellrange(rangeValue);\r\n let isExists = _this.rangeIsExists(cellrange, dataIndex)[0];\r\n\r\n if(isExists){\r\n if(isEditMode()){\r\n alert(alternatingColors.errorExistColors);\r\n }\r\n else{\r\n tooltip.info(alternatingColors.errorExistColors, \"\"); \r\n }\r\n\r\n return;\r\n }\r\n\r\n //页眉、页脚\r\n let hasRowHeader;\r\n if($(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-rowHeader\").is(\":checked\")){\r\n hasRowHeader = true;\r\n }\r\n else{\r\n hasRowHeader = false; \r\n }\r\n\r\n let hasRowFooter;\r\n if($(\"#luckysheet-modal-dialog-slider-alternateformat #luckysheet-alternateformat-rowFooter\").is(\":checked\")){\r\n hasRowFooter = true;\r\n }\r\n else{\r\n hasRowFooter = false; \r\n }\r\n\r\n //获取选中样式模板的颜色\r\n let format = _this.getFormatByIndex();\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n \r\n let ruleArr = file[\"luckysheet_alternateformat_save\"];\r\n if(ruleArr == null){\r\n ruleArr = [];\r\n }\r\n \r\n //保存之前的规则\r\n let historyRules = $.extend(true, [], ruleArr);\r\n \r\n //保存当前的规则\r\n let obj = {\r\n \"cellrange\": {\r\n \"row\": cellrange[\"row\"],\r\n \"column\": cellrange[\"column\"]\r\n },\r\n \"format\": format,\r\n \"hasRowHeader\": hasRowHeader,\r\n \"hasRowFooter\": hasRowFooter\r\n }\r\n \r\n ruleArr[dataIndex] = obj;\r\n\r\n let currentRules = $.extend(true, [], ruleArr);\r\n \r\n //刷新一次表格\r\n _this.ref(historyRules, currentRules);\r\n\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, ruleArr, { \"k\": \"luckysheet_alternateformat_save\" });\r\n }\r\n },\r\n checksAF: function(r, c, computeMap){\r\n if((r + \"_\" + c) in computeMap){\r\n //返回值(fc bc)\r\n return computeMap[r + \"_\" + c];\r\n }\r\n else{\r\n return null;\r\n }\r\n },\r\n getComputeMap: function(){\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n let ruleArr = file[\"luckysheet_alternateformat_save\"];\r\n\r\n let computeMap = this.compute(ruleArr);\r\n\r\n return computeMap;\r\n },\r\n compute: function(obj){\r\n //计算存储\r\n let computeMap = {};\r\n\r\n if(obj != null && obj.length > 0){\r\n for(let i = 0; i < obj.length; i++){\r\n let cellrange = obj[i][\"cellrange\"];\r\n let format = obj[i][\"format\"];\r\n let hasRowHeader = obj[i][\"hasRowHeader\"];\r\n let hasRowFooter = obj[i][\"hasRowFooter\"];\r\n let st_r = cellrange[\"row\"][0], \r\n ed_r = cellrange[\"row\"][1], \r\n st_c = cellrange[\"column\"][0], \r\n ed_c = cellrange[\"column\"][1];\r\n \r\n if(hasRowHeader && hasRowFooter){\r\n //页眉所在行\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[st_r + \"_\" + c] = [format[\"head\"].fc, format[\"head\"].bc];\r\n }\r\n\r\n //中间行\r\n if(ed_r - st_r > 1){\r\n for(let r = st_r + 1; r < ed_r; r++){\r\n let fc, bc;\r\n if((r - st_r) % 2 != 0){\r\n fc = format[\"one\"].fc;\r\n bc = format[\"one\"].bc;\r\n }\r\n else{\r\n fc = format[\"two\"].fc;\r\n bc = format[\"two\"].bc;\r\n }\r\n\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[r + \"_\" + c] = [fc, bc];\r\n } \r\n }\r\n }\r\n\r\n //页脚所在行\r\n if(ed_r > st_r){\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[ed_r + \"_\" + c] = [format[\"foot\"].fc, format[\"foot\"].bc];\r\n }\r\n }\r\n }\r\n else if(hasRowHeader){\r\n //页眉所在行\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[st_r + \"_\" + c] = [format[\"head\"].fc, format[\"head\"].bc];\r\n }\r\n\r\n //中间行\r\n if(ed_r > st_r){\r\n for(let r = st_r + 1; r <= ed_r; r++){\r\n let fc, bc;\r\n if((r - st_r) % 2 != 0){\r\n fc = format[\"one\"].fc;\r\n bc = format[\"one\"].bc;\r\n }\r\n else{\r\n fc = format[\"two\"].fc;\r\n bc = format[\"two\"].bc;\r\n }\r\n\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[r + \"_\" + c] = [fc, bc];\r\n } \r\n }\r\n }\r\n }\r\n else if(hasRowFooter){\r\n //中间行\r\n if(ed_r > st_r){\r\n for(let r = st_r; r < ed_r; r++){\r\n let fc, bc;\r\n if((r - st_r) % 2 == 0){\r\n fc = format[\"one\"].fc;\r\n bc = format[\"one\"].bc;\r\n }\r\n else{\r\n fc = format[\"two\"].fc;\r\n bc = format[\"two\"].bc;\r\n }\r\n\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[r + \"_\" + c] = [fc, bc];\r\n }\r\n }\r\n }\r\n\r\n //页脚所在行\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[ed_r + \"_\" + c] = [format[\"foot\"].fc, format[\"foot\"].bc];\r\n }\r\n }\r\n else{\r\n //中间行\r\n for(let r = st_r; r <= ed_r; r++){\r\n let fc, bc;\r\n if((r - st_r) % 2 == 0){\r\n fc = format[\"one\"].fc;\r\n bc = format[\"one\"].bc;\r\n }\r\n else{\r\n fc = format[\"two\"].fc;\r\n bc = format[\"two\"].bc;\r\n }\r\n\r\n for(let c = st_c; c <= ed_c; c++){\r\n computeMap[r + \"_\" + c] = [fc, bc];\r\n } \r\n }\r\n }\r\n }\r\n }\r\n\r\n return computeMap;\r\n },\r\n ref: function(historyRules, currentRules){\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let redo = {};\r\n redo[\"type\"] = \"updateAF\";\r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n redo[\"data\"] = {\"historyRules\": historyRules, \"currentRules\": currentRules};\r\n Store.jfredo.push(redo); \r\n }\r\n\r\n let index = getSheetIndex(Store.currentSheetIndex);\r\n Store.luckysheetfile[index][\"luckysheet_alternateformat_save\"] = currentRules;\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n}\r\n\r\nexport default alternateformat;","import { getObjType } from '../utils/util';\r\n\r\nconst json = {\r\n parseJsonParm: function(obj){\r\n if(obj == null){\r\n return {};\r\n }\r\n else if(getObjType(obj) == \"string\"){\r\n try {\r\n let json = new Function(\"return \" + obj)(); \r\n return json;\r\n } \r\n catch(e) {\r\n return {};\r\n }\r\n }\r\n else{\r\n return obj;\r\n }\r\n },\r\n hasKey: function(obj){\r\n let _this = this;\r\n let json = _this.parseJsonParm(obj);\r\n \r\n for(let item in json){\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\nexport default json;","import { getSheetIndex } from '../methods/get';\r\nimport editor from '../global/editor';\r\nimport { isRealNull, isEditMode } from '../global/validate';\r\nimport tooltip from '../global/tooltip';\r\nimport { rowlenByRange } from '../global/getRowlen';\r\nimport { selectHightlightShow } from './select';\r\nimport { luckysheetMoveEndCell } from './sheetMove';\r\nimport server from './server';\r\nimport locale from '../locale/locale';\r\nimport Store from '../store';\r\nimport menuButton from './menuButton';\r\nimport conditionformat from './conditionformat';\r\nimport alternateformat from './alternateformat';\r\nimport {checkProtectionAuthorityNormal} from './protection';\r\nimport { \r\n rgbTohex, \r\n showrightclickmenu, \r\n} from '../utils/util';\r\nimport cleargridelement from '../global/cleargridelement';\r\nimport { \r\n jfrefreshgrid, \r\n jfrefreshgrid_rhcw,\r\n} from '../global/refresh';\r\nimport { orderbydata, orderbydata1D } from '../global/sort';\r\nimport json from '../global/json';\r\nimport { update, genarate } from '../global/format';\r\n\r\n//筛选配置状态\r\nfunction labelFilterOptionState($top, optionstate, rowhidden, caljs, notSave, str, edr, cindex, stc, edc) {\r\n if (optionstate) {\r\n $top.addClass(\"luckysheet-filter-options-active\").data(\"rowhidden\", JSON.stringify(rowhidden)).data(\"caljs\", JSON.stringify(caljs)).html('');\r\n\r\n if (caljs != null) {\r\n $top.data(\"byconditionvalue\", caljs[\"value\"]).data(\"byconditiontype\", caljs[\"type\"]).data(\"byconditiontext\", caljs[\"text\"]);\r\n \r\n if (caljs[\"value1\"] != null) {\r\n $top.data(\"byconditionvalue1\", caljs[\"value1\"]);\r\n }\r\n\r\n if (caljs[\"value2\"] != null) {\r\n $top.data(\"byconditionvalue2\", caljs[\"value2\"]);\r\n }\r\n }\r\n }\r\n else {\r\n $top.removeClass(\"luckysheet-filter-options-active\").data(\"rowhidden\", \"\").data(\"caljs\", \"\").html('');\r\n\r\n $top.data(\"byconditionvalue\", \"null\").data(\"byconditiontype\", \"0\").data(\"byconditiontext\", \"无\").data(\"byconditionvalue1\", \"\").data(\"byconditionvalue2\", \"\");\r\n }\r\n\r\n if(!!notSave){\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n\r\n if(file.filter == null){\r\n file.filter = {};\r\n }\r\n\r\n if (optionstate) {\r\n let param = {\r\n \"caljs\": caljs, \r\n \"rowhidden\": rowhidden, \r\n \"optionstate\": optionstate,\r\n \"str\": str,\r\n \"edr\": edr,\r\n \"cindex\": cindex,\r\n \"stc\": stc,\r\n \"edc\": edc\r\n };\r\n file.filter[cindex - stc] = param;\r\n }\r\n else {\r\n delete file.filter[cindex - stc];\r\n }\r\n\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.filter, { \"k\": \"filter\" });\r\n }\r\n}\r\n\r\n//筛选排序\r\nfunction orderbydatafiler(str, stc, edr, edc, index, asc) {\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n str = str + 1;\r\n\r\n let hasMc = false; //排序选区是否有合并单元格\r\n let data = [];\r\n\r\n for(let r = str; r <= edr; r++){\r\n let data_row = [];\r\n\r\n for(let c = stc; c <= edc; c++){\r\n if(d[r][c] != null && d[r][c].mc != null){\r\n hasMc = true;\r\n break;\r\n }\r\n\r\n data_row.push(d[r][c]);\r\n }\r\n\r\n data.push(data_row);\r\n }\r\n\r\n if(hasMc){\r\n const locale_filter = locale().filter;\r\n\r\n if(isEditMode()){\r\n alert(locale_filter.mergeError);\r\n }\r\n else{\r\n tooltip.info(locale_filter.mergeError, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n data = orderbydata(data, index - stc, asc);\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = stc; c <= edc; c++){\r\n d[r][c] = data[r - str][c - stc];\r\n }\r\n }\r\n\r\n let allParam = {};\r\n if(Store.config[\"rowlen\"] != null){\r\n let cfg = $.extend(true, {}, Store.config);\r\n cfg = rowlenByRange(d, str, edr, cfg);\r\n\r\n allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true\r\n }\r\n }\r\n\r\n jfrefreshgrid(d, [{ \"row\": [str, edr], \"column\": [stc, edc] }], allParam);\r\n}\r\n\r\n//创建筛选按钮\r\nfunction createFilter() {\r\n\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"filter\")){\r\n return;\r\n }\r\n\r\n if(Store.luckysheet_select_save.length > 1){\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n $(\"#\" + Store.container).attr(\"tabindex\", 0).focus();\r\n\r\n const locale_splitText = locale().splitText;\r\n\r\n if(isEditMode()){\r\n alert(locale_splitText.tipNoMulti);\r\n }\r\n else{\r\n tooltip.info(locale_splitText.tipNoMulti, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n if(Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].isPivotTable){\r\n return;\r\n }\r\n\r\n $('#luckysheet-filter-selected-sheet' + Store.currentSheetIndex + ', #luckysheet-filter-options-sheet' + Store.currentSheetIndex).remove();\r\n\r\n let last = Store.luckysheet_select_save[0];\r\n if (last[\"row\"][0] == last[\"row\"][1] && last[\"column\"][0] == last[\"column\"][1]) {\r\n let st_c, ed_c, curR = last[\"row\"][1];\r\n\r\n for (let c = 0; c < Store.flowdata[curR].length; c++) {\r\n let cell = Store.flowdata[curR][c];\r\n\r\n if (cell != null && !isRealNull(cell.v)) {\r\n if (st_c == null) {\r\n st_c = c;\r\n }\r\n }\r\n else if (st_c != null) {\r\n ed_c = c - 1;\r\n break;\r\n }\r\n }\r\n\r\n if (ed_c == null) {\r\n ed_c = Store.flowdata[curR].length - 1;\r\n }\r\n\r\n Store.luckysheet_select_save = [{ \"row\": [curR, curR], \"column\": [st_c, ed_c] }];\r\n selectHightlightShow();\r\n\r\n Store.luckysheet_shiftpositon = $.extend(true, {}, last);\r\n luckysheetMoveEndCell(\"down\", \"range\");\r\n }\r\n else if (last[\"row\"][1] - last[\"row\"][0] < 2) {\r\n Store.luckysheet_shiftpositon = $.extend(true, {}, last);\r\n luckysheetMoveEndCell(\"down\", \"range\");\r\n }\r\n\r\n Store.luckysheet_filter_save = $.extend(true, {}, Store.luckysheet_select_save[0]);\r\n\r\n createFilterOptions(Store.luckysheet_filter_save);\r\n\r\n server.saveParam(\"all\", Store.currentSheetIndex, Store.luckysheet_filter_save, { \"k\": \"filter_select\" });\r\n\r\n if (Store.filterchage) {\r\n Store.jfredo.push({ \r\n \"type\": \"filtershow\", \r\n \"data\": [], \r\n \"curdata\": [], \r\n \"sheetIndex\": Store.currentSheetIndex, \r\n \"filter_save\": Store.luckysheet_filter_save \r\n });\r\n }\r\n}\r\n\r\n//创建筛选配置\r\nfunction createFilterOptions(luckysheet_filter_save, filterObj) {\r\n $(\"#luckysheet-filter-selected-sheet\" + Store.currentSheetIndex).remove();\r\n $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex).remove();\r\n \r\n if(luckysheet_filter_save == null || JSON.stringify(luckysheet_filter_save) == \"{}\"){\r\n return;\r\n }\r\n\r\n let r1 = luckysheet_filter_save.row[0], \r\n r2 = luckysheet_filter_save.row[1];\r\n let c1 = luckysheet_filter_save.column[0], \r\n c2 = luckysheet_filter_save.column[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n \r\n let newSelectedHTML = '
';\r\n $(\"#luckysheet-cell-main\").append(newSelectedHTML);\r\n \r\n let optionHTML = \"\";\r\n\r\n for (let c = c1; c <= c2; c++) {\r\n if(filterObj == null || filterObj[c - c1] == null){\r\n optionHTML += '
';\r\n }\r\n else{\r\n let caljs_data;\r\n\r\n if(filterObj[c - c1].caljs != null){\r\n let caljs_value1_data;\r\n if (filterObj[c - c1].caljs[\"value1\"] != null) {\r\n caljs_value1_data = 'data-byconditionvalue1=\"'+ filterObj[c - c1].caljs[\"value1\"] +'\" ';\r\n }\r\n else{\r\n caljs_value1_data = '';\r\n }\r\n\r\n let caljs_value2_data;\r\n if (filterObj[c - c1].caljs[\"value2\"] != null) {\r\n caljs_value2_data = 'data-byconditionvalue2=\"'+ filterObj[c - c1].caljs[\"value2\"] +'\" ';\r\n }\r\n else{\r\n caljs_value2_data = '';\r\n }\r\n\r\n caljs_data = 'data-caljs=\"'+ JSON.stringify(filterObj[c - c1].caljs) +'\" ' +\r\n 'data-byconditionvalue=\"'+ filterObj[c - c1].caljs[\"value\"] +'\" ' + \r\n 'data-byconditiontype=\"'+ filterObj[c - c1].caljs[\"type\"] +'\" ' +\r\n 'data-byconditiontext=\"'+ filterObj[c - c1].caljs[\"text\"] +'\" ' +\r\n caljs_value1_data + caljs_value2_data;\r\n }\r\n else{\r\n caljs_data = '';\r\n }\r\n\r\n optionHTML += '
';\r\n }\r\n }\r\n\r\n $(\"#luckysheet-cell-main\").append('
' + optionHTML + '
');\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n\r\n if ($(\"#luckysheet-cell-main\").scrollTop() > luckysheet_filter_save[\"top_move\"]) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(luckysheet_filter_save[\"top_move\"]);\r\n }\r\n\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n\r\n file.filter_select = luckysheet_filter_save;\r\n}\r\n\r\nfunction initialFilterHandler(){\r\n //filter event handler\r\n let hidefilersubmenu = null;\r\n const _locale = locale();\r\n const locale_filter = _locale.filter;\r\n const locale_button= _locale.button;\r\n $(\"#luckysheetfilter\").click(createFilter);\r\n\r\n //右键菜单 菜单项hover\r\n let submenuhide = null, rightclickmenu = null;\r\n $(\".luckysheet-cols-menu .luckysheet-cols-submenu\").hover(\r\n function () {\r\n let $t = $(this), attrid = $t.attr(\"id\"), $attr = $(\"#\" + attrid + \"_sub\"), $con = $t.parent();\r\n let winW = $(window).width(), winH = $(window).height();\r\n let menuW = $con.width(), attrH = $attr.height() + 25, attrW = $attr.width() + 5;\r\n let offset = $t.offset();\r\n let top = offset.top, left = offset.left + menuW;\r\n\r\n if (left + attrW > winW) {\r\n left = offset.left - attrW;\r\n }\r\n\r\n if (top + attrH > winH) {\r\n top = winH - attrH;\r\n }\r\n\r\n $attr.css({ \"top\": top, \"left\": left }).show();\r\n rightclickmenu = $t;\r\n },\r\n function () {\r\n let $t = $(this), attrid = $t.attr(\"id\"), $attr = $(\"#\" + attrid + \"_sub\");\r\n submenuhide = setTimeout(function () { $attr.hide(); }, 200);\r\n }\r\n );\r\n\r\n $(\".luckysheet-rightgclick-menu-sub\").hover(\r\n function () {\r\n rightclickmenu.addClass(\"luckysheet-cols-menuitem-hover\");\r\n clearTimeout(submenuhide);\r\n },\r\n function () {\r\n rightclickmenu.removeClass(\"luckysheet-cols-menuitem-hover\");\r\n $(this).hide();\r\n }\r\n );\r\n\r\n $(\"#luckysheet-filter-menu\").mouseover(function () {\r\n clearTimeout(hidefilersubmenu);\r\n \r\n hidefilersubmenu = setTimeout(function () {\r\n $(\"#luckysheet-filter-submenu\").hide();\r\n }, 500);\r\n });\r\n \r\n\r\n $(\"#luckysheet-filter-submenu\").mouseover(function () {\r\n clearTimeout(hidefilersubmenu);\r\n }).find(\".luckysheet-cols-menuitem\").click(function (e) {\r\n $(\"#luckysheet-filter-selected span\").html($(this).find(\".luckysheet-cols-menuitem-content\").text()).data(\"value\", $(this).data(\"value\"));\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input\").hide();\r\n\r\n let $type = $(this).data(\"type\");\r\n let $value = $(this).attr(\"data-value\");\r\n \r\n if ($type == \"2\") {\r\n $(\"#luckysheet-filter-selected span\").data(\"type\", \"2\");\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input2\").show();\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input input\").prop(\"type\", \"number\");\r\n }\r\n else if ($type == \"0\") {\r\n $(\"#luckysheet-filter-selected span\").data(\"type\", \"0\");\r\n }\r\n else {\r\n $(\"#luckysheet-filter-selected span\").data(\"type\", \"1\");\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input\").eq(0).show();\r\n \r\n //若是日期 改变input type类型为date\r\n if($value == \"dateequal\" || $value == \"datelessthan\" || $value == \"datemorethan\"){\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input input\").prop(\"type\", \"date\");\r\n }\r\n else if($value == \"morethan\" || $value == \"moreequalthan\" || $value == \"lessthan\" || $value == \"lessequalthan\" || $value == \"equal\" || $value == \"noequal\"){\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input input\").prop(\"type\", \"number\");\r\n }\r\n else{\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input input\").prop(\"type\", \"text\");\r\n }\r\n }\r\n\r\n $(\"#luckysheet-filter-byvalue\").next().slideUp();\r\n $(\"#luckysheet-filter-submenu\").hide();\r\n });\r\n\r\n $(\"#luckysheet-filter-bycondition, #luckysheet-filter-byvalue\").click(function () {\r\n let $t = $(this);\r\n $t.next().slideToggle(200);\r\n\r\n setTimeout(function () {\r\n if ($t.attr(\"id\") == \"luckysheet-filter-bycondition\" && $(\"#luckysheet-filter-bycondition\").next().is(\":visible\")) {\r\n if ($(\"#luckysheet-filter-selected span\").text() != locale_filter.filiterInputNone) {\r\n $(\"#luckysheet-filter-byvalue\").next().slideUp(200);\r\n }\r\n }\r\n\r\n if ($t.is($(\"#luckysheet-filter-bycondition\"))) {\r\n if ($(\"#luckysheet-filter-bycondition\").next().is(\":hidden\") && $(\"#luckysheet-filter-byvalue\").next().is(\":hidden\")) {\r\n $(\"#luckysheet-filter-byvalue\").next().slideDown(200);\r\n }\r\n }\r\n }, 300);\r\n });\r\n\r\n $(\"#luckysheet-filter-selected\").click(function () {\r\n let $t = $(this), toffset = $t.offset(), $menu = $(\"#luckysheet-filter-submenu\");\r\n $menu.hide();\r\n \r\n let winH = $(window).height(), winW = $(window).width();\r\n let menuW = $menu.width(), menuH = $menu.height();\r\n let top = toffset.top, left = toffset.left, mheight = winH - toffset.top - 20;\r\n \r\n if (toffset.left + menuW > winW) {\r\n left = toffset.left - menuW;\r\n }\r\n \r\n if (toffset.top > winH / 2) {\r\n top = winH - toffset.top;\r\n \r\n if (top < 0) {\r\n top = 0;\r\n }\r\n \r\n mheight = toffset.top - 20;\r\n }\r\n \r\n $menu.css({ \"top\": top, \"left\": left, \"height\": mheight }).show();\r\n clearTimeout(hidefilersubmenu);\r\n });\r\n\r\n //筛选按钮点击事件\r\n $(\"#luckysheet-cell-main\").on(\"click\", \".luckysheet-filter-options\", function (e) {\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"filter\")){\r\n return;\r\n }\r\n let $t = $(e.currentTarget), \r\n toffset = $t.offset(), \r\n $menu = $(\"#luckysheet-filter-menu\"), \r\n winH = $(window).height(), \r\n winW = $(window).width();\r\n\r\n let st_r = $t.data(\"str\"), \r\n ed_r = $t.data(\"edr\"), \r\n cindex = $t.data(\"cindex\"), \r\n st_c = $t.data(\"stc\"), \r\n ed_c = $t.data(\"edc\"), \r\n rowhidden = $t.data(\"rowhidden\") == \"\" ? {} : JSON.parse($t.data(\"rowhidden\").replace(/\\'/g, '\"'));\r\n\r\n $(\"body .luckysheet-cols-menu\").hide();\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n $(\"#luckysheet-filter-byvalue-input\").val(\"\");\r\n $(\"#luckysheet-filter-bycondition\").next().hide();\r\n $(\"#luckysheet-filter-byvalue\").next().show();\r\n \r\n $menu.data(\"str\", st_r);\r\n $menu.data(\"edr\", ed_r);\r\n $menu.data(\"cindex\", cindex);\r\n $menu.data(\"stc\", st_c);\r\n $menu.data(\"edc\", ed_c);\r\n\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input\").hide().find(\"input\").val();\r\n $(\"#luckysheet-filter-selected span\").data(\"type\", \"0\").data(\"type\", null).text(locale_filter.filiterInputNone);\r\n\r\n let byconditiontype = $t.data(\"byconditiontype\");\r\n $(\"#luckysheet-filter-selected span\").data(\"value\", $t.data(\"byconditionvalue\")).data(\"type\", byconditiontype).text($t.data(\"byconditiontext\"));\r\n\r\n if (byconditiontype == \"2\") {\r\n let $input = $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input2\").show().find(\"input\");\r\n $input.eq(0).val($t.data(\"byconditionvalue1\"));\r\n $input.eq(1).val($t.data(\"byconditionvalue2\"));\r\n }\r\n else if (byconditiontype == \"1\") {\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input\").eq(0).show().find(\"input\").val($t.data(\"byconditionvalue1\"));\r\n }\r\n\r\n $(\"#luckysheet-filter-orderby-asc\").off(\"click\").on(\"click\", function () {\r\n orderbydatafiler(st_r, st_c, ed_r, ed_c, cindex, true);\r\n });\r\n\r\n $(\"#luckysheet-filter-orderby-desc\").off(\"click\").on(\"click\", function () {\r\n orderbydatafiler(st_r, st_c, ed_r, ed_c, cindex, false);\r\n });\r\n\r\n $(\"#luckysheet-filter-byvalue-select\").empty().html('
'+locale_filter.filiterMoreDataTip+'
');\r\n\r\n let rowhiddenother = {}; //其它筛选列的隐藏行\r\n $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").not(this).each(function () {\r\n let $t = $(this), rh = $t.data(\"rowhidden\");\r\n \r\n if (rh == \"\") {\r\n return true;\r\n }\r\n\r\n rh = JSON.parse(rh.replace(/\\'/g, '\"'));\r\n \r\n for (let r in rh) {\r\n rowhiddenother[r] = 0;\r\n }\r\n });\r\n\r\n let data = Store.flowdata;\r\n\r\n setTimeout(function () {\r\n //日期值\r\n let dvmap = {}; \r\n let dvmap_uncheck = {};\r\n\r\n //除日期以外的值\r\n let vmap = {}; \r\n let vmap_uncheck = {}; \r\n\r\n for (let r = st_r + 1; r <= ed_r; r++) {\r\n if(r in rowhiddenother){\r\n continue;\r\n }\r\n\r\n if(Store.flowdata[r] == null){\r\n continue;\r\n }\r\n\r\n let cell = Store.flowdata[r][cindex];\r\n\r\n if(cell != null && !isRealNull(cell.v) && cell.ct != null && cell.ct.t == \"d\" ){ //单元格是日期\r\n let v = update(\"YYYY-MM-DD\", cell.v);\r\n\r\n let y = v.split(\"-\")[0];\r\n let m = v.split(\"-\")[1];\r\n let d = v.split(\"-\")[2];\r\n\r\n if(!(y in dvmap)){\r\n dvmap[y] = {};\r\n }\r\n\r\n if(!(m in dvmap[y])){\r\n dvmap[y][m] = {};\r\n }\r\n\r\n if(!(d in dvmap[y][m])){\r\n dvmap[y][m][d] = 0;\r\n }\r\n \r\n dvmap[y][m][d]++;\r\n\r\n if(r in rowhidden){\r\n dvmap_uncheck[y] = 0;\r\n dvmap_uncheck[m] = 0;\r\n dvmap_uncheck[d] = 0;\r\n }\r\n }\r\n else{\r\n let v, m;\r\n if(cell == null || isRealNull(cell.v)){\r\n v = null;\r\n m = null;\r\n }\r\n else{\r\n v = cell.v;\r\n m = cell.m;\r\n }\r\n\r\n if(!(v in vmap)){\r\n vmap[v] = {};\r\n }\r\n\r\n if(!(m in vmap[v])){\r\n vmap[v][m] = 0; \r\n }\r\n\r\n vmap[v][m]++;\r\n\r\n if(r in rowhidden){\r\n vmap_uncheck[v + \"#$$$#\" + m] = 0;\r\n }\r\n }\r\n }\r\n\r\n //遍历数据加到页面\r\n let item = [];\r\n\r\n if(JSON.stringify(dvmap).length > 2){\r\n for(let y in dvmap){\r\n let ysum = 0;\r\n let monthHtml = '';\r\n\r\n for(let m in dvmap[y]){\r\n let msum = 0;\r\n let dayHtml = '';\r\n\r\n for(let d in dvmap[y][m]){\r\n let dayL = dvmap[y][m][d];\r\n msum += dayL;\r\n\r\n //月 小于 10\r\n let mT;\r\n if(Number(m) < 10){\r\n mT = \"0\" + Number(m);\r\n }\r\n else{\r\n mT = m; \r\n }\r\n\r\n //日 小于 10\r\n let dT;\r\n if(Number(d) < 10){\r\n dT = \"0\" + Number(d);\r\n }\r\n else{\r\n dT = d; \r\n }\r\n\r\n //日是否选中状态\r\n if((y in dvmap_uncheck) && (m in dvmap_uncheck) && (d in dvmap_uncheck)){\r\n dayHtml += '
' +\r\n '' +\r\n '' +\r\n '( ' + dayL + ' )' +\r\n '
';\r\n }\r\n else{\r\n dayHtml += '
' +\r\n '' +\r\n '' +\r\n '( ' + dayL + ' )' +\r\n '
';\r\n }\r\n }\r\n\r\n ysum += msum;\r\n \r\n //月 小于 10\r\n let mT2;\r\n if(Number(m) < 10){\r\n mT2 = \"0\" + Number(m);\r\n }\r\n else{\r\n mT2 = m; \r\n }\r\n\r\n //月是否选中状态\r\n if((y in dvmap_uncheck) && (m in dvmap_uncheck)){\r\n monthHtml += '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + msum + ' )' +\r\n '
' +\r\n '
' + dayHtml + '
' +\r\n '
';\r\n }\r\n else{\r\n monthHtml += '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + msum + ' )' +\r\n '
' +\r\n '
' + dayHtml + '
' +\r\n '
';\r\n }\r\n }\r\n\r\n //年是否选中状态\r\n let yearHtml;\r\n if(y in dvmap_uncheck){\r\n yearHtml = '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + ysum + ' )' +\r\n '
' +\r\n '
' + monthHtml + '
' +\r\n '
';\r\n }\r\n else{\r\n yearHtml = '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + ysum + ' )' +\r\n '
' +\r\n '
' + monthHtml + '
' +\r\n '
';\r\n }\r\n\r\n item.unshift(yearHtml);\r\n }\r\n }\r\n\r\n if(JSON.stringify(vmap).length > 2){\r\n let vmapKeys = Object.keys(vmap);\r\n vmapKeys = orderbydata1D(vmapKeys, true);\r\n\r\n for(let i = 0; i < vmapKeys.length; i++){\r\n let v = vmapKeys[i];\r\n\r\n for(let x in vmap[v]){\r\n let text;\r\n if((v + \"#$$$#\" + x) == \"null#$$$#null\"){\r\n text = locale_filter.valueBlank;\r\n }\r\n else{\r\n text = x;\r\n }\r\n\r\n //是否选中状态\r\n let dataHtml;\r\n if((v + \"#$$$#\" + x) in vmap_uncheck){\r\n dataHtml = '
' +\r\n '' +\r\n '' +\r\n '( ' + vmap[v][x] + ' )' +\r\n '
';\r\n }\r\n else{\r\n dataHtml = '
' +\r\n '' +\r\n '' +\r\n '( ' + vmap[v][x] + ' )' +\r\n '
';\r\n }\r\n\r\n item.push(dataHtml);\r\n }\r\n }\r\n }\r\n\r\n $(\"#luckysheet-filter-byvalue-select\").html(\"
\" + item.join(\"\") + \"
\");\r\n }, 1);\r\n\r\n showrightclickmenu($menu, toffset.left, toffset.top + 20);\r\n\r\n e.stopPropagation();\r\n return false;\r\n });\r\n\r\n //按颜色筛选\r\n $(\"#luckysheet-filter-orderby-color\").hover(\r\n function(){\r\n //遍历筛选列颜色\r\n let $menu = $(\"#luckysheet-filter-menu\");\r\n let st_r = $menu.data(\"str\"), \r\n ed_r = $menu.data(\"edr\"), \r\n cindex = $menu.data(\"cindex\"), \r\n st_c = $menu.data(\"stc\"), \r\n ed_c = $menu.data(\"edc\");\r\n let bgMap = {}; //单元格颜色\r\n let fcMap = {}; //字体颜色\r\n \r\n let af_compute = alternateformat.getComputeMap();\r\n let cf_compute = conditionformat.getComputeMap();\r\n \r\n for (let r = st_r + 1; r <= ed_r; r++) {\r\n let cell = Store.flowdata[r][cindex];\r\n \r\n //单元格颜色\r\n let bg = menuButton.checkstatus(Store.flowdata, r, cindex , \"bg\");\r\n\r\n if(bg == null){\r\n bg = \"#ffffff\";\r\n }\r\n \r\n let checksAF = alternateformat.checksAF(r, cindex, af_compute);\r\n if(checksAF != null){//若单元格有交替颜色\r\n bg = checksAF[1];\r\n }\r\n \r\n let checksCF = conditionformat.checksCF(r, cindex, cf_compute);\r\n if(checksCF != null && checksCF[\"cellColor\"] != null){//若单元格有条件格式\r\n bg = checksCF[\"cellColor\"];\r\n }\r\n \r\n if(bg.indexOf(\"rgb\") > -1){\r\n bg = rgbTohex(bg);\r\n }\r\n \r\n if(bg.length == 4){\r\n bg = bg.substr(0, 1) + bg.substr(1, 1).repeat(2) + bg.substr(2, 1).repeat(2) + bg.substr(3, 1).repeat(2);\r\n }\r\n \r\n //字体颜色\r\n let fc = menuButton.checkstatus(Store.flowdata, r, cindex , \"fc\");\r\n \r\n if(checksAF != null){//若单元格有交替颜色\r\n fc = checksAF[0];\r\n }\r\n \r\n if(checksCF != null && checksCF[\"textColor\"] != null){//若单元格有条件格式\r\n fc = checksCF[\"textColor\"];\r\n }\r\n \r\n if(fc.indexOf(\"rgb\") > -1){\r\n fc = rgbTohex(fc);\r\n }\r\n \r\n if(fc.length == 4){\r\n fc = fc.substr(0, 1) + fc.substr(1, 1).repeat(2) + fc.substr(2, 1).repeat(2) + fc.substr(3, 1).repeat(2);\r\n }\r\n \r\n if(Store.config != null && Store.config[\"rowhidden\"] != null && r in Store.config[\"rowhidden\"]){\r\n bgMap[bg] = 1;\r\n \r\n if(cell != null && !isRealNull(cell.v)){\r\n fcMap[fc] = 1;\r\n }\r\n }\r\n else{\r\n bgMap[bg] = 0;\r\n \r\n if(cell != null && !isRealNull(cell.v)){\r\n fcMap[fc] = 0;\r\n }\r\n }\r\n }\r\n //\r\n let filterBgColorHtml = '';\r\n if(JSON.stringify(bgMap).length > 2 && Object.keys(bgMap).length > 1){\r\n let bgColorItemHtml = '';\r\n for(let b in bgMap){\r\n if(bgMap[b] == 0){\r\n bgColorItemHtml += '
';\r\n }\r\n else{\r\n bgColorItemHtml += '
';\r\n }\r\n }\r\n filterBgColorHtml = '
'+locale_filter.filiterByColorTip+'
' + bgColorItemHtml + '
';\r\n }\r\n \r\n let filterFcColorHtml = '';\r\n if(JSON.stringify(fcMap).length > 2 && Object.keys(fcMap).length > 1){\r\n let fcColorItemHtml = '';\r\n for(let f in fcMap){\r\n if(fcMap[f] == 0){\r\n fcColorItemHtml += '
';\r\n }\r\n else{\r\n fcColorItemHtml += '
';\r\n }\r\n }\r\n filterFcColorHtml = '
'+locale_filter.filiterByTextColorTip+'
' + fcColorItemHtml + '
';\r\n }\r\n //\r\n let content;\r\n if(filterBgColorHtml == '' && filterFcColorHtml == ''){\r\n content = '
'+locale_filter.filterContainerOneColorTip+'
';\r\n }\r\n else{\r\n content = filterBgColorHtml + filterFcColorHtml + '
';\r\n }\r\n //颜色筛选子菜单\r\n $(\"#luckysheet-filter-orderby-color-submenu\").remove();\r\n $(\"body\").append('
'+content+'
');\r\n let $t = $(\"#luckysheet-filter-orderby-color-submenu\").end();\r\n let $con = $(this).parent();\r\n let winW = $(window).width(), winH = $(window).height();\r\n let menuW = $con.width(), \r\n myh = $t.height() + 25, \r\n myw = $t.width() + 5;\r\n let offset = $(this).offset();\r\n let top = offset.top, left = offset.left + menuW;\r\n \r\n if (left + myw > winW) {\r\n left = offset.left - myw;\r\n }\r\n \r\n if (top + myh > winH) {\r\n top = winH - myh;\r\n }\r\n \r\n $(\"#luckysheet-filter-orderby-color-submenu\").css({ \"top\": top, \"left\": left }).show();\r\n },\r\n function(){\r\n submenuhide = setTimeout(function () { $(\"#luckysheet-filter-orderby-color-submenu\").hide(); }, 200);\r\n }\r\n );\r\n\r\n $(document).on(\"mouseover mouseleave\", \"#luckysheet-filter-orderby-color-submenu\", function(e){\r\n if (e.type === \"mouseover\") {\r\n clearTimeout(submenuhide);\r\n } \r\n else {\r\n $(this).hide();\r\n }\r\n });\r\n $(document).on(\"click\", \"#luckysheet-filter-orderby-color-submenu .item label\", function(){\r\n $(this).siblings(\"input[type='checkbox']\").click();\r\n });\r\n $(document).off(\"click.orderbyColorConfirm\").on(\"click.orderbyColorConfirm\", \"#luckysheet-filter-orderby-color-submenu #luckysheet-filter-orderby-color-confirm\", function(){\r\n let bg_colorMap = {};\r\n let fc_colorMap = {};\r\n \r\n $(\"#luckysheet-filter-orderby-color-submenu .item\").each(function(i, e){\r\n if($(e).find(\"input[type='checkbox']\").is(\":checked\")){\r\n let color = $(this).find(\"label\").attr(\"title\");\r\n let $id = $(this).closest(\".box\").attr(\"id\");\r\n \r\n if($id == \"filterBgColor\"){\r\n bg_colorMap[color] = 0;\r\n }\r\n else if($id == \"filterFcColor\"){\r\n fc_colorMap[color] = 0;\r\n }\r\n }\r\n });\r\n \r\n let bg_filter;\r\n if($(\"#luckysheet-filter-orderby-color-submenu #filterBgColor\").length > 0){\r\n bg_filter = true;\r\n }\r\n else{\r\n bg_filter = false;\r\n }\r\n \r\n let fc_filter;\r\n if($(\"#luckysheet-filter-orderby-color-submenu #filterFcColor\").length > 0){\r\n fc_filter = true;\r\n }\r\n else{\r\n fc_filter = false;\r\n }\r\n \r\n let $menu = $(\"#luckysheet-filter-menu\");\r\n let st_r = $menu.data(\"str\"), \r\n ed_r = $menu.data(\"edr\"), \r\n cindex = $menu.data(\"cindex\"), \r\n st_c = $menu.data(\"stc\"), \r\n ed_c = $menu.data(\"edc\");\r\n \r\n let rowhiddenother = {}; //其它筛选列的隐藏行\r\n $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").not($(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").eq(cindex - st_c).get(0)).each(function () {\r\n let $t = $(this), rh = $t.data(\"rowhidden\");\r\n \r\n if (rh == \"\") {\r\n return true;\r\n }\r\n \r\n rh = JSON.parse(rh);\r\n \r\n for (let r in rh) {\r\n rowhiddenother[r] = 0;\r\n }\r\n });\r\n \r\n let filterdata = {};\r\n let rowhidden = {};\r\n let caljs = {};\r\n \r\n let af_compute = alternateformat.getComputeMap();\r\n let cf_compute = conditionformat.getComputeMap();\r\n \r\n for (let r = st_r + 1; r <= ed_r; r++) {\r\n if(r in rowhiddenother){\r\n continue;\r\n }\r\n \r\n if(Store.flowdata[r] == null){\r\n continue;\r\n }\r\n \r\n let cell = Store.flowdata[r][cindex];\r\n \r\n //单元格颜色\r\n let bg = menuButton.checkstatus(Store.flowdata, r, cindex , \"bg\");\r\n \r\n let checksAF = alternateformat.checksAF(r, cindex, af_compute);\r\n if(checksAF != null){//若单元格有交替颜色\r\n bg = checksAF[1];\r\n }\r\n \r\n let checksCF = conditionformat.checksCF(r, cindex, cf_compute);\r\n if(checksCF != null && checksCF[\"cellColor\"] != null){//若单元格有条件格式\r\n bg = checksCF[\"cellColor\"];\r\n }\r\n \r\n // bg maybe null\r\n bg = bg == null ? '#ffffff' : bg;\r\n\r\n if(bg.indexOf(\"rgb\") > -1){\r\n bg = rgbTohex(bg);\r\n }\r\n \r\n if(bg.length == 4){\r\n bg = bg.substr(0, 1) + bg.substr(1, 1).repeat(2) + bg.substr(2, 1).repeat(2) + bg.substr(3, 1).repeat(2);\r\n }\r\n \r\n //文本颜色\r\n let fc = menuButton.checkstatus(Store.flowdata, r, cindex , \"fc\");\r\n \r\n if(checksAF != null){//若单元格有交替颜色\r\n fc = checksAF[0];\r\n }\r\n \r\n if(checksCF != null && checksCF[\"textColor\"] != null){//若单元格有条件格式\r\n fc = checksCF[\"textColor\"];\r\n }\r\n \r\n if(fc.indexOf(\"rgb\") > -1){\r\n fc = rgbTohex(fc);\r\n }\r\n \r\n if(fc.length == 4){\r\n fc = fc.substr(0, 1) + fc.substr(1, 1).repeat(2) + fc.substr(2, 1).repeat(2) + fc.substr(3, 1).repeat(2);\r\n }\r\n \r\n if(bg_filter && fc_filter){\r\n if(!(bg in bg_colorMap) && (!(fc in fc_colorMap) || cell == null || isRealNull(cell.v))){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if(bg_filter){\r\n if(!(bg in bg_colorMap)){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if(fc_filter){\r\n if(!(fc in fc_colorMap) || cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n \r\n let $top = $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").eq(cindex - st_c);\r\n \r\n let optionstate = Object.keys(rowhidden).length > 0;\r\n \r\n let rowhiddenall = $.extend(true, rowhiddenother, rowhidden), \r\n rowhidenPre = json.parseJsonParm($top.data(\"rowhidden\"));\r\n \r\n labelFilterOptionState($top, optionstate, rowhidden, caljs, true, st_r, ed_r, cindex, st_c, ed_c);\r\n \r\n let cfg = $.extend(true, {}, Store.config);\r\n cfg[\"rowhidden\"] = rowhiddenall;\r\n \r\n //保存撤销\r\n if(Store.clearjfundo){\r\n let redo = {};\r\n redo[\"type\"] = \"datachangeAll_filter\";\r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n \r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = cfg;\r\n \r\n redo[\"optionstate\"] = optionstate;\r\n redo[\"optionsindex\"] = cindex - st_c;\r\n \r\n redo[\"rowhidden\"] = $.extend(true, {}, rowhidden);\r\n redo[\"rowhidenPre\"] = $.extend(true, {}, rowhidenPre);\r\n \r\n if (caljs != null) {\r\n redo[\"caljs\"] = caljs;\r\n }\r\n \r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n }\r\n \r\n //config\r\n Store.config = cfg;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n \r\n server.saveParam(\"cg\", Store.currentSheetIndex, cfg[\"rowhidden\"], { \"k\": \"rowhidden\" });\r\n \r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n \r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu, #luckysheet-filter-orderby-color-submenu\").hide();\r\n cleargridelement();\r\n });\r\n\r\n //点击复选框\r\n $(document).off(\"click.filterCheckbox1\").on(\"click.filterCheckbox1\", \"#luckysheet-filter-byvalue-select .textBox\",function(){\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n })\r\n $(document).off(\"click.filterCheckbox2\").on(\"click.filterCheckbox2\", \"#luckysheet-filter-byvalue-select .year\",function(){\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".month\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".day\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".month\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".day\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n })\r\n $(document).off(\"click.filterCheckbox3\").on(\"click.filterCheckbox3\", \"#luckysheet-filter-byvalue-select .month\",function(){\r\n //月份 对应的 天\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).parents(\".monthBox\").find(\".day\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".monthBox\").find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).parents(\".monthBox\").find(\".day\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".monthBox\").find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n //月份 对应的 年份\r\n let yearDayAllCheck = true;\r\n let $yearDay = $(this).parents(\".yearBox\").find(\".day\");\r\n $yearDay.each(function(i,e){\r\n if($(e).attr(\"data-check\") == \"true\"){\r\n \r\n }\r\n else{\r\n yearDayAllCheck = false;\r\n }\r\n });\r\n if(yearDayAllCheck){\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n else{\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n })\r\n $(document).off(\"click.filterCheckbox4\").on(\"click.filterCheckbox4\", \"#luckysheet-filter-byvalue-select .day\",function(){\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n //天 对应的 月份\r\n let monthDayAllCheck = true;\r\n let $monthDay = $(this).parents(\".monthBox\").find(\".day\");\r\n $monthDay.each(function(i,e){\r\n if($(e).attr(\"data-check\") == \"true\"){\r\n \r\n }\r\n else{\r\n monthDayAllCheck = false;\r\n }\r\n });\r\n if(monthDayAllCheck){\r\n $(this).parents(\".monthBox\").find(\".month\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".monthBox\").find(\".month input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n else{\r\n $(this).parents(\".monthBox\").find(\".month\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".monthBox\").find(\".month input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n //天 对应的 年份\r\n let yearDayAllCheck = true;\r\n let $yearDay = $(this).parents(\".yearBox\").find(\".day\");\r\n $yearDay.each(function(i,e){\r\n if($(e).attr(\"data-check\") == \"true\"){\r\n \r\n }\r\n else{\r\n yearDayAllCheck = false;\r\n }\r\n });\r\n if(yearDayAllCheck){\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n else{\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n })\r\n\r\n //日期 三级下拉显示\r\n $(document).off(\"click.filterYearDropdown\").on(\"click.filterYearDropdown\", \"#luckysheet-filter-byvalue-select .yearBox .fa-caret-right\",function(event){\r\n let $p = $(this).parents(\".luckysheet-mousedown-cancel\");\r\n if($p.hasClass(\"year\")){\r\n $(this).parents(\".yearBox\").find(\".monthList\").slideToggle();\r\n }\r\n if($p.hasClass(\"month\")){\r\n $(this).parents(\".monthBox\").find(\".dayList\").slideToggle();\r\n }\r\n\r\n event.stopPropagation();\r\n });\r\n\r\n //全选\r\n $(\"#luckysheet-filter-byvalue-btn-all\").click(function () {\r\n $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']\").prop(\"checked\", true);\r\n $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']\").parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"true\");\r\n });\r\n\r\n //清除\r\n $(\"#luckysheet-filter-byvalue-btn-clear\").click(function () {\r\n $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']\").removeAttr(\"checked\");\r\n $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']\").parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"false\");\r\n });\r\n\r\n //反选\r\n $(\"#luckysheet-filter-byvalue-btn-contra\").click(function () {\r\n let $input = $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']\");\r\n $input.each(function(i, e){\r\n if($(e).is(\":checked\")){\r\n $(e).removeAttr(\"checked\");\r\n $(e).parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"false\");\r\n }\r\n else{\r\n $(e).prop(\"checked\", true);\r\n $(e).parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"true\");\r\n }\r\n });\r\n //天 对应的 月份\r\n let $month = $(\"#luckysheet-filter-byvalue-select .ListBox .monthBox\");\r\n $month.each(function(index, event){\r\n let monthDayAllCheck = true;\r\n let $monthDay = $(event).find(\".day input[type='checkbox']\");\r\n $monthDay.each(function(i,e){\r\n if($(e).is(\":checked\")){\r\n \r\n }\r\n else{\r\n monthDayAllCheck = false;\r\n }\r\n });\r\n if(monthDayAllCheck){\r\n $(event).find(\".month input[type='checkbox']\").prop(\"checked\", true);\r\n $(event).attr(\"data-check\", \"true\");\r\n }\r\n else{\r\n $(event).find(\".month input[type='checkbox']\").removeAttr(\"checked\");\r\n $(event).attr(\"data-check\", \"false\");\r\n }\r\n });\r\n //天 对应的 年份\r\n let $year = $(\"#luckysheet-filter-byvalue-select .ListBox .yearBox\");\r\n $year.each(function(index, event){\r\n let yearDayAllCheck = true;\r\n let $yearDay = $(event).find(\".day input[type='checkbox']\");\r\n $yearDay.each(function(i,e){\r\n if($(e).is(\":checked\")){\r\n \r\n }\r\n else{\r\n yearDayAllCheck = false;\r\n }\r\n });\r\n if(yearDayAllCheck){\r\n $(event).find(\".year input[type='checkbox']\").prop(\"checked\", true);\r\n $(event).attr(\"data-check\", \"true\");\r\n }\r\n else{\r\n $(event).find(\".year input[type='checkbox']\").removeAttr(\"checked\");\r\n $(event).attr(\"data-check\", \"false\");\r\n }\r\n });\r\n });\r\n\r\n //清除筛选\r\n $(\"#luckysheet-filter-initial\").click(function () {\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"filter\")){\r\n return;\r\n }\r\n\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input\").hide().find(\"input\").val();\r\n $(\"#luckysheet-filter-selected span\").data(\"type\", \"0\").data(\"type\", null).text(locale_filter.conditionNone);\r\n\r\n let redo = {};\r\n redo[\"type\"] = \"datachangeAll_filter_clear\";\r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n Store.config[\"rowhidden\"] = {};\r\n redo[\"curconfig\"] = $.extend(true, {}, Store.config);\r\n\r\n redo[\"filter_save\"] = $.extend(true, {}, Store.luckysheet_filter_save);\r\n\r\n let optiongroups = [];\r\n $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").each(function () {\r\n let $t = $(this);\r\n\r\n let optionstate = $t.hasClass(\"luckysheet-filter-options-active\");\r\n let rowhidden = json.parseJsonParm($t.data(\"rowhidden\"));\r\n let caljs = json.parseJsonParm($t.data(\"caljs\"));\r\n\r\n optiongroups.push({\r\n \"optionstate\":optionstate,\r\n \"rowhidden\": rowhidden, \r\n \"caljs\":caljs, \r\n \"str\": $t.data(\"str\"),\r\n \"edr\": $t.data(\"edr\"),\r\n \"cindex\": $t.data(\"cindex\"),\r\n \"stc\": $t.data(\"stc\"),\r\n \"edc\": $t.data(\"edc\")\r\n });\r\n });\r\n redo[\"optiongroups\"] = optiongroups;\r\n\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n\r\n $('#luckysheet-filter-selected-sheet' + Store.currentSheetIndex + ', #luckysheet-filter-options-sheet' + Store.currentSheetIndex).remove();\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n\r\n //清除筛选发送给后台\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].filter = null;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].filter_select = null;\r\n\r\n server.saveParam(\"fsc\", Store.currentSheetIndex, null);\r\n\r\n //config\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, {}, { \"k\": \"rowhidden\" });\r\n\r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n });\r\n\r\n //按照值进行筛选\r\n $(\"#luckysheet-filter-byvalue-input\").on('input propertychange', function () {\r\n let v = $(this).val().toString();\r\n $(\"#luckysheet-filter-byvalue-select .ListBox .luckysheet-mousedown-cancel\").show();\r\n \r\n if(v != \"\"){\r\n $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']\").each(function(i, e){\r\n if($(e).closest(\".day\").length > 0){\r\n let day = $(e).siblings(\"label\").text().toString();\r\n let month = $(e).closest(\".monthBox\").find(\".month label\").text().toString();\r\n let year = $(e).closest(\".yearBox\").find(\".year label\").text().toString();\r\n let itemV = year + \"-\" + month + \"-\" + day;\r\n\r\n if(itemV.indexOf(v) == -1){\r\n $(e).closest(\".day\").hide();\r\n \r\n //天 对应的 月份\r\n let $monthDay = $(e).closest(\".dayList\").find(\".day:visible\");\r\n if($monthDay.length == 0){\r\n $(e).closest(\".monthBox\").find(\".month\").hide();\r\n }\r\n\r\n //天 对应的 年份\r\n let $yearDay = $(e).closest(\".monthList\").find(\".day:visible\");\r\n if($yearDay.length == 0){\r\n $(e).closest(\".yearBox\").find(\".year\").hide();\r\n }\r\n }\r\n }\r\n\r\n if($(e).closest(\".textBox\").length > 0){\r\n let itemV = $(e).siblings(\"label\").text().toString();\r\n \r\n if(itemV.indexOf(v) == -1){\r\n $(e).parents(\".textBox\").hide();\r\n }\r\n }\r\n });\r\n }\r\n });\r\n\r\n //筛选取消\r\n $(\"#luckysheet-filter-cancel\").click(function () {\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n });\r\n\r\n //筛选 确认\r\n $(\"#luckysheet-filter-confirm\").click(function () {\r\n let $menu = $(\"#luckysheet-filter-menu\");\r\n let st_r = $menu.data(\"str\"), \r\n ed_r = $menu.data(\"edr\"), \r\n cindex = $menu.data(\"cindex\"), \r\n st_c = $menu.data(\"stc\"), \r\n ed_c = $menu.data(\"edc\");\r\n\r\n let rowhiddenother = {}; //其它筛选列的隐藏行\r\n $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").not($(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").eq(cindex - st_c).get(0)).each(function () {\r\n let $t = $(this), rh = $t.data(\"rowhidden\");\r\n\r\n if (rh == \"\") {\r\n return true;\r\n }\r\n\r\n rh = JSON.parse(rh.replace(/\\'/g, '\"'));\r\n \r\n for (let r in rh) {\r\n rowhiddenother[r] = 0;\r\n }\r\n });\r\n\r\n let filterdata = {};\r\n let rowhidden = {};\r\n let caljs = {};\r\n\r\n if ($(\"#luckysheet-filter-bycondition\").next().is(\":visible\") && $(\"#luckysheet-filter-byvalue\").next().is(\":hidden\") && $(\"#luckysheet-filter-selected span\").data(\"value\") != \"null\") {\r\n let $t = $(\"#luckysheet-filter-selected span\");\r\n let type = $t.data(\"type\"), value = $t.data(\"value\");\r\n\r\n caljs[\"value\"] = value;\r\n caljs[\"text\"] = $t.text();\r\n\r\n if (type == \"0\") {\r\n caljs[\"type\"] = \"0\";\r\n }\r\n else if (type == \"2\") {\r\n let $input = $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input2 input\");\r\n caljs[\"type\"] = \"2\";\r\n caljs[\"value1\"] = $input.eq(0).val();\r\n caljs[\"value2\"] = $input.eq(1).val();\r\n }\r\n else {\r\n caljs[\"type\"] = \"1\";\r\n caljs[\"value1\"] = $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input\").eq(0).find(\"input\").val();\r\n }\r\n\r\n for (let r = st_r + 1; r <= ed_r; r++) {\r\n if(r in rowhiddenother){\r\n continue;\r\n }\r\n\r\n if(Store.flowdata[r] == null){\r\n continue;\r\n }\r\n\r\n let cell = Store.flowdata[r][cindex];\r\n \r\n if (value == \"cellnull\") { //单元格为空\r\n if(cell != null && !isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"cellnonull\") { //单元格有数据\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"textinclude\") { //文本包含 \r\n let value1 = caljs[\"value1\"];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(cell.m.indexOf(value1) == -1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textnotinclude\") { //文本不包含\r\n let value1 = caljs[\"value1\"];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n\r\n }\r\n else{\r\n if(cell.m.indexOf(value1) > -1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textstart\") { //文本开头为\r\n let value1 = caljs[\"value1\"], valuelen = value1.length;\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(cell.m.substr(0, valuelen) != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textend\") { //文本结尾为\r\n let value1 = caljs[\"value1\"], valuelen = value1.length;\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(valuelen > cell.m.length || cell.m.substr(cell.m.length - valuelen, valuelen) != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textequal\") { //文本等于\r\n let value1 = caljs[\"value1\"];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(cell.m != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"dateequal\") { //日期等于\r\n let value1 = genarate(caljs[\"value1\"])[2];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n if(parseInt(cell.v) != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"datelessthan\") { //日期早于\r\n let value1 = genarate(caljs[\"value1\"])[2];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n if(parseInt(cell.v) >= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"datemorethan\") { //日期晚于\r\n let value1 = genarate(caljs[\"value1\"])[2];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n if(parseInt(cell.v) <= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"morethan\") { //大于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v <= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"moreequalthan\") { //大于等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v < value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"lessthan\") { //小于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v >= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"lessequalthan\") { //小于等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v > value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"equal\") { //等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"noequal\") { //不等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v == value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"include\") { //介于\r\n let value1 = parseFloat(caljs[\"value1\"]), value2 = parseFloat(caljs[\"value2\"]);\r\n\r\n let min, max;\r\n if(value1 < value2){\r\n min = value1;\r\n max = value2;\r\n }\r\n else{\r\n max = value1;\r\n min = value2; \r\n }\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v < min || cell.v > max){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"noinclude\") { //不在其中\r\n let value1 = parseFloat(caljs[\"value1\"]), value2 = parseFloat(caljs[\"value2\"]);\r\n\r\n let min, max;\r\n if(value1 < value2){\r\n min = value1;\r\n max = value2;\r\n }\r\n else{\r\n max = value1;\r\n min = value2; \r\n }\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v >= min && cell.v <= max){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']\").each(function(i, e){\r\n if($(e).is(\":visible\") && $(e).is(\":checked\")){\r\n return true;\r\n }\r\n\r\n if($(e).closest(\".day\").length > 0){\r\n let day = $(e).siblings(\"label\").text();\r\n if(Number(day) < 10){\r\n day = \"0\" + Number(day);\r\n }\r\n\r\n let month = $(e).closest(\".monthBox\").find(\".month label\").text().replace(locale_filter.filiterMonthText, \"\");\r\n if(Number(month) < 10){\r\n month = \"0\" + Number(month);\r\n }\r\n\r\n let year = $(e).closest(\".yearBox\").find(\".year label\").text().replace(locale_filter.filiterYearText, \"\");\r\n\r\n let itemV = locale_filter.filterDateFormatTip +\"#$$$#\" + year + \"-\" + month + \"-\" + day;\r\n\r\n filterdata[itemV] = \"1\";\r\n }\r\n\r\n if($(e).closest(\".textBox\").length > 0){\r\n let itemV = $(e).closest(\".textBox\").data(\"filter\");\r\n\r\n filterdata[itemV] = \"1\";\r\n }\r\n });\r\n \r\n for (let r = st_r + 1; r <= ed_r; r++) {\r\n if(r in rowhiddenother){\r\n continue;\r\n }\r\n\r\n if(Store.flowdata[r] == null){\r\n continue;\r\n }\r\n\r\n let cell = Store.flowdata[r][cindex];\r\n\r\n let value;\r\n if(cell == null || isRealNull(cell.v)){\r\n value = \"null#$$$#null\";\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n let fmt = update(\"YYYY-MM-DD\", cell.v);\r\n value = locale_filter.filterDateFormatTip +\"#$$$#\" + fmt;\r\n }\r\n else{\r\n value = cell.v + \"#$$$#\" + cell.m;\r\n }\r\n\r\n if(value in filterdata){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n\r\n let $top = $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").eq(cindex - st_c);\r\n\r\n let optionstate = $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']:visible:checked\").length < $(\"#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']:visible\").length || $(\"#luckysheet-filter-byvalue-input\").val().length > 0 || ($(\"#luckysheet-filter-bycondition\").next().is(\":visible\") && $(\"#luckysheet-filter-byvalue\").next().is(\":hidden\") && $(\"#luckysheet-filter-selected span\").data(\"value\") != \"null\");\r\n\r\n let rowhiddenall = $.extend(true, rowhiddenother, rowhidden), \r\n rowhidenPre = json.parseJsonParm($top.data(\"rowhidden\"));\r\n\r\n labelFilterOptionState($top, optionstate, rowhidden, caljs, true, st_r, ed_r, cindex, st_c, ed_c);\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n cfg[\"rowhidden\"] = rowhiddenall;\r\n\r\n //保存撤销\r\n if(Store.clearjfundo){\r\n let redo = {};\r\n redo[\"type\"] = \"datachangeAll_filter\";\r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = cfg;\r\n\r\n redo[\"optionstate\"] = optionstate;\r\n redo[\"optionsindex\"] = cindex - st_c;\r\n\r\n redo[\"rowhidden\"] = $.extend(true, {}, rowhidden);\r\n redo[\"rowhidenPre\"] = $.extend(true, {}, rowhidenPre);\r\n\r\n if (caljs != null) {\r\n redo[\"caljs\"] = caljs;\r\n }\r\n\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n //config\r\n Store.config = cfg;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, cfg[\"rowhidden\"], { \"k\": \"rowhidden\" });\r\n\r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n cleargridelement();\r\n });\r\n}\r\n\r\nexport {\r\n labelFilterOptionState,\r\n orderbydatafiler,\r\n createFilter,\r\n createFilterOptions,\r\n initialFilterHandler\r\n}","import { mouseposition } from '../global/location';\r\nimport server from './server';\r\nimport luckysheetsizeauto from './resize';\r\nimport { modelHTML } from './constant';\r\nimport {checkProtectionAuthorityNormal} from './protection';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { setluckysheet_scroll_status } from '../methods/set';\r\nimport { replaceHtml } from '../utils/util';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\nconst imageCtrl = {\r\n imgItem: {\r\n type: '3', //1移动并调整单元格大小 2移动并且不调整单元格的大小 3不要移动单元格并调整其大小\r\n src: '', //图片url\r\n originWidth: null, //图片原始宽度\r\n originHeight: null, //图片原始高度\r\n default: {\r\n width: null, //图片 宽度\r\n height: null, //图片 高度\r\n left: null, //图片离表格左边的 位置\r\n top: null, //图片离表格顶部的 位置\r\n },\r\n crop: {\r\n width: null, //图片裁剪后 宽度\r\n height: null, //图片裁剪后 高度\r\n offsetLeft: 0, //图片裁剪后离未裁剪时 左边的位移\r\n offsetTop: 0, //图片裁剪后离未裁剪时 顶部的位移\r\n },\r\n isFixedPos: false, //固定位置\r\n fixedLeft: null, //固定位置 左位移\r\n fixedTop: null, //固定位置 右位移\r\n border: {\r\n width: 0, //边框宽度\r\n radius: 0, //边框半径\r\n style: 'solid', //边框类型\r\n color: '#000', //边框颜色\r\n }\r\n },\r\n images: null,\r\n currentImgId: null,\r\n currentWinW: null,\r\n currentWinH: null,\r\n resize: null, \r\n resizeXY: null,\r\n move: false,\r\n moveXY: null,\r\n cropChange: null, \r\n cropChangeXY: null,\r\n cropChangeObj: null,\r\n copyImgItemObj: null,\r\n inserImg: function(src){\r\n let _this = this;\r\n \r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rowIndex = last.row_focus || 0;\r\n let colIndex = last.column_focus || 0;\r\n let left = colIndex == 0 ? 0 : Store.visibledatacolumn[colIndex - 1];\r\n let top = rowIndex == 0 ? 0 : Store.visibledatarow[rowIndex - 1];\r\n\r\n let image = new Image();\r\n image.onload = function(){\r\n let width = image.width,\r\n height = image.height;\r\n\r\n let img = {\r\n src: src,\r\n left: left,\r\n top: top,\r\n originWidth: width,\r\n originHeight: height\r\n }\r\n\r\n _this.addImgItem(img);\r\n }\r\n image.src = src;\r\n },\r\n generateRandomId: function(prefix) {\r\n if(prefix == null){\r\n prefix = \"img\";\r\n }\r\n\r\n let userAgent = window.navigator.userAgent.replace(/[^a-zA-Z0-9]/g, \"\").split(\"\");\r\n\r\n let mid = \"\";\r\n\r\n for(let i = 0; i < 12; i++){\r\n mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))];\r\n }\r\n\r\n let time = new Date().getTime();\r\n\r\n return prefix + \"_\" + mid + \"_\" + time;\r\n },\r\n modelHtml: function(id, imgItem) {\r\n let _this = this;\r\n\r\n let src = imgItem.src;\r\n let imgItemParam = _this.getImgItemParam(imgItem);\r\n\r\n let width = imgItemParam.width * Store.zoomRatio;\r\n let height = imgItemParam.height * Store.zoomRatio;\r\n let left = imgItemParam.left * Store.zoomRatio;\r\n let top = imgItemParam.top * Store.zoomRatio;\r\n let position = imgItemParam.position;\r\n\r\n let borderWidth = imgItem.border.width;\r\n\r\n return `
\r\n
\r\n \r\n
\r\n
\r\n
`;\r\n },\r\n getSliderHtml: function() {\r\n let imageText = locale().imageText;\r\n\r\n return `
\r\n
\r\n ${imageText.imageSetting}\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
${imageText.conventional}
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
${imageText.border}
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
`;\r\n },\r\n sliderHtmlShow: function() {\r\n let _this = this;\r\n\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").remove();\r\n\r\n let sliderHtml = _this.getSliderHtml();\r\n $(\"body\").append(sliderHtml);\r\n luckysheetsizeauto();\r\n\r\n let imgItem = _this.images[_this.currentImgId];\r\n\r\n //类型\r\n let type = imgItem.type;\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl #imgItemType\" + type).prop(\"checked\", true);\r\n\r\n //固定位置\r\n let isFixedPos = imgItem.isFixedPos;\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl #imgItemIsFixedPos\").prop(\"checked\", isFixedPos);\r\n\r\n //边框宽度\r\n let border = imgItem.border;\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl #imgItemBorderWidth\").val(border.width);\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl #imgItemBorderRadius\").val(border.radius);\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl #imgItemBorderStyle\").val(border.style);\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl #imgItemBorderColor span\").css(\"background-color\", border.color).attr(\"title\", border.color);\r\n \r\n _this.init();\r\n },\r\n colorSelectDialog: function(currenColor){\r\n const _locale = locale();\r\n const locale_button = _locale.button;\r\n const locale_toolbar = _locale.toolbar;\r\n const locale_imageCtrl = _locale.imageCtrl;\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-imageCtrl-colorSelect-dialog\").remove();\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-imageCtrl-colorSelect-dialog\", \r\n \"addclass\": \"luckysheet-imageCtrl-colorSelect-dialog\", \r\n \"title\": locale_imageCtrl.borderTile, \r\n \"content\": `
\r\n ${locale_imageCtrl.borderCur}:\r\n
\r\n
`, \r\n \"botton\": `\r\n `, \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-imageCtrl-colorSelect-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-imageCtrl-colorSelect-dialog\").css({ \r\n \"left\": (winw + scrollLeft - myw) / 2, \r\n \"top\": (winh + scrollTop - myh) / 3 \r\n }).show();\r\n \r\n //初始化选择颜色插件\r\n $(\"#luckysheet-imageCtrl-colorSelect-dialog\").find(\".colorshowbox\").spectrum({\r\n showPalette: true,\r\n showPaletteOnly: true,\r\n preferredFormat: \"hex\",\r\n clickoutFiresChange: false,\r\n showInitial: true,\r\n showInput: true,\r\n flat: true,\r\n hideAfterPaletteSelect: true,\r\n showSelectionPalette: true,\r\n showButtons: false,//隐藏选择取消按钮\r\n maxPaletteSize: 8,\r\n maxSelectionSize: 8,\r\n color: currenColor,\r\n cancelText: locale_button.cancel,\r\n chooseText: locale_toolbar.confirmColor,\r\n togglePaletteMoreText: locale_toolbar.customColor,\r\n togglePaletteLessText: locale_toolbar.collapse,\r\n togglePaletteOnly: true,\r\n clearText: locale_toolbar.clearText,\r\n noColorSelectedText: locale_toolbar.noColorSelectedText,\r\n localStorageKey: \"spectrum.textcolor\" + server.gridKey,\r\n palette: [\r\n [\"#000\", \"#444\", \"#666\", \"#999\", \"#ccc\", \"#eee\", \"#f3f3f3\", \"#fff\"],\r\n [\"#f00\", \"#f90\", \"#ff0\", \"#0f0\", \"#0ff\", \"#00f\", \"#90f\", \"#f0f\"],\r\n [\"#f4cccc\", \"#fce5cd\", \"#fff2cc\", \"#d9ead3\", \"#d0e0e3\", \"#cfe2f3\", \"#d9d2e9\", \"#ead1dc\"],\r\n [\"#ea9999\", \"#f9cb9c\", \"#ffe599\", \"#b6d7a8\", \"#a2c4c9\", \"#9fc5e8\", \"#b4a7d6\", \"#d5a6bd\"],\r\n [\"#e06666\", \"#f6b26b\", \"#ffd966\", \"#93c47d\", \"#76a5af\", \"#6fa8dc\", \"#8e7cc3\", \"#c27ba0\"],\r\n [\"#c00\", \"#e69138\", \"#f1c232\", \"#6aa84f\", \"#45818e\", \"#3d85c6\", \"#674ea7\", \"#a64d79\"],\r\n [\"#900\", \"#b45f06\", \"#bf9000\", \"#38761d\", \"#134f5c\", \"#0b5394\", \"#351c75\", \"#741b47\"],\r\n [\"#600\", \"#783f04\", \"#7f6000\", \"#274e13\", \"#0c343d\", \"#073763\", \"#20124d\", \"#4c1130\"]\r\n ],\r\n move: function(color){\r\n if (color != null) {\r\n color = color.toHexString();\r\n }\r\n else {\r\n color = \"#000\";\r\n }\r\n\r\n $(\"#luckysheet-imageCtrl-colorSelect-dialog .currenColor span\").css(\"background-color\", color).attr(\"title\", color);\r\n }\r\n });\r\n },\r\n init: function() {\r\n let _this = this;\r\n\r\n //关闭\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl .luckysheet-model-close-btn\").click(function () {\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").hide();\r\n luckysheetsizeauto();\r\n });\r\n\r\n //常规\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").off(\"change.radio\").on(\"change.radio\", \".radio-item input[type=radio][name=imgItemType]\", function() {\r\n _this.configChange(\"type\", this.value);\r\n })\r\n\r\n //固定位置\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").off(\"change.checkbox\").on(\"change.checkbox\", \".slider-box-checkbox input[type=checkbox]\", function() {\r\n _this.configChange(\"fixedPos\", this.checked);\r\n })\r\n\r\n //边框宽度\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").off(\"change.borderWidth\").on(\"change.borderWidth\", \"#imgItemBorderWidth\", function() {\r\n _this.configChange(\"border-width\", this.valueAsNumber);\r\n })\r\n\r\n //边框半径\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").off(\"change.borderRadius\").on(\"change.borderRadius\", \"#imgItemBorderRadius\", function() {\r\n _this.configChange(\"border-radius\", this.valueAsNumber);\r\n })\r\n\r\n //边框样式\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").off(\"change.borderStyle\").on(\"change.borderStyle\", \"#imgItemBorderStyle\", function() {\r\n _this.configChange(\"border-style\", this.value);\r\n })\r\n\r\n //边框颜色 选择\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").off(\"click.color\").on(\"click.color\", \"#imgItemBorderColor\", function() {\r\n let currenColor = $(this).find(\"span\").attr(\"title\");\r\n _this.colorSelectDialog(currenColor);\r\n })\r\n\r\n //边框选择颜色 确定 \r\n $(document).off(\"click.selectColorConfirm\").on(\"click.selectColorConfirm\", \"#luckysheet-imageCtrl-colorSelect-dialog-confirm\", function(){\r\n let $parent = $(this).parents(\"#luckysheet-imageCtrl-colorSelect-dialog\");\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $parent.hide();\r\n\r\n let currenColor = $parent.find(\".currenColor span\").attr(\"title\");\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl #imgItemBorderColor span\").css(\"background-color\", currenColor).attr(\"title\", currenColor);\r\n\r\n _this.configChange(\"border-color\", currenColor); \r\n });\r\n\r\n //image active\r\n $(\"#luckysheet-image-showBoxs\").off(\"mousedown.active\").on(\"mousedown.active\", \".luckysheet-modal-dialog-image\", function(e) {\r\n \r\n\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\",false)){\r\n return;\r\n }\r\n\r\n $(this).hide();\r\n let id = $(this).attr(\"id\");\r\n\r\n if(_this.currentImgId != null && _this.currentImgId != id){\r\n _this.cancelActiveImgItem();\r\n }\r\n\r\n _this.currentImgId = id;\r\n\r\n let item = _this.images[id];\r\n let imgItemParam = _this.getImgItemParam(item);\r\n\r\n let width = imgItemParam.width * Store.zoomRatio;\r\n let height = imgItemParam.height * Store.zoomRatio;\r\n let left = imgItemParam.left * Store.zoomRatio;\r\n let top = imgItemParam.top * Store.zoomRatio;\r\n let position = imgItemParam.position;\r\n \r\n $(\"#luckysheet-modal-dialog-activeImage\").show().css({\r\n \"width\": width,\r\n \"height\": height,\r\n \"left\": left,\r\n \"top\": top,\r\n \"position\": position\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content\").css({\r\n \"background-image\": \"url(\" + item.src + \")\",\r\n \"background-size\": item.default.width * Store.zoomRatio + \"px \" + item.default.height * Store.zoomRatio + \"px\",\r\n \"background-position\": -item.crop.offsetLeft * Store.zoomRatio + \"px \" + -item.crop.offsetTop * Store.zoomRatio + \"px\"\r\n })\r\n\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-border\").css({\r\n \"border-width\": item.border.width * Store.zoomRatio,\r\n \"border-style\": item.border.style,\r\n \"border-color\": item.border.color,\r\n \"border-radius\": item.border.radius * Store.zoomRatio,\r\n \"left\": -item.border.width * Store.zoomRatio,\r\n \"right\": -item.border.width * Store.zoomRatio,\r\n \"top\": -item.border.width * Store.zoomRatio,\r\n \"bottom\": -item.border.width * Store.zoomRatio,\r\n })\r\n\r\n _this.sliderHtmlShow();\r\n\r\n e.stopPropagation();\r\n })\r\n\r\n //image move\r\n $(\"#luckysheet-modal-dialog-activeImage\").off(\"mousedown.move\").on(\"mousedown.move\", \".luckysheet-modal-dialog-content\", function(e) {\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\",false)){\r\n return;\r\n }\r\n \r\n if(!$(\"#luckysheet-modal-dialog-slider-imageCtrl\").is(\":visible\")){\r\n _this.sliderHtmlShow();\r\n }\r\n \r\n _this.move = true;\r\n \r\n _this.currentWinW = $(\"#luckysheet-cell-main\")[0].scrollWidth;\r\n _this.currentWinH = $(\"#luckysheet-cell-main\")[0].scrollHeight;\r\n\r\n let offset = $(\"#luckysheet-modal-dialog-activeImage\").offset();\r\n\r\n _this.moveXY = [\r\n e.pageX - offset.left, \r\n e.pageY - offset.top, \r\n ];\r\n\r\n setluckysheet_scroll_status(true);\r\n\r\n e.stopPropagation();\r\n })\r\n\r\n //image resize\r\n $(\"#luckysheet-modal-dialog-activeImage\").off(\"mousedown.resize\").on(\"mousedown.resize\", \".luckysheet-modal-dialog-resize-item\", function(e) {\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\",false)){\r\n return;\r\n }\r\n \r\n _this.currentWinW = $(\"#luckysheet-cell-main\")[0].scrollWidth;\r\n _this.currentWinH = $(\"#luckysheet-cell-main\")[0].scrollHeight;\r\n\r\n _this.resize = $(this).data(\"type\");\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop(), \r\n scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let mouse = mouseposition(e.pageX, e.pageY);\r\n let x = mouse[0] + scrollLeft;\r\n let y = mouse[1] + scrollTop;\r\n\r\n let position = $(\"#luckysheet-modal-dialog-activeImage\").position();\r\n let width = $(\"#luckysheet-modal-dialog-activeImage\").width();\r\n let height = $(\"#luckysheet-modal-dialog-activeImage\").height();\r\n\r\n _this.resizeXY = [\r\n x, \r\n y, \r\n width, \r\n height, \r\n position.left + scrollLeft, \r\n position.top + scrollTop, \r\n scrollLeft, \r\n scrollTop\r\n ];\r\n\r\n setluckysheet_scroll_status(true);\r\n \r\n e.stopPropagation();\r\n })\r\n\r\n //image croppingEnter\r\n $(\"#luckysheet-modal-dialog-activeImage\").off(\"mousedown.croppingEnter\").on(\"mousedown.croppingEnter\", \".luckysheet-modal-controll-crop\", function(e) {\r\n _this.croppingEnter();\r\n e.stopPropagation();\r\n })\r\n\r\n //image croppingExit\r\n $(\"#luckysheet-modal-dialog-cropping\").off(\"mousedown.croppingExit\").on(\"mousedown.croppingExit\", \".luckysheet-modal-controll-crop\", function(e) {\r\n _this.croppingExit();\r\n e.stopPropagation();\r\n })\r\n\r\n //image crop change\r\n $(\"#luckysheet-modal-dialog-cropping\").off(\"mousedown.cropChange\").on(\"mousedown.cropChange\", \".resize-item\", function(e) {\r\n _this.cropChange = $(this).data(\"type\");\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop(), \r\n scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let mouse = mouseposition(e.pageX, e.pageY);\r\n let x = mouse[0] + scrollLeft;\r\n let y = mouse[1] + scrollTop;\r\n\r\n _this.cropChangeXY = [\r\n x, \r\n y\r\n ];\r\n\r\n setluckysheet_scroll_status(true);\r\n \r\n e.stopPropagation();\r\n })\r\n\r\n //image restore\r\n $(\"#luckysheet-image-showBoxs\").off(\"mousedown.restore\").on(\"mousedown.restore\", \".luckysheet-modal-controll-restore\", function(e) {\r\n _this.restoreImgItem();\r\n e.stopPropagation();\r\n })\r\n\r\n //image delete\r\n $(\"#luckysheet-image-showBoxs\").off(\"mousedown.delete\").on(\"mousedown.delete\", \".luckysheet-modal-controll-del\", function(e) {\r\n _this.removeImgItem();\r\n e.stopPropagation();\r\n })\r\n },\r\n configChange: function(type, value){\r\n let _this = this;\r\n\r\n let imgItem = _this.images[_this.currentImgId];\r\n\r\n switch(type){\r\n case \"type\":\r\n imgItem.type = value;\r\n break;\r\n case \"fixedPos\":\r\n imgItem.isFixedPos = value;\r\n\r\n let imgItemParam = _this.getImgItemParam(imgItem);\r\n let width = imgItemParam.width;\r\n let height = imgItemParam.height;\r\n let left = imgItemParam.left;\r\n let top = imgItemParam.top;\r\n let position = imgItemParam.position;\r\n \r\n $(\"#luckysheet-modal-dialog-activeImage\").show().css({\r\n \"width\": width,\r\n \"height\": height,\r\n \"left\": left,\r\n \"top\": top,\r\n \"position\": position\r\n });\r\n break;\r\n case \"border-width\":\r\n imgItem.border.width = value;\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-border\").css({\r\n \"border-width\": value,\r\n \"left\": -value,\r\n \"right\": -value,\r\n \"top\": -value,\r\n \"bottom\": -value\r\n });\r\n break;\r\n case \"border-radius\":\r\n imgItem.border.radius = value;\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-border\").css(\"border-radius\", value);\r\n break;\r\n case \"border-style\":\r\n imgItem.border.style = value;\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-border\").css(\"border-style\", value);\r\n break;\r\n case \"border-color\":\r\n imgItem.border.color = value;\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-border\").css(\"border-color\", value);\r\n break;\r\n }\r\n \r\n _this.ref();\r\n },\r\n getImgItemParam(imgItem){\r\n let isFixedPos = imgItem.isFixedPos;\r\n\r\n let width = imgItem.default.width,\r\n height = imgItem.default.height,\r\n left = imgItem.default.left,\r\n top = imgItem.default.top;\r\n\r\n if(imgItem.crop.width != width || imgItem.crop.height != height){\r\n width = imgItem.crop.width;\r\n height = imgItem.crop.height;\r\n left += imgItem.crop.offsetLeft;\r\n top += imgItem.crop.offsetTop;\r\n }\r\n\r\n let position = 'absolute';\r\n if(isFixedPos){\r\n position = 'fixed';\r\n left = imgItem.fixedLeft + imgItem.crop.offsetLeft;\r\n top = imgItem.fixedTop + imgItem.crop.offsetTop;\r\n }\r\n\r\n return {\r\n width: width,\r\n height: height,\r\n left: left,\r\n top: top,\r\n position: position\r\n }\r\n },\r\n cancelActiveImgItem: function(){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-modal-dialog-activeImage\").hide();\r\n $(\"#luckysheet-modal-dialog-cropping\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").hide();\r\n\r\n let imgItem = _this.images[_this.currentImgId];\r\n let imgItemParam = _this.getImgItemParam(imgItem);\r\n\r\n let width = imgItemParam.width * Store.zoomRatio;\r\n let height = imgItemParam.height * Store.zoomRatio;\r\n let left = imgItemParam.left * Store.zoomRatio;\r\n let top = imgItemParam.top * Store.zoomRatio;\r\n let position = imgItemParam.position;\r\n\r\n $(\"#\" + _this.currentImgId).show().css({\r\n \"width\": width,\r\n \"height\": height,\r\n \"left\": left,\r\n \"top\": top,\r\n \"position\": position\r\n });\r\n $(\"#\" + _this.currentImgId + \" img\").css({\r\n \"width\": imgItem.default.width * Store.zoomRatio,\r\n \"height\": imgItem.default.height * Store.zoomRatio,\r\n \"left\": -imgItem.crop.offsetLeft * Store.zoomRatio,\r\n \"top\": -imgItem.crop.offsetTop * Store.zoomRatio\r\n });\r\n $(\"#\" + _this.currentImgId + \" .luckysheet-modal-dialog-border\").css({\r\n \"border-width\": imgItem.border.width * Store.zoomRatio,\r\n \"border-style\": imgItem.border.style,\r\n \"border-color\": imgItem.border.color,\r\n \"border-radius\": imgItem.border.radius * Store.zoomRatio,\r\n \"left\": -imgItem.border.width * Store.zoomRatio,\r\n \"right\": -imgItem.border.width * Store.zoomRatio,\r\n \"top\": -imgItem.border.width * Store.zoomRatio,\r\n \"bottom\": -imgItem.border.width * Store.zoomRatio,\r\n })\r\n\r\n _this.currentImgId = null;\r\n },\r\n addImgItem: function(img) {\r\n let _this = this;\r\n\r\n let width, height;\r\n let max = 400;\r\n\r\n if(img.originHeight < img.originWidth){\r\n height = Math.round(img.originHeight * (max / img.originWidth));\r\n width = max;\r\n }\r\n else{\r\n width = Math.round(img.originWidth * (max / img.originHeight));\r\n height = max;\r\n }\r\n\r\n if(_this.images == null){\r\n _this.images = {};\r\n }\r\n\r\n let imgItem = $.extend(true, {}, _this.imgItem);\r\n imgItem.src = img.src;\r\n imgItem.originWidth = img.originWidth;\r\n imgItem.originHeight = img.originHeight;\r\n imgItem.default.width = width;\r\n imgItem.default.height = height;\r\n imgItem.default.left = img.left;\r\n imgItem.default.top = img.top;\r\n imgItem.crop.width = width;\r\n imgItem.crop.height = height;\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop(), \r\n scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n\r\n imgItem.fixedLeft = img.left - scrollLeft + Store.rowHeaderWidth;\r\n imgItem.fixedTop = img.top - scrollTop + Store.infobarHeight + Store.toolbarHeight + Store.calculatebarHeight + Store.columnHeaderHeight;\r\n\r\n let id = _this.generateRandomId();\r\n let modelHtml = _this.modelHtml(id, imgItem);\r\n\r\n $(\"#luckysheet-image-showBoxs .img-list\").append(modelHtml);\r\n\r\n _this.images[id] = imgItem;\r\n _this.ref();\r\n\r\n _this.init();\r\n },\r\n moveImgItem: function() {\r\n let _this = this;\r\n\r\n _this.move = false;\r\n\r\n let obj = $(\"#luckysheet-modal-dialog-activeImage\")[0];\r\n let item = _this.images[_this.currentImgId];\r\n\r\n if(item.isFixedPos){\r\n item.fixedLeft = obj.offsetLeft - item.crop.offsetLeft;\r\n item.fixedTop = obj.offsetTop - item.crop.offsetTop;\r\n }\r\n else{\r\n item.default.left = obj.offsetLeft - item.crop.offsetLeft;\r\n item.default.top = obj.offsetTop - item.crop.offsetTop;\r\n }\r\n\r\n _this.ref();\r\n },\r\n resizeImgItem: function() {\r\n let _this = this;\r\n\r\n _this.resize = null;\r\n\r\n let obj = $(\"#luckysheet-modal-dialog-activeImage\")[0];\r\n\r\n let item = _this.images[_this.currentImgId];\r\n let scaleX = obj.clientWidth / item.crop.width;\r\n let scaleY = obj.clientHeight / item.crop.height;\r\n\r\n item.default.width = Math.round(item.default.width * scaleX);\r\n item.default.height = Math.round(item.default.height * scaleY);\r\n\r\n item.crop.width = Math.round(item.crop.width * scaleX);\r\n item.crop.height = Math.round(item.crop.height * scaleY);\r\n item.crop.offsetLeft = Math.round(item.crop.offsetLeft * scaleX);\r\n item.crop.offsetTop = Math.round(item.crop.offsetTop * scaleY);\r\n\r\n if(item.isFixedPos){\r\n item.fixedLeft = obj.offsetLeft;\r\n item.fixedTop = obj.offsetTop;\r\n }\r\n else{\r\n item.default.left = obj.offsetLeft - item.crop.offsetLeft;\r\n item.default.top = obj.offsetTop - item.crop.offsetTop;\r\n }\r\n\r\n _this.ref();\r\n },\r\n croppingEnter: function() {\r\n let _this = this;\r\n _this.cropping = true;\r\n\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\",false)){\r\n return;\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-activeImage\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").hide();\r\n\r\n let item = _this.images[_this.currentImgId];\r\n let imgItemParam = _this.getImgItemParam(item);\r\n\r\n let width = imgItemParam.width;\r\n let height = imgItemParam.height;\r\n let left = imgItemParam.left;\r\n let top = imgItemParam.top;\r\n let position = imgItemParam.position;\r\n \r\n $(\"#luckysheet-modal-dialog-cropping\").show().css({\r\n \"width\": width,\r\n \"height\": height,\r\n \"left\": left,\r\n \"top\": top,\r\n \"position\": position\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-cropping .cropping-mask\").css({\r\n \"width\": item.default.width,\r\n \"height\": item.default.height,\r\n \"background-image\": \"url(\" + item.src + \")\",\r\n \"left\": -item.crop.offsetLeft,\r\n \"top\": -item.crop.offsetTop\r\n })\r\n\r\n $(\"#luckysheet-modal-dialog-cropping .cropping-content\").css({\r\n \"background-image\": \"url(\" + item.src + \")\",\r\n \"background-size\": item.default.width + \"px \" + item.default.height + \"px\",\r\n \"background-position\": -item.crop.offsetLeft + \"px \" + -item.crop.offsetTop + \"px\"\r\n })\r\n\r\n $(\"#luckysheet-modal-dialog-cropping .luckysheet-modal-dialog-border\").css({\r\n \"border-width\": item.border.width,\r\n \"border-style\": item.border.style,\r\n \"border-color\": item.border.color,\r\n \"border-radius\": item.border.radius,\r\n \"left\": -item.border.width,\r\n \"right\": -item.border.width,\r\n \"top\": -item.border.width,\r\n \"bottom\": -item.border.width,\r\n })\r\n },\r\n croppingExit: function() {\r\n let _this = this;\r\n _this.cropping = false;\r\n\r\n $(\"#luckysheet-modal-dialog-cropping\").hide();\r\n\r\n let item = _this.images[_this.currentImgId];\r\n let imgItemParam = _this.getImgItemParam(item);\r\n\r\n let width = imgItemParam.width;\r\n let height = imgItemParam.height;\r\n let left = imgItemParam.left;\r\n let top = imgItemParam.top;\r\n let position = imgItemParam.position;\r\n\r\n $(\"#luckysheet-modal-dialog-activeImage\").show().css({\r\n \"width\": width,\r\n \"height\": height,\r\n \"left\": left,\r\n \"top\": top,\r\n \"position\": position\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content\").css({\r\n \"background-image\": \"url(\" + item.src + \")\",\r\n \"background-size\": item.default.width + \"px \" + item.default.height + \"px\",\r\n \"background-position\": -item.crop.offsetLeft + \"px \" + -item.crop.offsetTop + \"px\"\r\n })\r\n },\r\n cropChangeImgItem: function() {\r\n let _this = this;\r\n\r\n _this.cropChange = null;\r\n\r\n let item = _this.images[_this.currentImgId];\r\n item.crop.width = _this.cropChangeObj.width;\r\n item.crop.height = _this.cropChangeObj.height;\r\n item.crop.offsetLeft = _this.cropChangeObj.offsetLeft;\r\n item.crop.offsetTop = _this.cropChangeObj.offsetTop;\r\n\r\n _this.ref();\r\n },\r\n restoreImgItem: function() {\r\n let _this = this;\r\n let imgItem = _this.images[_this.currentImgId];\r\n\r\n imgItem.default.width = imgItem.originWidth;\r\n imgItem.default.height = imgItem.originHeight;\r\n\r\n imgItem.crop.width = imgItem.originWidth;\r\n imgItem.crop.height = imgItem.originHeight;\r\n imgItem.crop.offsetLeft = 0;\r\n imgItem.crop.offsetTop = 0;\r\n\r\n let imgItemParam = _this.getImgItemParam(imgItem);\r\n\r\n let width = imgItemParam.width;\r\n let height = imgItemParam.height;\r\n let left = imgItemParam.left;\r\n let top = imgItemParam.top;\r\n let position = imgItemParam.position;\r\n \r\n $(\"#luckysheet-modal-dialog-activeImage\").show().css({\r\n \"width\": width,\r\n \"height\": height,\r\n \"left\": left,\r\n \"top\": top,\r\n \"position\": position\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content\").css({\r\n \"background-image\": \"url(\" + imgItem.src + \")\",\r\n \"background-size\": imgItem.default.width + \"px \" + imgItem.default.height + \"px\",\r\n \"background-position\": -imgItem.crop.offsetLeft + \"px \" + -imgItem.crop.offsetTop + \"px\"\r\n })\r\n\r\n _this.ref();\r\n },\r\n removeImgItem: function() {\r\n let _this = this;\r\n \r\n $(\"#luckysheet-modal-dialog-activeImage\").hide();\r\n $(\"#luckysheet-modal-dialog-cropping\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").hide();\r\n $(\"#\" + _this.currentImgId).remove();\r\n\r\n delete _this.images[_this.currentImgId];\r\n _this.currentImgId = null;\r\n\r\n _this.ref();\r\n },\r\n copyImgItem: function(e) {\r\n let _this = this;\r\n\r\n _this.copyImgItemObj = $.extend(true, {}, _this.images[_this.currentImgId]);\r\n\r\n let clipboardData = window.clipboardData; //for IE\r\n if (!clipboardData) { // for chrome\r\n clipboardData = e.originalEvent.clipboardData;\r\n }\r\n\r\n let cpdata = '
';\r\n\r\n if (!clipboardData) {\r\n let textarea = $(\"#luckysheet-copy-content\");\r\n textarea.html(cpdata);\r\n textarea.focus();\r\n textarea.select();\r\n document.execCommand(\"selectAll\");\r\n document.execCommand(\"Copy\");\r\n // 等50毫秒,keyPress事件发生了再去处理数据\r\n setTimeout(function () { \r\n $(\"#luckysheet-copy-content\").blur(); \r\n }, 10);\r\n }\r\n else {\r\n clipboardData.setData('Text', cpdata);\r\n return false;//否则设不生效\r\n }\r\n },\r\n pasteImgItem: function() {\r\n let _this = this;\r\n\r\n let rowIndex = Store.luckysheet_select_save[0].row_focus || 0;\r\n let colIndex = Store.luckysheet_select_save[0].column_focus || 0;\r\n let left = colIndex == 0 ? 0 : Store.visibledatacolumn[colIndex - 1];\r\n let top = rowIndex == 0 ? 0 : Store.visibledatarow[rowIndex - 1];\r\n\r\n let img = $.extend(true, {}, _this.copyImgItemObj);\r\n \r\n img.default.left = left - img.crop.offsetLeft;\r\n img.default.top = top - img.crop.offsetTop;\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop(), \r\n scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n\r\n img.fixedLeft = img.default.left - scrollLeft + Store.rowHeaderWidth;\r\n img.fixedTop = img.default.top - scrollTop + Store.infobarHeight + Store.toolbarHeight + Store.calculatebarHeight + Store.columnHeaderHeight;\r\n\r\n let id = _this.generateRandomId();\r\n let modelHtml = _this.modelHtml(id, img);\r\n\r\n $(\"#luckysheet-image-showBoxs .img-list\").append(modelHtml);\r\n\r\n _this.images[id] = img;\r\n _this.ref();\r\n\r\n _this.init();\r\n },\r\n allImagesShow: function() {\r\n let _this = this;\r\n \r\n $(\"#luckysheet-modal-dialog-activeImage\").hide();\r\n $(\"#luckysheet-modal-dialog-cropping\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").hide();\r\n $(\"#luckysheet-image-showBoxs .img-list\").empty();\r\n\r\n if(_this.images == null){\r\n return;\r\n }\r\n\r\n for(let imgId in _this.images){\r\n let imgItem = _this.images[imgId];\r\n let modelHtml = _this.modelHtml(imgId, imgItem);\r\n $(\"#luckysheet-image-showBoxs .img-list\").append(modelHtml);\r\n }\r\n },\r\n moveChangeSize: function(rc, index, size) {\r\n let _this = this;\r\n let images = $.extend(true, {}, _this.images);\r\n\r\n if(rc == \"row\"){\r\n let row = Store.visibledatarow[index], \r\n row_pre = index - 1 == -1 ? 0 : Store.visibledatarow[index - 1];\r\n let changeSize = size - (row - row_pre - 1);\r\n \r\n for(let imgId in images){\r\n let imgItem = images[imgId];\r\n let imgItemParam = _this.getImgItemParam(imgItem);\r\n let type = imgItem.type;\r\n\r\n if(type == \"1\"){\r\n if(imgItemParam.top >= row){\r\n imgItem.default.top = imgItemParam.top + changeSize - imgItem.crop.offsetTop;\r\n }\r\n else{\r\n if(imgItemParam.top + imgItemParam.height >= row-2){\r\n if(imgItemParam.top < row + changeSize){\r\n let scaleY = (imgItemParam.height + changeSize) / imgItemParam.height;\r\n imgItem.default.height = Math.round(imgItem.default.height * scaleY);\r\n imgItem.crop.height = Math.round(imgItem.crop.height * scaleY);\r\n imgItem.crop.offsetTop = Math.round(imgItem.crop.offsetTop * scaleY);\r\n }\r\n else{\r\n let scaleY = (imgItemParam.top + imgItemParam.height - row) / imgItemParam.height;\r\n imgItem.default.height = Math.round(imgItem.default.height * scaleY);\r\n imgItem.crop.height = Math.round(imgItem.crop.height * scaleY);\r\n imgItem.crop.offsetTop = Math.round(imgItem.crop.offsetTop * scaleY);\r\n imgItem.default.top = row + changeSize - imgItem.crop.offsetTop;\r\n }\r\n }\r\n else{\r\n if(imgItemParam.top > row + changeSize){\r\n let scaleY = 1 / imgItemParam.height;\r\n imgItem.default.height = Math.round(imgItem.default.height * scaleY);\r\n imgItem.crop.height = Math.round(imgItem.crop.height * scaleY);\r\n imgItem.crop.offsetTop = Math.round(imgItem.crop.offsetTop * scaleY);\r\n imgItem.default.top = row + changeSize - imgItem.crop.offsetTop;\r\n }\r\n else if(imgItemParam.top + imgItemParam.height > row + changeSize){\r\n let scaleY = (row + changeSize - imgItemParam.top) / imgItemParam.height;\r\n imgItem.default.height = Math.round(imgItem.default.height * scaleY);\r\n imgItem.crop.height = Math.round(imgItem.crop.height * scaleY);\r\n imgItem.crop.offsetTop = Math.round(imgItem.crop.offsetTop * scaleY);\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"2\"){\r\n if(imgItemParam.top >= row){\r\n imgItem.default.top = imgItemParam.top + changeSize - imgItem.crop.offsetTop;\r\n }\r\n else if(imgItemParam.top > row + changeSize){\r\n imgItem.default.top = row + changeSize - imgItem.crop.offsetTop;\r\n }\r\n }\r\n }\r\n }\r\n else if(rc == \"column\"){\r\n let col = Store.visibledatacolumn[index], \r\n col_pre = index - 1 == -1 ? 0 : Store.visibledatacolumn[index - 1];\r\n let changeSize = size - (col - col_pre - 1);\r\n\r\n for(let imgId in images){\r\n let imgItem = images[imgId];\r\n let imgItemParam = _this.getImgItemParam(imgItem);\r\n let type = imgItem.type;\r\n\r\n if(type == \"1\"){\r\n if(imgItemParam.left >= col){\r\n imgItem.default.left = imgItemParam.left + changeSize - imgItem.crop.offsetLeft;\r\n }\r\n else{\r\n if(imgItemParam.left + imgItemParam.width >= col-2){\r\n if(imgItemParam.left < col + changeSize){\r\n let scaleX = (imgItemParam.width + changeSize) / imgItemParam.width;\r\n imgItem.default.width = Math.round(imgItem.default.width * scaleX);\r\n imgItem.crop.width = Math.round(imgItem.crop.width * scaleX);\r\n imgItem.crop.offsetLeft = Math.round(imgItem.crop.offsetLeft * scaleX);\r\n }\r\n else{\r\n let scaleX = (imgItemParam.left + imgItemParam.width - col) / imgItemParam.width;\r\n imgItem.default.width = Math.round(imgItem.default.width * scaleX);\r\n imgItem.crop.width = Math.round(imgItem.crop.width * scaleX);\r\n imgItem.crop.offsetLeft = Math.round(imgItem.crop.offsetLeft * scaleX);\r\n imgItem.default.left = col + changeSize - imgItem.crop.offsetLeft;\r\n }\r\n }\r\n else{\r\n if(imgItemParam.left > col + changeSize){\r\n let scaleX = 1 / imgItemParam.width;\r\n imgItem.default.width = Math.round(imgItem.default.width * scaleX);\r\n imgItem.crop.width = Math.round(imgItem.crop.width * scaleX);\r\n imgItem.crop.offsetLeft = Math.round(imgItem.crop.offsetLeft * scaleX);\r\n imgItem.default.left = col + changeSize - imgItem.crop.offsetLeft;\r\n }\r\n else if(imgItemParam.left + imgItemParam.width > col + changeSize){\r\n let scaleX = (col + changeSize - imgItemParam.left) / imgItemParam.width;\r\n imgItem.default.width = Math.round(imgItem.default.width * scaleX);\r\n imgItem.crop.width = Math.round(imgItem.crop.width * scaleX);\r\n imgItem.crop.offsetLeft = Math.round(imgItem.crop.offsetLeft * scaleX);\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"2\"){\r\n if(imgItemParam.left >= col){\r\n imgItem.default.left = imgItemParam.left + changeSize - imgItem.crop.offsetLeft;\r\n }\r\n else if(imgItemParam.left > col + changeSize){\r\n imgItem.default.left = col + changeSize - imgItem.crop.offsetLeft;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return images;\r\n },\r\n ref: function() {\r\n let _this = this;\r\n\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n let images = _this.images;\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n Store.jfredo.push({\r\n \"type\": \"imageCtrl\",\r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"images\": file.images == null ? null : $.extend(true, {}, file.images),\r\n \"curImages\": images\r\n });\r\n }\r\n\r\n file.images = $.extend(true, {}, images);\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.images, { \"k\": \"images\" });\r\n },\r\n}\r\n\r\nexport default imageCtrl;","import { replaceHtml } from '../utils/util';\r\nimport formula from '../global/formula';\r\nimport { isRealNum, isRealNull } from '../global/validate';\r\nimport { isdatetime, diff } from '../global/datecontroll';\r\nimport { luckysheetrefreshgrid } from '../global/refresh';\r\nimport tooltip from '../global/tooltip';\r\nimport { setcellvalue } from '../global/setdata';\r\nimport { getcellvalue } from '../global/getdata';\r\nimport editor from '../global/editor';\r\nimport { modelHTML } from './constant';\r\nimport { selectionCopyShow } from './select';\r\nimport server from './server';\r\nimport menuButton from './menuButton';\r\nimport sheetmanage from './sheetmanage';\r\nimport { getSheetIndex, getRangetxt } from '../methods/get';\r\nimport locale from '../locale/locale';\r\nimport Store from '../store';\r\n\r\nconst dataVerificationCtrl = {\r\n defaultItem: {\r\n type: 'dropdown', //类型\r\n type2: null, //\r\n value1: '', //\r\n value2: '', //\r\n checked: false,\r\n remote: false, //自动远程获取选项\r\n prohibitInput: false, //输入数据无效时禁止输入\r\n hintShow: false, //选中单元格时显示提示语\r\n hintText: '', //\r\n },\r\n curItem: null,\r\n dataVerification: null,\r\n selectRange: [],\r\n selectStatus: false,\r\n optionLabel: {\r\n 'number': '数值',\r\n 'number_integer': '整数',\r\n 'number_decimal': '小数',\r\n 'bw': '介于',\r\n 'nb': '不介于',\r\n 'eq': '等于',\r\n 'ne': '不等于',\r\n 'gt': '大于',\r\n 'lt': '小于',\r\n 'gte': '大于等于',\r\n 'lte': '小于等于',\r\n 'include': '包括',\r\n 'exclude': '不包括',\r\n 'equal': '等于',\r\n 'bf': '早于',\r\n 'nbf': '不早于',\r\n 'af': '晚于',\r\n 'naf': '不晚于',\r\n 'card': '身份证号码',\r\n 'phone': '手机号'\r\n },\r\n optionLabel_en: {\r\n 'number': 'numeric',\r\n 'number_integer': 'integer',\r\n 'number_decimal': 'decimal',\r\n 'bw': 'between',\r\n 'nb': 'not between',\r\n 'eq': 'equal to',\r\n 'ne': 'not equal to',\r\n 'gt': 'greater',\r\n 'lt': 'less than',\r\n 'gte': 'greater or equal to',\r\n 'lte': 'less than or equal to',\r\n 'include': 'include',\r\n 'exclude': 'not include',\r\n 'equal': 'equal to',\r\n 'bf': 'earlier than',\r\n 'nbf': 'not earlier than',\r\n 'af': 'later than',\r\n 'naf': 'not later than',\r\n 'card': 'identification number',\r\n 'phone': 'phone number'\r\n },\r\n createDialog: function(){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const dvText = _locale.dataVerification;\r\n const toolbarText = _locale.toolbar;\r\n const buttonText = _locale.button;\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-dataVerification-dialog\").remove();\r\n\r\n let content = `
\r\n
\r\n
${dvText.cellRange}
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
${dvText.verificationCondition}
\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n ${dvText.selected} ——\r\n \r\n
\r\n
\r\n ${dvText.notSelected} ——\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n -\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n -\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n -\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
`;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-dataVerification-dialog\", \r\n \"addclass\": \"luckysheet-dataVerification-dialog\", \r\n \"title\": toolbarText.dataVerification, \r\n \"content\": content, \r\n \"botton\": `\r\n \r\n `, \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-dataVerification-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 350).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), \r\n winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), \r\n scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-dataVerification-dialog\").css({ \r\n \"left\": (winw + scrollLeft - myw) / 2, \r\n \"top\": (winh + scrollTop - myh) / 3 \r\n }).show();\r\n\r\n _this.dataAllocation();\r\n },\r\n init: function(){\r\n let _this = this;\r\n\r\n const dvText = locale().dataVerification; \r\n\r\n //单元格数据验证 类型是 下拉列表\r\n $(document).off(\"click.dropdownBtn\").on(\"click.dropdownBtn\", \"#luckysheet-dataVerification-dropdown-btn\", function(e) {\r\n _this.dropdownListShow();\r\n e.stopPropagation();\r\n });\r\n $(document).off(\"click.dropdownListItem\").on(\"click.dropdownListItem\", \"#luckysheet-dataVerification-dropdown-List .dropdown-List-item\", function(e) {\r\n $(\"#luckysheet-dataVerification-dropdown-List\").hide();\r\n \r\n let value = e.target.innerText;\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rowIndex = last.row_focus;\r\n let colIndex = last.column_focus;\r\n\r\n $(\"#luckysheet-rich-text-editor\").text(value);\r\n formula.updatecell(rowIndex, colIndex);\r\n\r\n e.stopPropagation();\r\n });\r\n\r\n //单元格范围\r\n $(document).off(\"click.dvRange\").on(\"click.dvRange\", \"#data-verification-range .fa-table\", function(e) {\r\n $(\"#luckysheet-dataVerification-dialog\").hide();\r\n\r\n let dataSource = \"0\";\r\n let txt = $(this).siblings(\"input\").val().trim(); \r\n\r\n _this.rangeDialog(dataSource, txt);\r\n\r\n _this.selectRange = [];\r\n\r\n let range = _this.getRangeByTxt(txt);\r\n\r\n formula.rangetosheet = Store.currentSheetIndex;\r\n\r\n if(range[0].sheetIndex != Store.currentSheetIndex){\r\n sheetmanage.changeSheetExec(range[0].sheetIndex);\r\n }\r\n\r\n if(range.length > 0){\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n _this.selectRange.push({ \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1, \r\n \"left_move\": col_pre, \r\n \"width_move\": col - col_pre - 1, \r\n \"top_move\": row_pre, \r\n \"height_move\": row - row_pre - 1, \r\n \"row\": [r1, r2], \r\n \"column\": [c1, c2], \r\n \"row_focus\": r1, \r\n \"column_focus\": c1 \r\n });\r\n }\r\n }\r\n \r\n selectionCopyShow(_this.selectRange);\r\n }); \r\n $(document).off(\"click.dvRange2\").on(\"click.dvRange2\", \"#luckysheet-dataVerification-dialog .show-box-item-dropdown .range .fa-table\", function(e) {\r\n $(\"#luckysheet-dataVerification-dialog\").hide();\r\n\r\n let dataSource = \"1\";\r\n let txt = $(this).siblings(\"input\").val().trim(); \r\n\r\n _this.rangeDialog(dataSource, txt);\r\n\r\n _this.selectRange = [];\r\n\r\n let range = _this.getRangeByTxt(txt);\r\n\r\n formula.rangetosheet = Store.currentSheetIndex;\r\n\r\n if(range[0].sheetIndex != Store.currentSheetIndex){\r\n sheetmanage.changeSheetExec(range[0].sheetIndex);\r\n }\r\n\r\n if(range.length > 0){\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n _this.selectRange.push({ \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1, \r\n \"left_move\": col_pre, \r\n \"width_move\": col - col_pre - 1, \r\n \"top_move\": row_pre, \r\n \"height_move\": row - row_pre - 1, \r\n \"row\": [r1, r2], \r\n \"column\": [c1, c2], \r\n \"row_focus\": r1, \r\n \"column_focus\": c1 \r\n });\r\n }\r\n }\r\n \r\n selectionCopyShow(_this.selectRange);\r\n });\r\n $(document).off(\"click.dvRangeConfirm\").on(\"click.dvRangeConfirm\", \"#luckysheet-dataVerificationRange-dialog-confirm\", function(e) {\r\n let dataSource = $(this).attr(\"data-source\");\r\n let txt = $(this).parents(\"#luckysheet-dataVerificationRange-dialog\").find(\"input\").val();\r\n\r\n if(_this.getRangeByTxt(txt).length > 1){\r\n tooltip.info('', '不能对多重选择区域执行此操作,请选择单个区域,然后再试');\r\n return;\r\n }\r\n\r\n if(dataSource == '0'){\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-range input\").val(txt);\r\n }\r\n else if(dataSource == '1'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-dropdown .range input\").val(txt);\r\n }\r\n \r\n $(\"#luckysheet-dataVerificationRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-dataVerification-dialog\").show();\r\n\r\n if(formula.rangetosheet != null && formula.rangetosheet != Store.currentSheetIndex){\r\n sheetmanage.changeSheetExec(formula.rangetosheet);\r\n formula.rangetosheet = null;\r\n }\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n $(document).off(\"click.dvRangeClose\").on(\"click.dvRangeClose\", \"#luckysheet-dataVerificationRange-dialog-close\", function(e) {\r\n $(\"#luckysheet-dataVerificationRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-dataVerification-dialog\").show();\r\n\r\n if(formula.rangetosheet != null && formula.rangetosheet != Store.currentSheetIndex){\r\n sheetmanage.changeSheetExec(formula.rangetosheet);\r\n formula.rangetosheet = null;\r\n }\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n $(document).on(\"click\", \"#luckysheet-dataVerificationRange-dialog .luckysheet-modal-dialog-title-close\", function(e) {\r\n $(\"#luckysheet-dataVerificationRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-dataVerification-dialog\").show();\r\n\r\n if(formula.rangetosheet != null && formula.rangetosheet != Store.currentSheetIndex){\r\n sheetmanage.changeSheetExec(formula.rangetosheet);\r\n formula.rangetosheet = null;\r\n }\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n })\r\n\r\n //验证条件 下拉框\r\n $(document).off(\"change.typeSelect\").on(\"change.typeSelect\", \"#data-verification-type-select\", function(e) {\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item\").hide();\r\n\r\n let value = this.value;\r\n let item = _this.curItem;\r\n\r\n if(value == 'dropdown'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item-dropdown\").show();\r\n\r\n let value1 = \"\";\r\n\r\n if(value == item.type){\r\n value1 = item.value1;\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-dropdown .data-verification-value1\").val(value1);\r\n }\r\n else if(value == 'checkbox'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item-checkbox\").show();\r\n\r\n let value1 = \"\";\r\n let value2 = \"\";\r\n\r\n if(value == item.type){\r\n value1 = item.value1;\r\n value2 = item.value2;\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value1\").val(value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value2\").val(value2);\r\n }\r\n else if(value == 'number' || value == 'number_integer' || value == 'number_decimal'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number\").show();\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input\").hide();\r\n\r\n let type2 = \"bw\";\r\n let value1 = \"\";\r\n let value2 = \"\";\r\n\r\n if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){\r\n type2 = item.type2;\r\n value1 = item.value1;\r\n value2 = item.value2;\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-number-select\").val(type2);\r\n \r\n if(type2 == 'bw' || type2 == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input2\").show();\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value1\").val(value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value2\").val(value2);\r\n }\r\n else if(value == 'text_content'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-text\").show();\r\n\r\n let type2 = \"include\";\r\n let value1 = \"\";\r\n \r\n if(value == item.type){\r\n type2 = item.type2;\r\n value1 = item.value1;\r\n }\r\n \r\n $(\"#luckysheet-dataVerification-dialog #data-verification-text-select\").val(type2);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-text .data-verification-value1\").val(value1);\r\n }\r\n else if(value == 'text_length'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength\").show();\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input\").hide();\r\n\r\n let type2 = \"bw\";\r\n let value1 = \"\";\r\n let value2 = \"\";\r\n\r\n if(value == item.type){\r\n type2 = item.type2;\r\n value1 = item.value1;\r\n value2 = item.value2;\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-textLength-select\").val(type2);\r\n \r\n if(type2 == 'bw' || type2 == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input2\").show();\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value1\").val(value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value2\").val(value2);\r\n }\r\n else if(value == 'date'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date\").show();\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input\").hide();\r\n\r\n let type2 = \"bw\";\r\n let value1 = \"\";\r\n let value2 = \"\";\r\n\r\n if(value == item.type){\r\n type2 = item.type2;\r\n value1 = item.value1;\r\n value2 = item.value2;\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-date-select\").val(type2);\r\n\r\n if(type2 == 'bw' || type2 == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input2\").show();\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value1\").val(value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value2\").val(value2);\r\n }\r\n else if(value == 'validity'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item-validity\").show();\r\n\r\n let type2 = \"card\";\r\n\r\n if(value == item.type){\r\n type2 = item.type2;\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-validity-select\").val(type2);\r\n }\r\n });\r\n\r\n $(document).off(\"change.numberSelect\").on(\"change.numberSelect\", \"#data-verification-number-select\", function(e) {\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input\").hide();\r\n\r\n let value = this.value;\r\n\r\n if(value == 'bw' || value == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input2\").show();\r\n }\r\n });\r\n\r\n $(document).off(\"change.dateSelect\").on(\"change.dateSelect\", \"#data-verification-date-select\", function(e) {\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input\").hide();\r\n\r\n let value = this.value;\r\n\r\n if(value == 'bw' || value == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input2\").show();\r\n }\r\n });\r\n\r\n //选中单元格时显示提示语\r\n $(document).off(\"change.hintShow\").on(\"change.hintShow\", \"#data-verification-hint-show\", function(e) {\r\n if(this.checked){\r\n $(\"#luckysheet-dataVerification-dialog .data-verification-hint-text\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .data-verification-hint-text\").hide();\r\n }\r\n });\r\n\r\n //确认按钮\r\n $(document).off(\"click.dvSaveConfirm\").on(\"click.dvSaveConfirm\", \"#luckysheet-dataVerification-dialog-confirm\", function(e) {\r\n let rangeTxt = $(\"#luckysheet-dataVerification-dialog #data-verification-range input\").val().trim();\r\n let range = _this.getRangeByTxt(rangeTxt);\r\n\r\n if(range.length == 0){\r\n tooltip.info('', dvText.selectCellRange2);\r\n return;\r\n }\r\n\r\n let str = range[range.length - 1].row[0],\r\n edr = range[range.length - 1].row[1],\r\n stc = range[range.length - 1].column[0],\r\n edc = range[range.length - 1].column[1];\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n if(str < 0){\r\n str = 0;\r\n }\r\n\r\n if(edr > d.length - 1){\r\n edr = d.length - 1;\r\n }\r\n\r\n if(stc < 0){\r\n stc = 0;\r\n }\r\n\r\n if(edc > d[0].length - 1){\r\n edc = d[0].length - 1;\r\n }\r\n\r\n let type = $(\"#luckysheet-dataVerification-dialog #data-verification-type-select\").val();\r\n let type2 = null, value1 = \"\", value2 = \"\";\r\n\r\n if(type == 'dropdown'){\r\n value1 = $(\"#luckysheet-dataVerification-dialog .show-box-item-dropdown .data-verification-value1\").val().trim();\r\n \r\n if(value1.length == 0){\r\n tooltip.info('', dvText.tooltipInfo1);\r\n return;\r\n }\r\n }\r\n else if(type == 'checkbox'){\r\n value1 = $(\"#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value1\").val().trim();\r\n value2 = $(\"#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value2\").val().trim();\r\n \r\n if(value1.length == 0 || value2.length == 0){\r\n tooltip.info('', dvText.tooltipInfo2);\r\n return;\r\n }\r\n }\r\n else if(type == 'number' || type == 'number_integer' || type == 'number_decimal'){\r\n type2 = $(\"#luckysheet-dataVerification-dialog #data-verification-number-select\").val();\r\n value1 = $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input:visible .data-verification-value1\").val().trim();\r\n \r\n if(!isRealNum(value1)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(type2 == 'bw' || type2 == 'nb'){\r\n value2 = $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input:visible .data-verification-value2\").val().trim();\r\n \r\n if(!isRealNum(value2)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(Number(value2) < Number(value1)){\r\n tooltip.info('', dvText.tooltipInfo4);\r\n return;\r\n }\r\n }\r\n }\r\n else if(type == 'text_content'){\r\n type2 = $(\"#luckysheet-dataVerification-dialog #data-verification-text-select\").val();\r\n value1 = $(\"#luckysheet-dataVerification-dialog .show-box-item-text .data-verification-value1\").val().trim();\r\n \r\n if(value1.length == 0){\r\n tooltip.info('', dvText.tooltipInfo5);\r\n return;\r\n }\r\n }\r\n else if(type == 'text_length'){\r\n type2 = $(\"#luckysheet-dataVerification-dialog #data-verification-textLength-select\").val();\r\n value1 = $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input:visible .data-verification-value1\").val().trim();\r\n \r\n if(!isRealNum(value1)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(type2 == 'bw' || type2 == 'nb'){\r\n value2 = $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input:visible .data-verification-value2\").val().trim();\r\n \r\n if(!isRealNum(value2)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(Number(value2) < Number(value1)){\r\n tooltip.info('', dvText.tooltipInfo4);\r\n return;\r\n }\r\n }\r\n }\r\n else if(type == 'date'){\r\n type2 = $(\"#luckysheet-dataVerification-dialog #data-verification-date-select\").val();\r\n value1 = $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input:visible .data-verification-value1\").val().trim();\r\n \r\n if(!isdatetime(value1)){\r\n tooltip.info('', dvText.tooltipInfo6);\r\n return;\r\n }\r\n\r\n if(type2 == 'bw' || type2 == 'nb'){\r\n value2 = $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input:visible .data-verification-value2\").val().trim();\r\n \r\n if(!isdatetime(value2)){\r\n tooltip.info('', dvText.tooltipInfo6);\r\n return;\r\n }\r\n\r\n if(diff(value1, value2) > 0){\r\n tooltip.info('', dvText.tooltipInfo7);\r\n return;\r\n }\r\n }\r\n }\r\n else if(type == 'validity'){\r\n type2 = $(\"#luckysheet-dataVerification-dialog #data-verification-validity-select\").val();\r\n }\r\n\r\n let remote = $(\"#luckysheet-dataVerification-dialog #data-verification-remote\").is(\":checked\");\r\n let prohibitInput = $(\"#luckysheet-dataVerification-dialog #data-verification-prohibitInput\").is(\":checked\");\r\n let hintShow = $(\"#luckysheet-dataVerification-dialog #data-verification-hint-show\").is(\":checked\");\r\n let hintText = \"\";\r\n\r\n if(hintShow){\r\n hintText = $(\"#luckysheet-dataVerification-dialog .data-verification-hint-text input\").val().trim();\r\n }\r\n\r\n let item = {\r\n type: type,\r\n type2: type2, \r\n value1: value1, \r\n value2: value2, \r\n checked: false, \r\n remote: remote, \r\n prohibitInput: prohibitInput, \r\n hintShow: hintShow, \r\n hintText: hintText,\r\n }\r\n \r\n let historyDataVerification = $.extend(true, {}, _this.dataVerification);\r\n let currentDataVerification = $.extend(true, {}, _this.dataVerification);\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = stc; c <= edc; c++){\r\n currentDataVerification[r + '_' + c] = item;\r\n\r\n if(type == 'checkbox'){\r\n setcellvalue(r, c, d, item.value2);\r\n }\r\n }\r\n }\r\n\r\n if(type == 'checkbox'){\r\n _this.refOfCheckbox(historyDataVerification, currentDataVerification, Store.currentSheetIndex, d, range[range.length - 1]);\r\n }\r\n else{\r\n _this.ref(historyDataVerification, currentDataVerification, Store.currentSheetIndex);\r\n }\r\n \r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-dataVerification-dialog\").hide();\r\n });\r\n\r\n //删除验证按钮\r\n $(document).off(\"click.delete\").on(\"click.delete\", \"#luckysheet-dataVerification-dialog-delete\", function(e) {\r\n let rangeTxt = $(\"#luckysheet-dataVerification-dialog #data-verification-range input\").val().trim();\r\n let range = _this.getRangeByTxt(rangeTxt);\r\n\r\n if(range.length == 0){\r\n tooltip.info('', dvText.selectCellRange2);\r\n return;\r\n }\r\n \r\n let historyDataVerification = $.extend(true, {}, _this.dataVerification);\r\n let currentDataVerification = $.extend(true, {}, _this.dataVerification);\r\n\r\n let str = range[range.length - 1].row[0],\r\n edr = range[range.length - 1].row[1],\r\n stc = range[range.length - 1].column[0],\r\n edc = range[range.length - 1].column[1];\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = stc; c <= edc; c++){\r\n delete currentDataVerification[r + '_' + c];\r\n }\r\n }\r\n\r\n _this.ref(historyDataVerification, currentDataVerification, Store.currentSheetIndex);\r\n \r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-dataVerification-dialog\").hide();\r\n });\r\n\r\n //info提示弹框 关闭\r\n $(document).on(\"click\", \"#luckysheet-info .luckysheet-modal-dialog-title-close, #luckysheet-info .luckysheet-model-close-btn\", function(e) {\r\n $(this).parents(\"#luckysheet-info\").hide();\r\n\r\n if($(\"#luckysheet-dataVerification-dialog\").is(\":visible\")){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n }\r\n e.stopPropagation();\r\n });\r\n },\r\n dataAllocation: function(){\r\n let _this = this;\r\n\r\n //单元格范围\r\n let range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rangeTxt = getRangetxt(Store.currentSheetIndex, range, Store.currentSheetIndex);\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-range input\").val(rangeTxt);\r\n\r\n //focus单元格\r\n let rowIndex = range.row_focus || range.row[0];\r\n let colIndex = range.column_focus || range.column[0];\r\n let dataVerification = $.extend(true, {}, _this.dataVerification); \r\n let item = dataVerification[rowIndex + '_' + colIndex];\r\n\r\n if(item == null){\r\n item = $.extend(true, {}, _this.defaultItem);\r\n }\r\n\r\n _this.curItem = item;\r\n \r\n //验证条件\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-type-select\").val(item.type);\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item\").hide();\r\n\r\n if(item.type == 'dropdown'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item-dropdown\").show();\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-dropdown .data-verification-value1\").val(item.value1);\r\n }\r\n else if(item.type == 'checkbox'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item-checkbox\").show();\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value1\").val(item.value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-checkbox .data-verification-value2\").val(item.value2);\r\n }\r\n else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number\").show();\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-number-select\").val(item.type2);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input\").hide();\r\n \r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .input2\").show();\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value1\").val(item.value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-number .data-verification-value2\").val(item.value2);\r\n }\r\n else if(item.type == 'text_content'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-text\").show();\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-text-select\").val(item.type2);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-text .data-verification-value1\").val(item.value1);\r\n }\r\n else if(item.type == 'text_length'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength\").show();\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-textLength-select\").val(item.type2);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input\").hide();\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .input2\").show();\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value1\").val(item.value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-textLength .data-verification-value2\").val(item.value2);\r\n }\r\n else if(item.type == 'date'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date\").show();\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-date-select\").val(item.type2);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input\").hide();\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input1\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .input2\").show();\r\n }\r\n\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value1\").val(item.value1);\r\n $(\"#luckysheet-dataVerification-dialog .show-box-item-date .data-verification-value2\").val(item.value2);\r\n }\r\n else if(item.type == 'validity'){\r\n $(\"#luckysheet-dataVerification-dialog .show-box .show-box-item-validity\").show();\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-validity-select\").val(item.type2);\r\n }\r\n\r\n //自动远程获取选项\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-remote\").prop(\"checked\", item.remote);\r\n\r\n //输入数据无效时禁止输入\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-prohibitInput\").prop(\"checked\", item.prohibitInput);\r\n\r\n //选中单元格时显示提示语\r\n $(\"#luckysheet-dataVerification-dialog #data-verification-hint-show\").prop(\"checked\", item.hintShow);\r\n \r\n if(item.hintShow){\r\n $(\"#luckysheet-dataVerification-dialog .data-verification-hint-text\").show();\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dialog .data-verification-hint-text\").hide();\r\n }\r\n \r\n $(\"#luckysheet-dataVerification-dialog .data-verification-hint-text input\").val(item.hintText);\r\n },\r\n rangeDialog: function(dataSource, txt){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const dvText = _locale.dataVerification;\r\n const buttonText = _locale.button;\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-dataVerificationRange-dialog\").remove();\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-dataVerificationRange-dialog\", \r\n \"addclass\": \"luckysheet-dataVerificationRange-dialog\", \r\n \"title\": dvText.selectCellRange, \r\n \"content\": ``, \r\n \"botton\": `\r\n `, \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-dataVerificationRange-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-dataVerificationRange-dialog\").css({ \r\n \"left\": (winw + scrollLeft - myw) / 2, \r\n \"top\": (winh + scrollTop - myh) / 3 \r\n }).show();\r\n },\r\n getTxtByRange: function(range){\r\n if(range.length > 0){\r\n let txt = [];\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n \r\n txt.push(getRangetxt(Store.currentSheetIndex, { \"row\": [r1, r2], \"column\": [c1, c2] }, Store.currentSheetIndex));\r\n }\r\n\r\n return txt.join(\",\");\r\n }\r\n },\r\n getRangeByTxt: function(txt){\r\n let range = [];\r\n\r\n if(txt.indexOf(\",\") != -1){\r\n let arr = txt.split(\",\");\r\n for(let i = 0; i < arr.length; i++){\r\n if(formula.iscelldata(arr[i])){\r\n range.push(formula.getcellrange(arr[i]));\r\n }\r\n else{\r\n range = [];\r\n break; \r\n }\r\n }\r\n }\r\n else{\r\n if(formula.iscelldata(txt)){\r\n range.push(formula.getcellrange(txt));\r\n }\r\n }\r\n\r\n return range;\r\n },\r\n cellFocus: function(r, c, clickMode){\r\n $(\"#luckysheet-dataVerification-dropdown-btn\").hide();\r\n $(\"#luckysheet-dataVerification-showHintBox\").hide();\r\n\r\n let _this = this;\r\n\r\n if(_this.dataVerification == null || _this.dataVerification[r + '_' + c] == null){\r\n $(\"#luckysheet-dataVerification-dropdown-List\").hide();\r\n return;\r\n }\r\n\r\n let row = Store.visibledatarow[r],\r\n row_pre = r == 0 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c],\r\n col_pre = c == 0 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let item = _this.dataVerification[r + '_' + c];\r\n\r\n //单元格数据验证 类型是 复选框\r\n if(clickMode && item.type == 'checkbox'){\r\n _this.checkboxChange(r, c);\r\n return;\r\n }\r\n\r\n //单元格数据验证 类型是 下拉列表\r\n if(item.type == 'dropdown'){\r\n $(\"#luckysheet-dataVerification-dropdown-btn\").show().css({\r\n 'max-width': col - col_pre,\r\n 'max-height': row - row_pre,\r\n 'left': col - 20,\r\n 'top': row_pre + (row - row_pre - 20) / 2\r\n })\r\n\r\n if($(\"#luckysheet-dataVerification-dropdown-List\").is(\":visible\")){\r\n let dataIndex = $(\"#luckysheet-dataVerification-dropdown-List\").prop(\"data-index\");\r\n \r\n if(dataIndex != (r + '_' + c)){\r\n $(\"#luckysheet-dataVerification-dropdown-List\").hide();\r\n }\r\n }\r\n }\r\n else{\r\n $(\"#luckysheet-dataVerification-dropdown-List\").hide();\r\n }\r\n\r\n //提示语\r\n if(item.hintShow){\r\n let hintText;\r\n\r\n if(Store.lang == 'en'){\r\n hintText = 'Hint: ';\r\n }\r\n else{\r\n hintText = '提示:';\r\n }\r\n\r\n hintText += _this.getHintText(item);\r\n\r\n $(\"#luckysheet-dataVerification-showHintBox\").html(hintText).show().css({\r\n 'left': col_pre,\r\n 'top': row\r\n });\r\n\r\n return;\r\n }\r\n \r\n //数据验证未通过\r\n let cellValue = getcellvalue(r, c, null);\r\n\r\n if(isRealNull(cellValue)){\r\n return;\r\n }\r\n\r\n let validate = _this.validateCellData(cellValue, item);\r\n\r\n if(!validate){\r\n let failureText;\r\n\r\n if(Store.lang == 'en'){\r\n failureText = 'Failure: ';\r\n }\r\n else{\r\n failureText = '失效:';\r\n }\r\n\r\n failureText += _this.getFailureText(item);\r\n\r\n $(\"#luckysheet-dataVerification-showHintBox\").html(failureText).show().css({\r\n 'left': col_pre,\r\n 'top': row\r\n });\r\n }\r\n },\r\n getHintText: function(item) {\r\n let _this = this;\r\n\r\n let hintText = item.hintText || '';\r\n\r\n if(hintText.length == 0){\r\n if(Store.lang == 'en'){\r\n if(item.type == 'dropdown'){\r\n hintText += 'please select an option in the drop-down list';\r\n }\r\n else if(item.type == 'checkbox'){\r\n\r\n }\r\n else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){\r\n hintText += 'please enter a ' + _this.optionLabel_en[item.type] + ' ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n hintText += ' and ' + item.value2;\r\n }\r\n }\r\n else if(item.type == 'text_content'){\r\n hintText += 'please enter text ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n }\r\n else if(item.type == 'text_length'){\r\n hintText += 'please enter text with length ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n \r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n hintText += ' and ' + item.value2;\r\n }\r\n }\r\n else if(item.type == 'date'){\r\n hintText += 'please enter a date ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n hintText += ' and ' + item.value2;\r\n }\r\n }\r\n else if(item.type == 'validity'){\r\n hintText += 'please enter the correct ' + _this.optionLabel_en[item.type2];\r\n }\r\n }\r\n else{\r\n if(item.type == 'dropdown'){\r\n hintText += '请选择下拉列表中的选项';\r\n }\r\n else if(item.type == 'checkbox'){\r\n\r\n }\r\n else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){\r\n hintText += '请输入' + _this.optionLabel[item.type2] + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n hintText += '和' + item.value2 + '之间';\r\n }\r\n\r\n hintText += '的' + _this.optionLabel[item.type];\r\n }\r\n else if(item.type == 'text_content'){\r\n hintText += '请输入内容' + _this.optionLabel[item.type2] + item.value1 + '的文本';\r\n }\r\n else if(item.type == 'text_length'){\r\n hintText += '请输入长度' + _this.optionLabel[item.type2] + item.value1;\r\n \r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n hintText += '和' + item.value2 + '之间';\r\n }\r\n\r\n hintText += '的文本';\r\n }\r\n else if(item.type == 'date'){\r\n hintText += '请输入' + _this.optionLabel[item.type2] + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n hintText += '和' + item.value2 + '之间';\r\n }\r\n\r\n hintText += '的日期';\r\n }\r\n else if(item.type == 'validity'){\r\n hintText += '请输入正确的' + _this.optionLabel[item.type2];\r\n }\r\n }\r\n }\r\n\r\n return hintText;\r\n },\r\n getFailureText: function(item) {\r\n let _this = this;\r\n\r\n let failureText = '';\r\n\r\n if(Store.lang == 'en'){\r\n if(item.type == 'dropdown'){\r\n failureText += 'what you selected is not an option in the drop-down list';\r\n }\r\n else if(item.type == 'checkbox'){\r\n\r\n }\r\n else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){\r\n failureText += 'what you entered is not a ' + _this.optionLabel_en[item.type] + ' ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n failureText += ' and ' + item.value2;\r\n }\r\n }\r\n else if(item.type == 'text_content'){\r\n failureText += 'what you entered is not text that ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n }\r\n else if(item.type == 'text_length'){\r\n failureText += 'the text you entered is not length ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n \r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n failureText += ' and ' + item.value2;\r\n }\r\n }\r\n else if(item.type == 'date'){\r\n failureText += 'the date you entered is not ' + _this.optionLabel_en[item.type2] + ' ' + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n failureText += ' and ' + item.value2;\r\n }\r\n }\r\n else if(item.type == 'validity'){\r\n failureText += 'what you entered is not a correct ' + _this.optionLabel_en[item.type2];\r\n }\r\n }\r\n else{\r\n if(item.type == 'dropdown'){\r\n failureText += '你选择的不是下拉列表中的选项';\r\n }\r\n else if(item.type == 'checkbox'){\r\n\r\n }\r\n else if(item.type == 'number' || item.type == 'number_integer' || item.type == 'number_decimal'){\r\n failureText += '你输入的不是' + _this.optionLabel[item.type2] + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n failureText += '和' + item.value2 + '之间';\r\n }\r\n\r\n failureText += '的' + _this.optionLabel[item.type];\r\n }\r\n else if(item.type == 'text_content'){\r\n failureText += '你输入的不是内容' + _this.optionLabel[item.type2] + item.value1 + '的文本';\r\n }\r\n else if(item.type == 'text_length'){\r\n failureText += '你输入的不是长度' + _this.optionLabel[item.type2] + item.value1;\r\n \r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n failureText += '和' + item.value2 + '之间';\r\n }\r\n\r\n failureText += '的文本';\r\n }\r\n else if(item.type == 'date'){\r\n failureText += '你输入的不是' + _this.optionLabel[item.type2] + item.value1;\r\n\r\n if(item.type2 == 'bw' || item.type2 == 'nb'){\r\n failureText += '和' + item.value2 + '之间';\r\n }\r\n\r\n failureText += '的日期';\r\n }\r\n else if(item.type == 'validity'){\r\n failureText += '你输入的不是一个正确的' + _this.optionLabel[item.type2];\r\n }\r\n }\r\n\r\n return failureText;\r\n },\r\n validateCellData: function(cellValue, item){\r\n let _this = this;\r\n\r\n let type = item.type,\r\n type2 = item.type2,\r\n value1 = item.value1,\r\n value2 = item.value2;\r\n\r\n if(type == 'dropdown'){\r\n let list = _this.getDropdownList(value1);\r\n\r\n let result = false;\r\n\r\n for(let i = 0; i < list.length; i++){\r\n if(list[i] == cellValue){\r\n result = true;\r\n break;\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(type == 'checkbox'){\r\n\r\n }\r\n else if(type == 'number' || type == 'number_integer' || type == 'number_decimal'){\r\n if(!isRealNum(cellValue)){\r\n return false;\r\n }\r\n \r\n cellValue = Number(cellValue);\r\n\r\n if(type == 'number_integer' && cellValue % 1 !== 0){\r\n return false;\r\n }\r\n\r\n if(type == 'number_decimal' && cellValue % 1 === 0){\r\n return false;\r\n }\r\n\r\n value1 = Number(value1);\r\n value2 = Number(value2);\r\n\r\n if(type2 == 'bw' && (cellValue < value1 || cellValue > value2)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'nb' && (cellValue >= value1 && cellValue <= value2)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'eq' && cellValue != value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'ne' && cellValue == value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'gt' && cellValue <= value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'lt' && cellValue >= value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'gte' && cellValue < value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'lte' && cellValue > value1){\r\n return false;\r\n }\r\n }\r\n else if(type == 'text_content'){\r\n cellValue = cellValue.toString();\r\n value1 = value1.toString();\r\n\r\n if(type2 == 'include' && cellValue.indexOf(value1) == -1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'exclude' && cellValue.indexOf(value1) > -1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'equal' && cellValue != value1){\r\n return false;\r\n }\r\n }\r\n else if(type == 'text_length'){\r\n cellValue = cellValue.toString().length;\r\n\r\n value1 = Number(value1);\r\n value2 = Number(value2);\r\n\r\n if(type2 == 'bw' && (cellValue < value1 || cellValue > value2)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'nb' && (cellValue >= value1 && cellValue <= value2)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'eq' && cellValue != value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'ne' && cellValue == value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'gt' && cellValue <= value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'lt' && cellValue >= value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'gte' && cellValue < value1){\r\n return false;\r\n }\r\n\r\n if(type2 == 'lte' && cellValue > value1){\r\n return false;\r\n }\r\n }\r\n else if(type == 'date'){\r\n if(!isdatetime(cellValue)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'bw' && (diff(cellValue, value1) < 0 || diff(cellValue, value2) > 0)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'nb' && (diff(cellValue, value1) >= 0 && diff(cellValue, value2) <= 0)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'eq' && diff(cellValue, value1) != 0){\r\n return false;\r\n }\r\n\r\n if(type2 == 'ne' && diff(cellValue, value1) == 0){\r\n return false;\r\n }\r\n\r\n if(type2 == 'bf' && diff(cellValue, value1) >= 0){\r\n return false;\r\n }\r\n\r\n if(type2 == 'nbf' && diff(cellValue, value1) < 0){\r\n return false;\r\n }\r\n\r\n if(type2 == 'af' && diff(cellValue, value1) <= 0){\r\n return false;\r\n }\r\n\r\n if(type2 == 'naf' && diff(cellValue, value1) > 0){\r\n return false;\r\n }\r\n }\r\n else if(type == 'validity'){\r\n if(type2 == 'card' && !/(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)/.test(cellValue)){\r\n return false;\r\n }\r\n\r\n if(type2 == 'phone' && !/^[1][3,4,5,7,8][0-9]{9}$/.test(cellValue)){\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n dropdownListShow: function(){\r\n $(\"#luckysheet-dataVerification-showHintBox\").hide();\r\n\r\n let _this = this;\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rowIndex = last.row_focus;\r\n let colIndex = last.column_focus;\r\n\r\n let row = Store.visibledatarow[rowIndex],\r\n row_pre = rowIndex == 0 ? 0 : Store.visibledatarow[rowIndex - 1];\r\n let col = Store.visibledatacolumn[colIndex],\r\n col_pre = colIndex == 0 ? 0 : Store.visibledatacolumn[colIndex - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, rowIndex, colIndex);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let item = _this.dataVerification[rowIndex + '_' + colIndex];\r\n let list = _this.getDropdownList(item.value1);\r\n\r\n let optionHtml = '';\r\n list.forEach(i => {\r\n optionHtml += `
${i}
`;\r\n })\r\n\r\n $(\"#luckysheet-dataVerification-dropdown-List\")\r\n .html(optionHtml)\r\n .prop(\"data-index\", rowIndex + '_' + colIndex)\r\n .show()\r\n .css({\r\n 'width': col - col_pre - 1,\r\n 'left': col_pre,\r\n 'top': row,\r\n });\r\n\r\n let myh = $(\"#luckysheet-dataVerification-dropdown-List\").outerHeight();\r\n let currentWinH = $(\"#luckysheet-cell-main\")[0].scrollHeight;\r\n\r\n if(row + myh > currentWinH - 42 - 6){\r\n $(\"#luckysheet-dataVerification-dropdown-List\").css({\r\n 'top': row_pre - myh,\r\n })\r\n }\r\n },\r\n getDropdownList: function(txt){\r\n let list = [];\r\n\r\n if(formula.iscelldata(txt)){\r\n let range = formula.getcellrange(txt);\r\n let d = Store.luckysheetfile[getSheetIndex(range.sheetIndex)].data;\r\n\r\n for(let r = range.row[0]; r <= range.row[1]; r++){\r\n for(let c = range.column[0]; c <= range.column[1]; c++){\r\n if(d[r] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(cell == null || cell.v == null){\r\n continue;\r\n }\r\n\r\n let v = cell.m || cell.v;\r\n\r\n if(!list.includes(v)){\r\n list.push(v);\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n let arr = txt.split(\",\");\r\n\r\n for(let i = 0; i < arr.length; i++){\r\n let v = arr[i];\r\n\r\n if(v.length == 0){\r\n continue;\r\n }\r\n\r\n if(!list.includes(v)){\r\n list.push(v);\r\n }\r\n }\r\n }\r\n\r\n return list;\r\n },\r\n checkboxChange: function(r, c){\r\n let _this = this;\r\n\r\n let historyDataVerification = $.extend(true, {}, _this.dataVerification);\r\n let currentDataVerification = $.extend(true, {}, _this.dataVerification);\r\n\r\n let item = currentDataVerification[r + '_' + c];\r\n item.checked = !item.checked;\r\n\r\n let value = item.value2;\r\n if(item.checked){\r\n value = item.value1;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n setcellvalue(r, c, d, value);\r\n\r\n _this.refOfCheckbox(\r\n historyDataVerification, \r\n currentDataVerification, \r\n Store.currentSheetIndex, \r\n d, \r\n { \"row\": [r, r], \"column\": [c, c] }\r\n );\r\n },\r\n ref: function(historyDataVerification, currentDataVerification, sheetIndex){\r\n let _this = this;\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let redo = {};\r\n redo[\"type\"] = \"updateDataVerification\";\r\n redo[\"sheetIndex\"] = sheetIndex;\r\n redo[\"historyDataVerification\"] = historyDataVerification;\r\n redo[\"currentDataVerification\"] = currentDataVerification;\r\n Store.jfredo.push(redo); \r\n }\r\n \r\n _this.dataVerification = currentDataVerification;\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)].dataVerification = currentDataVerification;\r\n\r\n //共享编辑模式\r\n if(server.allowUpdate){ \r\n server.saveParam(\"all\", sheetIndex, currentDataVerification, { \"k\": \"dataVerification\" });\r\n }\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n },\r\n refOfCheckbox: function(historyDataVerification, currentDataVerification, sheetIndex, d, range){\r\n let _this = this;\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let redo = {};\r\n redo[\"type\"] = \"updateDataVerificationOfCheckbox\";\r\n redo[\"sheetIndex\"] = sheetIndex;\r\n redo[\"historyDataVerification\"] = historyDataVerification;\r\n redo[\"currentDataVerification\"] = currentDataVerification;\r\n redo[\"data\"] = Store.flowdata; \r\n redo[\"curData\"] = d;\r\n redo[\"range\"] = range; \r\n Store.jfredo.push(redo); \r\n }\r\n\r\n _this.dataVerification = currentDataVerification;\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)].dataVerification = currentDataVerification;\r\n\r\n Store.flowdata = d;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)].data = Store.flowdata;\r\n\r\n //共享编辑模式\r\n if(server.allowUpdate){ \r\n server.saveParam(\"all\", sheetIndex, currentDataVerification, { \"k\": \"dataVerification\" });\r\n server.historyParam(Store.flowdata, sheetIndex, range);\r\n }\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n },\r\n}\r\n\r\nexport default dataVerificationCtrl;","import editor from './editor';\r\nimport formula from './formula';\r\nimport { jfrefreshgrid_adRC, jfrefreshgrid_deleteCell, jfrefreshgrid_rhcw } from './refresh';\r\nimport { datagridgrowth, getcellFormula } from './getdata';\r\nimport { setcellvalue } from './setdata';\r\nimport conditionformat from '../controllers/conditionformat';\r\nimport luckysheetFreezen from '../controllers/freezen';\r\nimport { selectHightlightShow } from '../controllers/select';\r\nimport { luckysheet_searcharray } from '../controllers/sheetSearch';\r\nimport {checkProtectionAuthorityNormal,checkProtectionNotEnable} from '../controllers/protection';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport Store from '../store';\r\n\r\n//增加行列\r\nfunction luckysheetextendtable(type, index, value, direction, sheetIndex) {\r\n sheetIndex = sheetIndex || Store.currentSheetIndex;\r\n\r\n if(type=='row' && !checkProtectionAuthorityNormal(sheetIndex, \"insertRows\")){\r\n return;\r\n }\r\n else if(type=='column' && !checkProtectionAuthorityNormal(sheetIndex, \"insertColumns\")){\r\n return;\r\n }\r\n\r\n let curOrder = getSheetIndex(sheetIndex);\r\n let file = Store.luckysheetfile[curOrder];\r\n let d = $.extend(true, [], file.data);\r\n\r\n value = Math.floor(value);\r\n let cfg = $.extend(true, {}, file.config);\r\n\r\n //合并单元格配置变动\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n let merge_new = {};\r\n for(let m in cfg[\"merge\"]){\r\n let mc = cfg[\"merge\"][m];\r\n\r\n let r = mc.r,\r\n c = mc.c,\r\n rs = mc.rs,\r\n cs = mc.cs;\r\n\r\n if(type == \"row\"){\r\n if(index < r){\r\n merge_new[(r + value) + \"_\" + c] = { \"r\": r + value, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n else if(index == r){\r\n if(direction == \"lefttop\"){\r\n merge_new[(r + value) + \"_\" + c] = { \"r\": r + value, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n else{\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs + value, \"cs\": cs };\r\n }\r\n }\r\n else if(index < r + rs - 1){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs + value, \"cs\": cs };\r\n }\r\n else if(index == r + rs - 1){\r\n if(direction == \"lefttop\"){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs + value, \"cs\": cs };\r\n }\r\n else{\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n }\r\n else{\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(index < c){\r\n merge_new[r + \"_\" + (c + value)] = { \"r\": r, \"c\": c + value, \"rs\": rs, \"cs\": cs };\r\n }\r\n else if(index == c){\r\n if(direction == \"lefttop\"){\r\n merge_new[r + \"_\" + (c + value)] = { \"r\": r, \"c\": c + value, \"rs\": rs, \"cs\": cs };\r\n }\r\n else{\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs + value };\r\n }\r\n }\r\n else if(index < c + cs - 1){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs + value };\r\n }\r\n else if(index == c + cs - 1){\r\n if(direction == \"lefttop\"){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs + value };\r\n }\r\n else{\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n }\r\n else{\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n }\r\n }\r\n cfg[\"merge\"] = merge_new;\r\n\r\n //公式配置变动\r\n let calcChain = file.calcChain;\r\n let newCalcChain = [];\r\n if(calcChain != null && calcChain.length > 0){\r\n for(let i = 0; i < calcChain.length; i++){\r\n let calc = $.extend(true, {}, calcChain[i]);\r\n let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = getcellFormula(calc_r, calc_c, calc_i);\r\n\r\n if(type == \"row\"){\r\n let functionStr = \"=\" + formula.functionStrChange(calc_funcStr, \"add\", \"row\", direction, index, value);\r\n\r\n if(d[calc_r][calc_c] && d[calc_r][calc_c].f == calc_funcStr){\r\n d[calc_r][calc_c].f = functionStr;\r\n }\r\n\r\n if(direction == \"lefttop\"){\r\n if(calc_r >= index){\r\n calc.r += value;\r\n }\r\n }\r\n else if(direction == \"rightbottom\"){\r\n if(calc_r > index){\r\n calc.r += value;\r\n }\r\n }\r\n\r\n newCalcChain.push(calc);\r\n }\r\n else if(type == \"column\"){\r\n let functionStr = \"=\" + formula.functionStrChange(calc_funcStr, \"add\", \"col\", direction, index, value);\r\n\r\n if(d[calc_r][calc_c] && d[calc_r][calc_c].f == calc_funcStr){\r\n d[calc_r][calc_c].f = functionStr;\r\n }\r\n\r\n if(direction == \"lefttop\"){\r\n if(calc_c >= index){\r\n calc.c += value;\r\n }\r\n }\r\n else if(direction == \"rightbottom\"){\r\n if(calc_c > index){\r\n calc.c += value;\r\n }\r\n }\r\n\r\n newCalcChain.push(calc);\r\n }\r\n }\r\n }\r\n\r\n //筛选配置变动\r\n let filter_select = file.filter_select;\r\n let filter = file.filter;\r\n let newFilterObj = null;\r\n if(filter_select != null && JSON.stringify(filter_select) != \"{}\"){\r\n newFilterObj = { \"filter_select\": null, \"filter\": null };\r\n\r\n let f_r1 = filter_select.row[0], f_r2 = filter_select.row[1];\r\n let f_c1 = filter_select.column[0], f_c2 = filter_select.column[1];\r\n\r\n if(type == \"row\"){\r\n if(f_r1 < index){\r\n if(f_r2 == index && direction == \"lefttop\"){\r\n f_r2 += value; \r\n }\r\n else if(f_r2 > index){\r\n f_r2 += value; \r\n }\r\n }\r\n else if(f_r1 == index){\r\n if(direction == \"lefttop\"){\r\n f_r1 += value;\r\n f_r2 += value;\r\n }\r\n else if(direction == \"rightbottom\" && f_r2 > index){\r\n f_r2 += value;\r\n }\r\n }\r\n else{\r\n f_r1 += value;\r\n f_r2 += value;\r\n }\r\n\r\n if(filter != null){\r\n newFilterObj.filter = {};\r\n\r\n for(let k in filter){\r\n let f_rowhidden = filter[k].rowhidden;\r\n let f_rowhidden_new = {};\r\n\r\n for(let n in f_rowhidden){\r\n n = parseFloat(n);\r\n\r\n if(n < index){\r\n f_rowhidden_new[n] = 0;\r\n }\r\n else if(n == index){\r\n if(direction == \"lefttop\"){\r\n f_rowhidden_new[n + value] = 0;\r\n }\r\n else if(direction == \"rightbottom\"){\r\n f_rowhidden_new[n] = 0;\r\n }\r\n }\r\n else{\r\n f_rowhidden_new[n + value] = 0;\r\n }\r\n }\r\n\r\n newFilterObj.filter[k] = $.extend(true, {}, filter[k]);\r\n newFilterObj.filter[k].rowhidden = f_rowhidden_new;\r\n newFilterObj.filter[k].str = f_r1;\r\n newFilterObj.filter[k].edr = f_r2;\r\n }\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(f_c1 < index){\r\n if(f_c2 == index && direction == \"lefttop\"){\r\n f_c2 += value; \r\n }\r\n else if(f_c2 > index){\r\n f_c2 += value; \r\n }\r\n }\r\n else if(f_c1 == index){\r\n if(direction == \"lefttop\"){\r\n f_c1 += value;\r\n f_c2 += value;\r\n }\r\n else if(direction == \"rightbottom\" && f_c2 > index){\r\n f_c2 += value;\r\n }\r\n }\r\n else{\r\n f_c1 += value;\r\n f_c2 += value;\r\n }\r\n\r\n if(filter != null){\r\n newFilterObj.filter = {};\r\n\r\n for(let k in filter){\r\n let f_cindex = filter[k].cindex;\r\n\r\n if(f_cindex == index && direction == \"lefttop\"){\r\n f_cindex += value;\r\n }\r\n else if(f_cindex > index){\r\n f_cindex += value;\r\n }\r\n\r\n newFilterObj.filter[f_cindex - f_c1] = $.extend(true, {}, filter[k]);\r\n newFilterObj.filter[f_cindex - f_c1].cindex = f_cindex;\r\n newFilterObj.filter[f_cindex - f_c1].stc = f_c1;\r\n newFilterObj.filter[f_cindex - f_c1].edc = f_c2;\r\n }\r\n }\r\n }\r\n\r\n newFilterObj.filter_select = { \"row\": [f_r1, f_r2], \"column\": [f_c1, f_c2] };\r\n }\r\n\r\n if(newFilterObj != null && newFilterObj.filter != null){\r\n if(cfg[\"rowhidden\"] == null){\r\n cfg[\"rowhidden\"] = {};\r\n }\r\n\r\n for(let k in newFilterObj.filter){\r\n let f_rowhidden = newFilterObj.filter[k].rowhidden;\r\n\r\n for(let n in f_rowhidden){\r\n cfg[\"rowhidden\"][n] = 0;\r\n }\r\n }\r\n }\r\n\r\n //条件格式配置变动\r\n let CFarr = file.luckysheet_conditionformat_save;\r\n let newCFarr = [];\r\n if(CFarr != null && CFarr.length > 0){\r\n for(let i = 0; i < CFarr.length; i++){\r\n let cf_range = CFarr[i].cellrange;\r\n let cf_new_range = [];\r\n\r\n for(let j = 0; j < cf_range.length; j++){\r\n let CFr1 = cf_range[j].row[0],\r\n CFr2 = cf_range[j].row[1],\r\n CFc1 = cf_range[j].column[0],\r\n CFc2 = cf_range[j].column[1];\r\n\r\n if(type == \"row\"){\r\n if(CFr1 < index){\r\n if(CFr2 == index && direction == \"lefttop\"){\r\n CFr2 += value; \r\n }\r\n else if(CFr2 > index){\r\n CFr2 += value; \r\n }\r\n }\r\n else if(CFr1 == index){\r\n if(direction == \"lefttop\"){\r\n CFr1 += value;\r\n CFr2 += value;\r\n }\r\n else if(direction == \"rightbottom\" && CFr2 > index){\r\n CFr2 += value;\r\n }\r\n }\r\n else{\r\n CFr1 += value;\r\n CFr2 += value;\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(CFc1 < index){\r\n if(CFc2 == index && direction == \"lefttop\"){\r\n CFc2 += value; \r\n }\r\n else if(CFc2 > index){\r\n CFc2 += value; \r\n }\r\n }\r\n else if(CFc1 == index){\r\n if(direction == \"lefttop\"){\r\n CFc1 += value;\r\n CFc2 += value;\r\n }\r\n else if(direction == \"rightbottom\" && CFc2 > index){\r\n CFc2 += value;\r\n }\r\n }\r\n else{\r\n CFc1 += value;\r\n CFc2 += value;\r\n }\r\n }\r\n\r\n cf_new_range.push({ \"row\": [CFr1, CFr2], \"column\": [CFc1, CFc2] });\r\n }\r\n\r\n let cf = $.extend(true, {}, CFarr[i]);\r\n cf.cellrange = cf_new_range;\r\n\r\n newCFarr.push(cf);\r\n }\r\n }\r\n\r\n //交替颜色配置变动\r\n let AFarr = file.luckysheet_alternateformat_save;\r\n let newAFarr = [];\r\n if(AFarr != null && AFarr.length > 0){\r\n for(let i = 0; i < AFarr.length; i++){\r\n let AFr1 = AFarr[i].cellrange.row[0],\r\n AFr2 = AFarr[i].cellrange.row[1],\r\n AFc1 = AFarr[i].cellrange.column[0],\r\n AFc2 = AFarr[i].cellrange.column[1];\r\n\r\n let af = $.extend(true, {}, AFarr[i]);\r\n\r\n if(type == \"row\"){\r\n if(AFr1 < index){\r\n if(AFr2 == index && direction == \"lefttop\"){\r\n AFr2 += value; \r\n }\r\n else if(AFr2 > index){\r\n AFr2 += value; \r\n }\r\n }\r\n else if(AFr1 == index){\r\n if(direction == \"lefttop\"){\r\n AFr1 += value;\r\n AFr2 += value;\r\n }\r\n else if(direction == \"rightbottom\" && AFr2 > index){\r\n AFr2 += value;\r\n }\r\n }\r\n else{\r\n AFr1 += value;\r\n AFr2 += value;\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(AFc1 < index){\r\n if(AFc2 == index && direction == \"lefttop\"){\r\n AFc2 += value; \r\n }\r\n else if(AFc2 > index){\r\n AFc2 += value; \r\n }\r\n }\r\n else if(AFc1 == index){\r\n if(direction == \"lefttop\"){\r\n AFc1 += value;\r\n AFc2 += value;\r\n }\r\n else if(direction == \"rightbottom\" && AFc2 > index){\r\n AFc2 += value;\r\n }\r\n }\r\n else{\r\n AFc1 += value;\r\n AFc2 += value;\r\n }\r\n }\r\n\r\n af.cellrange = { \"row\": [AFr1, AFr2], \"column\": [AFc1, AFc2] };\r\n\r\n newAFarr.push(af);\r\n }\r\n }\r\n\r\n //冻结配置变动\r\n let newFreezen = { \"freezenhorizontaldata\": null, \"freezenverticaldata\": null };\r\n if(luckysheetFreezen.freezenhorizontaldata != null && type == \"row\"){\r\n let freezen_scrollTop = luckysheetFreezen.freezenhorizontaldata[2];\r\n let freezen_row_st = luckysheetFreezen.freezenhorizontaldata[1] - 1;\r\n\r\n if(freezen_row_st == index && direction == \"lefttop\"){\r\n freezen_row_st += value;\r\n }\r\n else if(freezen_row_st > index){\r\n freezen_row_st += value;\r\n }\r\n\r\n let freezen_top = Store.visibledatarow[freezen_row_st] - 2 - freezen_scrollTop + Store.columnHeaderHeight;\r\n\r\n newFreezen.freezenhorizontaldata = [\r\n Store.visibledatarow[freezen_row_st], \r\n freezen_row_st + 1, \r\n freezen_scrollTop, \r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, freezen_row_st + 1), \r\n freezen_top\r\n ];\r\n }\r\n else{\r\n newFreezen.freezenhorizontaldata = luckysheetFreezen.freezenhorizontaldata;\r\n }\r\n\r\n if(luckysheetFreezen.freezenverticaldata != null && type == \"column\"){\r\n let freezen_scrollLeft = luckysheetFreezen.freezenverticaldata[2];\r\n let freezen_col_st = luckysheetFreezen.freezenverticaldata[1] - 1;\r\n\r\n if(freezen_col_st == index && direction == \"lefttop\"){\r\n freezen_col_st += value;\r\n }\r\n else if(freezen_col_st > index){\r\n freezen_col_st += value;\r\n }\r\n\r\n let freezen_left = Store.visibledatacolumn[freezen_col_st] - 2 - freezen_scrollLeft + Store.rowHeaderWidth;\r\n\r\n newFreezen.freezenverticaldata = [\r\n Store.visibledatacolumn[freezen_col_st], \r\n freezen_col_st + 1, \r\n freezen_scrollLeft, \r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, freezen_col_st + 1), \r\n freezen_left\r\n ];\r\n }\r\n else{\r\n newFreezen.freezenverticaldata = luckysheetFreezen.freezenverticaldata;\r\n }\r\n\r\n //数据验证配置变动\r\n let dataVerification = file.dataVerification;\r\n let newDataVerification = {};\r\n if(dataVerification != null){\r\n for(let key in dataVerification){\r\n let r = Number(key.split('_')[0]),\r\n c = Number(key.split('_')[1]);\r\n let item = dataVerification[key];\r\n \r\n if(type == \"row\"){\r\n if(index < r){\r\n newDataVerification[(r + value) + \"_\" + c] = item;\r\n }\r\n else if(index == r){\r\n if(direction == \"lefttop\"){\r\n newDataVerification[(r + value) + \"_\" + c] = item;\r\n\r\n for(let i = 0; i < value; i++){\r\n newDataVerification[(r + i) + \"_\" + c] = item;\r\n }\r\n }\r\n else{\r\n newDataVerification[r + \"_\" + c] = item;\r\n\r\n for(let i = 0; i < value; i++){\r\n newDataVerification[(r + i + 1) + \"_\" + c] = item;\r\n }\r\n }\r\n }\r\n else{\r\n newDataVerification[r + \"_\" + c] = item;\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(index < c){\r\n newDataVerification[r + \"_\" + (c + value)] = item;\r\n }\r\n else if(index == c){\r\n if(direction == \"lefttop\"){\r\n newDataVerification[r + \"_\" + (c + value)] = item;\r\n\r\n for(let i = 0; i < value; i++){\r\n newDataVerification[r + \"_\" + (c + i)] = item;\r\n }\r\n }\r\n else{\r\n newDataVerification[r + \"_\" + c] = item;\r\n\r\n for(let i = 0; i < value; i++){\r\n newDataVerification[r + \"_\" + (c + i + 1)] = item;\r\n }\r\n }\r\n }\r\n else{\r\n newDataVerification[r + \"_\" + c] = item;\r\n }\r\n }\r\n }\r\n }\r\n\r\n //超链接配置变动\r\n let hyperlink = file.hyperlink;\r\n let newHyperlink = {};\r\n if(hyperlink != null){\r\n for(let key in hyperlink){\r\n let r = Number(key.split('_')[0]),\r\n c = Number(key.split('_')[1]);\r\n let item = hyperlink[key];\r\n \r\n if(type == \"row\"){\r\n if(index < r){\r\n newHyperlink[(r + value) + \"_\" + c] = item;\r\n }\r\n else if(index == r){\r\n if(direction == \"lefttop\"){\r\n newHyperlink[(r + value) + \"_\" + c] = item;\r\n }\r\n else{\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n }\r\n else{\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(index < c){\r\n newHyperlink[r + \"_\" + (c + value)] = item;\r\n }\r\n else if(index == c){\r\n if(direction == \"lefttop\"){\r\n newHyperlink[r + \"_\" + (c + value)] = item;\r\n }\r\n else{\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n }\r\n else{\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n }\r\n }\r\n }\r\n\r\n let type1;\r\n if (type == \"row\") {\r\n type1 = \"r\";\r\n\r\n //行高配置变动\r\n if(cfg[\"rowlen\"] != null){\r\n let rowlen_new = {};\r\n\r\n for(let r in cfg[\"rowlen\"]){\r\n r = parseFloat(r);\r\n\r\n if(r < index){\r\n rowlen_new[r] = cfg[\"rowlen\"][r];\r\n }\r\n else if(r == index){\r\n if(direction == \"lefttop\"){\r\n rowlen_new[(r + value)] = cfg[\"rowlen\"][r];\r\n }\r\n else if(direction == \"rightbottom\"){\r\n rowlen_new[r] = cfg[\"rowlen\"][r];\r\n }\r\n }\r\n else{\r\n rowlen_new[(r + value)] = cfg[\"rowlen\"][r];\r\n }\r\n }\r\n\r\n cfg[\"rowlen\"] = rowlen_new;\r\n }\r\n\r\n //隐藏行配置变动\r\n if(cfg[\"rowhidden\"] != null){\r\n let rowhidden_new = {};\r\n\r\n for(let r in cfg[\"rowhidden\"]){\r\n r = parseFloat(r);\r\n\r\n if(r < index){\r\n rowhidden_new[r] = cfg[\"rowhidden\"][r];\r\n }\r\n else if(r == index){\r\n if(direction == \"lefttop\"){\r\n rowhidden_new[(r + value)] = cfg[\"rowhidden\"][r];\r\n }\r\n else if(direction == \"rightbottom\"){\r\n rowhidden_new[r] = cfg[\"rowhidden\"][r];\r\n }\r\n }\r\n else{\r\n rowhidden_new[(r + value)] = cfg[\"rowhidden\"][r];\r\n }\r\n }\r\n\r\n cfg[\"rowhidden\"] = rowhidden_new;\r\n }\r\n\r\n //空行模板\r\n let row = [];\r\n for(let c = 0; c < d[0].length; c++){\r\n row.push(null);\r\n }\r\n\r\n //边框\r\n if(cfg[\"borderInfo\"] && cfg[\"borderInfo\"].length > 0){\r\n let borderInfo = []; \r\n\r\n for(let i = 0; i < cfg[\"borderInfo\"].length; i++){\r\n let rangeType = cfg[\"borderInfo\"][i].rangeType;\r\n\r\n if(rangeType == \"range\"){\r\n let borderRange = cfg[\"borderInfo\"][i].range;\r\n\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < borderRange.length; j++){\r\n let bd_r1 = borderRange[j].row[0],\r\n bd_r2 = borderRange[j].row[1];\r\n\r\n if(direction == \"lefttop\"){\r\n if(index <= bd_r1){\r\n bd_r1 += value;\r\n bd_r2 += value;\r\n }\r\n else if(index <= bd_r2){\r\n bd_r2 += value;\r\n }\r\n }\r\n else{\r\n if(index < bd_r1){\r\n bd_r1 += value;\r\n bd_r2 += value;\r\n }\r\n else if(index < bd_r2){\r\n bd_r2 += value;\r\n }\r\n }\r\n\r\n if(bd_r2 >= bd_r1){\r\n emptyRange.push({ \"row\": [bd_r1, bd_r2], \"column\": borderRange[j].column });\r\n } \r\n }\r\n\r\n if(emptyRange.length > 0){\r\n let bd_obj = {\r\n \"rangeType\": \"range\",\r\n \"borderType\": cfg[\"borderInfo\"][i].borderType,\r\n \"style\": cfg[\"borderInfo\"][i].style,\r\n \"color\": cfg[\"borderInfo\"][i].color,\r\n \"range\": emptyRange\r\n }\r\n\r\n borderInfo.push(bd_obj);\r\n }\r\n }\r\n else if(rangeType == \"cell\"){\r\n let row_index = cfg[\"borderInfo\"][i].value.row_index;\r\n\r\n if(direction == \"lefttop\"){\r\n if(index <= row_index){\r\n row_index += value;\r\n }\r\n }\r\n else{\r\n if(index < row_index){\r\n row_index += value;\r\n }\r\n }\r\n \r\n cfg[\"borderInfo\"][i].value.row_index = row_index;\r\n borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"] = borderInfo;\r\n }\r\n \r\n let arr = [];\r\n for (let r = 0; r < value; r++) {\r\n arr.push(JSON.stringify(row));\r\n }\r\n\r\n if(direction == \"lefttop\"){\r\n if(index == 0){\r\n new Function(\"d\",\"return \" + 'd.unshift(' + arr.join(\",\") + ')')(d);\r\n }\r\n else{\r\n new Function(\"d\",\"return \" + 'd.splice(' + index + ', 0, ' + arr.join(\",\") + ')')(d);\r\n }\r\n }\r\n else{ \r\n new Function(\"d\",\"return \" + 'd.splice(' + (index + 1) + ', 0, ' + arr.join(\",\") + ')')(d); \r\n }\r\n }\r\n else {\r\n type1 = \"c\";\r\n\r\n //行高配置变动\r\n if(cfg[\"columnlen\"] != null){\r\n let columnlen_new = {};\r\n\r\n for(let c in cfg[\"columnlen\"]){\r\n c = parseFloat(c);\r\n \r\n if(c < index){\r\n columnlen_new[c] = cfg[\"columnlen\"][c];\r\n }\r\n else if(c == index){\r\n if(direction == \"lefttop\"){\r\n columnlen_new[(c + value)] = cfg[\"columnlen\"][c];\r\n }\r\n else if(direction == \"rightbottom\"){\r\n columnlen_new[c] = cfg[\"columnlen\"][c];\r\n }\r\n }\r\n else{\r\n columnlen_new[(c + value)] = cfg[\"columnlen\"][c];\r\n }\r\n }\r\n\r\n cfg[\"columnlen\"] = columnlen_new;\r\n }\r\n\r\n //隐藏列配置变动\r\n if(cfg[\"colhidden\"] != null){\r\n let colhidden_new = {};\r\n\r\n for(let c in cfg[\"colhidden\"]){\r\n c = parseFloat(c);\r\n \r\n if(c < index){\r\n colhidden_new[c] = cfg[\"colhidden\"][c];\r\n }\r\n else if(c == index){\r\n if(direction == \"lefttop\"){\r\n colhidden_new[(c + value)] = cfg[\"colhidden\"][c];\r\n }\r\n else if(direction == \"rightbottom\"){\r\n colhidden_new[c] = cfg[\"colhidden\"][c];\r\n }\r\n }\r\n else{\r\n colhidden_new[(c + value)] = cfg[\"colhidden\"][c];\r\n }\r\n }\r\n\r\n cfg[\"colhidden\"] = colhidden_new;\r\n }\r\n\r\n //空列模板\r\n let col = [];\r\n for(let r = 0; r < d.length; r++){\r\n col.push(null);\r\n }\r\n\r\n //边框\r\n if(cfg[\"borderInfo\"] && cfg[\"borderInfo\"].length > 0){\r\n let borderInfo = []; \r\n\r\n for(let i = 0; i < cfg[\"borderInfo\"].length; i++){\r\n let rangeType = cfg[\"borderInfo\"][i].rangeType;\r\n\r\n if(rangeType == \"range\"){\r\n let borderRange = cfg[\"borderInfo\"][i].range;\r\n\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < borderRange.length; j++){\r\n let bd_c1 = borderRange[j].column[0],\r\n bd_c2 = borderRange[j].column[1];\r\n\r\n if(direction == \"lefttop\"){\r\n if(index <= bd_c1){\r\n bd_c1 += value;\r\n bd_c2 += value;\r\n }\r\n else if(index <= bd_c2){\r\n bd_c2 += value;\r\n }\r\n }\r\n else{\r\n if(index < bd_c1){\r\n bd_c1 += value;\r\n bd_c2 += value;\r\n }\r\n else if(index < bd_c2){\r\n bd_c2 += value;\r\n }\r\n }\r\n\r\n if(bd_c2 >= bd_c1){\r\n emptyRange.push({ \"row\": borderRange[j].row, \"column\": [bd_c1, bd_c2] });\r\n } \r\n }\r\n\r\n if(emptyRange.length > 0){\r\n let bd_obj = {\r\n \"rangeType\": \"range\",\r\n \"borderType\": cfg[\"borderInfo\"][i].borderType,\r\n \"style\": cfg[\"borderInfo\"][i].style,\r\n \"color\": cfg[\"borderInfo\"][i].color,\r\n \"range\": emptyRange\r\n }\r\n\r\n borderInfo.push(bd_obj);\r\n }\r\n }\r\n else if(rangeType == \"cell\"){\r\n let col_index = cfg[\"borderInfo\"][i].value.col_index;\r\n\r\n if(direction == \"lefttop\"){\r\n if(index <= col_index){\r\n col_index += value;\r\n }\r\n }\r\n else{\r\n if(index < col_index){\r\n col_index += value;\r\n }\r\n }\r\n \r\n cfg[\"borderInfo\"][i].value.col_index = col_index;\r\n borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"] = borderInfo;\r\n }\r\n \r\n for (let r = 0; r < d.length; r++) {\r\n let row = d[r];\r\n\r\n for(let i = 0; i < value; i++){\r\n if(direction == \"lefttop\"){\r\n if(index == 0){\r\n row.unshift(col[r]);\r\n }\r\n else{\r\n row.splice(index, 0, col[r]);\r\n }\r\n }\r\n else{\r\n row.splice((index + 1), 0, col[r]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // 修改当前sheet页时刷新\r\n if (file.index == Store.currentSheetIndex) {\r\n jfrefreshgrid_adRC(\r\n d, \r\n cfg, \r\n \"addRC\", \r\n { \"index\": index, \"len\": value, \"direction\": direction, \"rc\": type1, \"restore\": false }, \r\n newCalcChain, \r\n newFilterObj, \r\n newCFarr, \r\n newAFarr, \r\n newFreezen,\r\n newDataVerification,\r\n newHyperlink\r\n );\r\n }\r\n else{\r\n file.data = d;\r\n file.config = cfg;\r\n file.calcChain = newCalcChain;\r\n file.filter = newFilterObj.filter;\r\n file.filter_select = newFilterObj.filter_select;\r\n file.luckysheet_conditionformat_save = newCFarr;\r\n file.luckysheet_alternateformat_save = newAFarr;\r\n file.dataVerification = newDataVerification;\r\n file.hyperlink = newHyperlink;\r\n }\r\n \r\n let range = null;\r\n if(type == \"row\"){\r\n if(direction == \"lefttop\"){\r\n range = [{ \"row\": [index, index + value - 1], \"column\": [0 , d[0].length - 1] }];\r\n }\r\n else{\r\n range = [{ \"row\": [index + 1, index + value], \"column\": [0 , d[0].length - 1] }];\r\n }\r\n }\r\n else{\r\n if(direction == \"lefttop\"){\r\n range = [{ \"row\": [0, d.length - 1], \"column\": [index, index + value - 1] }];\r\n }\r\n else{\r\n range = [{ \"row\": [0, d.length - 1], \"column\": [index + 1, index + value] }];\r\n }\r\n }\r\n \r\n file.luckysheet_select_save = range;\r\n if (file.index == Store.currentSheetIndex) {\r\n Store.luckysheet_select_save = range;\r\n selectHightlightShow();\r\n }\r\n\r\n if (type == \"row\"){\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft(), \r\n scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), \r\n winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let row = Store.visibledatarow[range[0].row[1]], \r\n row_pre = range[0].row[0] - 1 == -1 ? 0 : Store.visibledatarow[range[0].row[0] - 1];\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row - winH + 20);\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row_pre - 20);\r\n }\r\n\r\n if(value > 30){\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n }\r\n }\r\n}\r\n\r\nfunction luckysheetextendData(rowlen, newData) {\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n let collen = d[0].length;\r\n let addNullData = datagridgrowth([], rowlen, collen);\r\n\r\n d = d.concat(addNullData);\r\n\r\n for(let i = 0; i < newData.length; i++){\r\n let r = newData[i].r,\r\n c = newData[i].c,\r\n v = newData[i].v;\r\n\r\n setcellvalue(r, c, d, v);\r\n\r\n if(v != null && v.mc != null && v.mc.rs != null){\r\n cfg[\"merge\"][v.mc.r + \"_\" + v.mc.c] = $.extend(true, {}, v.mc);\r\n }\r\n }\r\n\r\n //luckysheet.flowdata\r\n Store.flowdata = d;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = d; \r\n\r\n //config\r\n Store.config = cfg;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n //行高、列宽刷新\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n}\r\n\r\n//删除行列\r\nfunction luckysheetdeletetable(type, st, ed, sheetIndex) {\r\n\r\n sheetIndex = sheetIndex || Store.currentSheetIndex;\r\n \r\n if(type=='row' && !checkProtectionAuthorityNormal(sheetIndex, \"deleteRows\")){\r\n return;\r\n }\r\n else if(type=='column' && !checkProtectionAuthorityNormal(sheetIndex, \"deleteColumns\")){\r\n return;\r\n }\r\n\r\n let curOrder = getSheetIndex(sheetIndex);\r\n\r\n let file = Store.luckysheetfile[curOrder];\r\n let d = $.extend(true, [], file.data);\r\n\r\n if(st < 0){\r\n st = 0;\r\n }\r\n\r\n if(ed < 0){\r\n ed = 0;\r\n }\r\n\r\n if(type == \"row\"){\r\n if(st > d.length - 1){\r\n st = d.length - 1;\r\n }\r\n\r\n if(ed > d.length - 1){\r\n ed = d.length - 1;\r\n }\r\n }\r\n else{\r\n if(st > d[0].length - 1){\r\n st = d[0].length - 1;\r\n }\r\n\r\n if(ed > d[0].length - 1){\r\n ed = d[0].length - 1;\r\n }\r\n }\r\n\r\n if(st > ed){\r\n return\r\n }\r\n\r\n let slen = ed - st + 1;\r\n let cfg = $.extend(true, {}, file.config);\r\n\r\n //合并单元格配置变动\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n let merge_new = {};\r\n for(let m in cfg[\"merge\"]){\r\n let mc = cfg[\"merge\"][m];\r\n\r\n let r = mc.r,\r\n c = mc.c,\r\n rs = mc.rs,\r\n cs = mc.cs;\r\n\r\n if(type == \"row\"){\r\n if(r < st){\r\n if(r + rs - 1 < st){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n else if(r + rs - 1 >= st && r + rs - 1 < ed){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": st - r, \"cs\": cs };\r\n }\r\n else if(r + rs - 1 >= ed){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs - slen, \"cs\": cs };\r\n }\r\n }\r\n else if(r >= st && r <= ed){\r\n if(r + rs - 1 > ed){\r\n merge_new[st + \"_\" + c] = { \"r\": st, \"c\": c, \"rs\": r + rs - 1 - ed, \"cs\": cs };\r\n }\r\n }\r\n else if(r > ed){\r\n merge_new[(r - slen) + \"_\" + c] = { \"r\": r - slen, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(c < st){\r\n if(c + cs - 1 < st){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n else if(c + cs - 1 >= st && c + cs - 1 < ed){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": st - c };\r\n }\r\n else if(c + cs - 1 >= ed){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs - slen };\r\n }\r\n }\r\n else if(c >= st && c <= ed){\r\n if(c + cs - 1 > ed){\r\n merge_new[r + \"_\" + st] = { \"r\": r, \"c\": st, \"rs\": rs, \"cs\": c + cs - 1 - ed };\r\n }\r\n }\r\n else if(c > ed){\r\n merge_new[r + \"_\" + (c - slen)] = { \"r\": r, \"c\": c - slen, \"rs\": rs, \"cs\": cs };\r\n }\r\n }\r\n }\r\n cfg[\"merge\"] = merge_new;\r\n\r\n //公式配置变动\r\n let calcChain = file.calcChain;\r\n let newCalcChain = [];\r\n if(calcChain != null && calcChain.length > 0){\r\n for(let i = 0; i < calcChain.length; i++){\r\n let calc = $.extend(true, {}, calcChain[i]);\r\n let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = getcellFormula(calc_r, calc_c, calc_i);\r\n\r\n if(type == \"row\"){\r\n if(calc_r < st || calc_r > ed){\r\n let functionStr = \"=\" + formula.functionStrChange(calc_funcStr, \"del\", \"row\", null, st, slen);\r\n\r\n if(d[calc_r][calc_c] && d[calc_r][calc_c].f == calc_funcStr){\r\n d[calc_r][calc_c].f = functionStr;\r\n }\r\n\r\n if(calc_r > ed){\r\n calc.r = calc_r - slen;\r\n }\r\n\r\n newCalcChain.push(calc);\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(calc_c < st || calc_c > ed){\r\n let functionStr = \"=\" + formula.functionStrChange(calc_funcStr, \"del\", \"col\", null, st, slen);\r\n\r\n if(d[calc_r][calc_c] && d[calc_r][calc_c].f == calc_funcStr){\r\n d[calc_r][calc_c].f = functionStr;\r\n }\r\n\r\n if(calc_c > ed){\r\n calc.c = calc_c - slen;\r\n }\r\n\r\n newCalcChain.push(calc);\r\n }\r\n }\r\n }\r\n }\r\n\r\n //筛选配置变动\r\n let filter_select = file.filter_select;\r\n let filter = file.filter;\r\n let newFilterObj = null;\r\n if(filter_select != null && JSON.stringify(filter_select) != \"{}\"){\r\n newFilterObj = { \"filter_select\": null, \"filter\": null };\r\n\r\n let f_r1 = filter_select.row[0], f_r2 = filter_select.row[1];\r\n let f_c1 = filter_select.column[0], f_c2 = filter_select.column[1];\r\n\r\n if(type == \"row\"){\r\n if(f_r1 > ed){\r\n f_r1 -= slen;\r\n f_r2 -= slen;\r\n\r\n newFilterObj.filter_select = { \"row\": [f_r1, f_r2], \"column\": [f_c1, f_c2] };\r\n }\r\n else if(f_r1 < st){\r\n if(f_r2 < st){\r\n\r\n }\r\n else if(f_r2 <= ed){\r\n f_r2 = st - 1;\r\n }\r\n else{\r\n f_r2 -= slen;\r\n }\r\n\r\n newFilterObj.filter_select = { \"row\": [f_r1, f_r2], \"column\": [f_c1, f_c2] };\r\n }\r\n\r\n if(newFilterObj.filter_select != null && filter != null){\r\n for(let k in filter){\r\n let f_rowhidden = filter[k].rowhidden;\r\n let f_rowhidden_new = {};\r\n\r\n for(let n in f_rowhidden){\r\n if(n < st){\r\n f_rowhidden_new[n] = 0;\r\n }\r\n else if(n > ed){\r\n f_rowhidden_new[n - slen] = 0;\r\n }\r\n }\r\n\r\n if(JSON.stringify(f_rowhidden_new) != \"{}\"){\r\n if(newFilterObj.filter == null){\r\n newFilterObj.filter = {};\r\n }\r\n\r\n newFilterObj.filter[k] = $.extend(true, {}, filter[k]);\r\n newFilterObj.filter[k].rowhidden = f_rowhidden_new;\r\n newFilterObj.filter[k].str = f_r1;\r\n newFilterObj.filter[k].edr = f_r2;\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(f_c1 > ed){\r\n f_c1 -= slen;\r\n f_c2 -= slen;\r\n\r\n newFilterObj.filter_select = { \"row\": [f_r1, f_r2], \"column\": [f_c1, f_c2] };\r\n }\r\n else if(f_c1 < st){\r\n if(f_c2 < st){\r\n\r\n }\r\n else if(f_c2 <= ed){\r\n f_c2 = st - 1;\r\n }\r\n else{\r\n f_c2 -= slen;\r\n }\r\n\r\n newFilterObj.filter_select = { \"row\": [f_r1, f_r2], \"column\": [f_c1, f_c2] };\r\n }\r\n else{\r\n if(f_c2 > ed){\r\n f_c1 = st;\r\n f_c2 -= slen;\r\n\r\n newFilterObj.filter_select = { \"row\": [f_r1, f_r2], \"column\": [f_c1, f_c2] };\r\n }\r\n }\r\n\r\n if(newFilterObj.filter_select != null && filter != null){\r\n for(let k in filter){\r\n let f_cindex = filter[k].cindex;\r\n\r\n if(f_cindex < st){\r\n if(newFilterObj.filter == null){\r\n newFilterObj.filter = {};\r\n }\r\n\r\n newFilterObj.filter[f_cindex - f_c1] = $.extend(true, {}, filter[k]);\r\n newFilterObj.filter[f_cindex - f_c1].edc = f_c2;\r\n }\r\n else if(f_cindex > ed){\r\n f_cindex -= slen;\r\n\r\n if(newFilterObj.filter == null){\r\n newFilterObj.filter = {};\r\n }\r\n\r\n newFilterObj.filter[f_cindex - f_c1] = $.extend(true, {}, filter[k]);\r\n newFilterObj.filter[f_cindex - f_c1].cindex = f_cindex;\r\n newFilterObj.filter[f_cindex - f_c1].stc = f_c1;\r\n newFilterObj.filter[f_cindex - f_c1].edc = f_c2;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(newFilterObj != null && newFilterObj.filter != null){\r\n if(cfg[\"rowhidden\"] == null){\r\n cfg[\"rowhidden\"] = {};\r\n }\r\n\r\n for(let k in newFilterObj.filter){\r\n let f_rowhidden = newFilterObj.filter[k].rowhidden;\r\n\r\n for(let n in f_rowhidden){\r\n cfg[\"rowhidden\"][n] = 0;\r\n }\r\n }\r\n }\r\n\r\n //条件格式配置变动\r\n let CFarr = file.luckysheet_conditionformat_save;\r\n let newCFarr = [];\r\n if(CFarr != null && CFarr.length > 0){\r\n for(let i = 0; i < CFarr.length; i++){\r\n let cf_range = CFarr[i].cellrange;\r\n let cf_new_range = [];\r\n\r\n for(let j = 0; j < cf_range.length; j++){\r\n let CFr1 = cf_range[j].row[0],\r\n CFr2 = cf_range[j].row[1],\r\n CFc1 = cf_range[j].column[0],\r\n CFc2 = cf_range[j].column[1];\r\n\r\n if(type == \"row\"){\r\n if(!(CFr1 >= st && CFr2 <= ed)){\r\n if(CFr1 > ed){\r\n CFr1 -= slen;\r\n CFr2 -= slen;\r\n }\r\n else if(CFr1 < st){\r\n if(CFr2 < st){\r\n\r\n }\r\n else if(CFr2 <= ed){\r\n CFr2 = st - 1;\r\n }\r\n else{\r\n CFr2 -= slen;\r\n }\r\n }\r\n else{\r\n if(CFr2 > ed){\r\n CFr1 = st;\r\n CFr2 -= slen;\r\n }\r\n }\r\n\r\n cf_new_range.push({ \"row\": [CFr1, CFr2], \"column\": [CFc1, CFc2] });\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(!(CFc1 >= st && CFc2 <= ed)){\r\n if(CFc1 > ed){\r\n CFc1 -= slen;\r\n CFc2 -= slen;\r\n }\r\n else if(CFc1 < st){\r\n if(CFc2 < st){\r\n\r\n }\r\n else if(CFc2 <= ed){\r\n CFc2 = st - 1;\r\n }\r\n else{\r\n CFc2 -= slen;\r\n }\r\n }\r\n else{\r\n if(CFc2 > ed){\r\n CFc1 = st;\r\n CFc2 -= slen;\r\n }\r\n }\r\n\r\n cf_new_range.push({ \"row\": [CFr1, CFr2], \"column\": [CFc1, CFc2] });\r\n }\r\n }\r\n }\r\n\r\n if(cf_new_range.length > 0){\r\n let cf = $.extend(true, {}, CFarr[i]);\r\n cf.cellrange = cf_new_range;\r\n\r\n newCFarr.push(cf);\r\n }\r\n }\r\n }\r\n\r\n //交替颜色配置变动\r\n let AFarr = file.luckysheet_alternateformat_save;\r\n let newAFarr = [];\r\n if(AFarr != null && AFarr.length > 0){\r\n for(let i = 0; i < AFarr.length; i++){\r\n let AFr1 = AFarr[i].cellrange.row[0],\r\n AFr2 = AFarr[i].cellrange.row[1],\r\n AFc1 = AFarr[i].cellrange.column[0],\r\n AFc2 = AFarr[i].cellrange.column[1];\r\n\r\n if(type == \"row\"){\r\n if(!(AFr1 >= st && AFr2 <= ed)){\r\n let af = $.extend(true, {}, AFarr[i]);\r\n\r\n if(AFr1 > ed){\r\n AFr1 -= slen;\r\n AFr2 -= slen;\r\n }\r\n else if(AFr1 < st){\r\n if(AFr2 < st){\r\n\r\n }\r\n else if(AFr2 <= ed){\r\n AFr2 = st - 1;\r\n }\r\n else{\r\n AFr2 -= slen;\r\n }\r\n }\r\n else{\r\n if(AFr2 > ed){\r\n AFr1 = st;\r\n AFr2 -= slen;\r\n }\r\n }\r\n\r\n af.cellrange = { \"row\": [AFr1, AFr2], \"column\": [AFc1, AFc2] };\r\n\r\n newAFarr.push(af);\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(!(AFc1 >= st && AFc2 <= ed)){\r\n let af = $.extend(true, {}, AFarr[i]);\r\n\r\n if(AFc1 > ed){\r\n AFc1 -= slen;\r\n AFc2 -= slen;\r\n }\r\n else if(AFc1 < st){\r\n if(AFc2 < st){\r\n\r\n }\r\n else if(AFc2 <= ed){\r\n AFc2 = st - 1;\r\n }\r\n else{\r\n AFc2 -= slen;\r\n }\r\n }\r\n else{\r\n if(AFc2 > ed){\r\n AFc1 = st;\r\n AFc2 -= slen;\r\n }\r\n }\r\n\r\n af.cellrange = { \"row\": [AFr1, AFr2], \"column\": [AFc1, AFc2] };\r\n\r\n newAFarr.push(af);\r\n }\r\n }\r\n }\r\n }\r\n\r\n //冻结配置变动\r\n let newFreezen = { \"freezenhorizontaldata\": null, \"freezenverticaldata\": null };\r\n if(luckysheetFreezen.freezenhorizontaldata != null && type == \"row\"){\r\n let freezen_scrollTop = luckysheetFreezen.freezenhorizontaldata[2];\r\n let freezen_st = luckysheet_searcharray(Store.visibledatarow, freezen_scrollTop);\r\n if(freezen_st == -1){\r\n freezen_st = 0;\r\n }\r\n\r\n let freezen_row_st = luckysheetFreezen.freezenhorizontaldata[1] - 1;\r\n\r\n if(freezen_row_st >= st){\r\n if(freezen_row_st < ed){\r\n freezen_row_st = st - 1;\r\n }\r\n else{\r\n freezen_row_st -= slen;\r\n }\r\n }\r\n\r\n if(freezen_row_st < freezen_st){\r\n freezen_row_st = freezen_st;\r\n }\r\n\r\n let freezen_top = Store.visibledatarow[freezen_row_st] - 2 - freezen_scrollTop + Store.columnHeaderHeight;\r\n\r\n newFreezen.freezenhorizontaldata = [\r\n Store.visibledatarow[freezen_row_st], \r\n freezen_row_st + 1, \r\n freezen_scrollTop, \r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, freezen_row_st + 1), \r\n freezen_top\r\n ];\r\n }\r\n else{\r\n newFreezen.freezenhorizontaldata = luckysheetFreezen.freezenhorizontaldata;\r\n }\r\n\r\n if(luckysheetFreezen.freezenverticaldata != null && type == \"column\"){\r\n let freezen_scrollLeft = luckysheetFreezen.freezenverticaldata[2];\r\n let freezen_st2 = luckysheet_searcharray(Store.visibledatacolumn, freezen_scrollLeft);\r\n if(freezen_st2 == -1){\r\n freezen_st2 = 0;\r\n }\r\n\r\n let freezen_col_st = luckysheetFreezen.freezenverticaldata[1] - 1;\r\n\r\n if(freezen_col_st >= st){\r\n if(freezen_col_st < ed){\r\n freezen_col_st = st - 1;\r\n }\r\n else{\r\n freezen_col_st -= slen;\r\n }\r\n }\r\n\r\n if(freezen_col_st < freezen_st2){\r\n freezen_col_st = freezen_st2;\r\n }\r\n\r\n let freezen_left = Store.visibledatacolumn[freezen_col_st] - 2 - freezen_scrollLeft + Store.rowHeaderWidth;\r\n\r\n newFreezen.freezenverticaldata = [\r\n Store.visibledatacolumn[freezen_col_st], \r\n freezen_col_st + 1, \r\n freezen_scrollLeft, \r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, freezen_col_st + 1), \r\n freezen_left\r\n ];\r\n }\r\n else{\r\n newFreezen.freezenverticaldata = luckysheetFreezen.freezenverticaldata;\r\n }\r\n\r\n //数据验证配置变动\r\n let dataVerification = file.dataVerification;\r\n let newDataVerification = {};\r\n if(dataVerification != null){\r\n for(let key in dataVerification){\r\n let r = Number(key.split('_')[0]),\r\n c = Number(key.split('_')[1]);\r\n let item = dataVerification[key];\r\n \r\n if(type == \"row\"){\r\n if(r < st){\r\n newDataVerification[r + \"_\" + c] = item;\r\n }\r\n else if(r > ed){\r\n newDataVerification[(r - slen) + \"_\" + c] = item;\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(c < st){\r\n newDataVerification[r + \"_\" + c] = item;\r\n }\r\n else if(c > ed){\r\n newDataVerification[r + \"_\" + (c - slen)] = item;\r\n }\r\n }\r\n }\r\n }\r\n\r\n //超链接配置变动\r\n let hyperlink = file.hyperlink;\r\n let newHyperlink = {};\r\n if(hyperlink != null){\r\n for(let key in hyperlink){\r\n let r = Number(key.split('_')[0]),\r\n c = Number(key.split('_')[1]);\r\n let item = hyperlink[key];\r\n \r\n if(type == \"row\"){\r\n if(r < st){\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n else if(r > ed){\r\n newHyperlink[(r - slen) + \"_\" + c] = item;\r\n }\r\n }\r\n else if(type == \"column\"){\r\n if(c < st){\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n else if(c > ed){\r\n newHyperlink[r + \"_\" + (c - slen)] = item;\r\n }\r\n }\r\n }\r\n }\r\n\r\n //主逻辑\r\n let type1;\r\n if (type == \"row\") {\r\n type1 = \"r\";\r\n\r\n //行高配置变动\r\n if(cfg[\"rowlen\"] == null){\r\n cfg[\"rowlen\"] = {};\r\n }\r\n\r\n let rowlen_new = {};\r\n for(let r in cfg[\"rowlen\"]){\r\n if(r < st){\r\n rowlen_new[r] = cfg[\"rowlen\"][r];\r\n }\r\n else if(r > ed){\r\n rowlen_new[r - slen] = cfg[\"rowlen\"][r];\r\n }\r\n }\r\n\r\n cfg[\"rowlen\"] = rowlen_new;\r\n\r\n //隐藏行配置变动\r\n if(cfg[\"rowhidden\"] == null){\r\n cfg[\"rowhidden\"] = {};\r\n }\r\n\r\n let rowhidden_new = {};\r\n for(let r in cfg[\"rowhidden\"]){\r\n if(r < st){\r\n rowhidden_new[r] = cfg[\"rowhidden\"][r];\r\n }\r\n else if(r > ed){\r\n rowhidden_new[r - slen] = cfg[\"rowhidden\"][r];\r\n }\r\n }\r\n\r\n cfg[\"rowhidden\"] = rowhidden_new;\r\n\r\n //边框配置变动\r\n if(cfg[\"borderInfo\"] && cfg[\"borderInfo\"].length > 0){\r\n let borderInfo = []; \r\n\r\n for(let i = 0; i < cfg[\"borderInfo\"].length; i++){\r\n let rangeType = cfg[\"borderInfo\"][i].rangeType;\r\n\r\n if(rangeType == \"range\"){\r\n let borderRange = cfg[\"borderInfo\"][i].range;\r\n\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < borderRange.length; j++){\r\n let bd_r1 = borderRange[j].row[0],\r\n bd_r2 = borderRange[j].row[1];\r\n\r\n for(let r = st; r <= ed; r++){\r\n if(r < borderRange[j].row[0]){\r\n bd_r1 -= 1;\r\n bd_r2 -= 1;\r\n }\r\n else if(r <= borderRange[j].row[1]){\r\n bd_r2 -= 1;\r\n }\r\n } \r\n\r\n if(bd_r2 >= bd_r1){\r\n emptyRange.push({ \"row\": [bd_r1, bd_r2], \"column\": borderRange[j].column });\r\n } \r\n }\r\n\r\n if(emptyRange.length > 0){\r\n let bd_obj = {\r\n \"rangeType\": \"range\",\r\n \"borderType\": cfg[\"borderInfo\"][i].borderType,\r\n \"style\": cfg[\"borderInfo\"][i].style,\r\n \"color\": cfg[\"borderInfo\"][i].color,\r\n \"range\": emptyRange\r\n }\r\n\r\n borderInfo.push(bd_obj);\r\n }\r\n }\r\n else if(rangeType == \"cell\"){\r\n let row_index = cfg[\"borderInfo\"][i].value.row_index;\r\n\r\n if(row_index < st){\r\n borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n else if(row_index > ed){\r\n cfg[\"borderInfo\"][i].value.row_index = row_index - (ed - st + 1);\r\n borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"] = borderInfo;\r\n }\r\n\r\n // 备注:该处理方式会在删除多行的时候会存在bug\r\n // 说明:删除多行后,会把同一个row空数组(引用类型)添加成为data多行的数据源,导致设置这些行数据时产生错误。\r\n //空白行模板\r\n // let row = [];\r\n // for (let c = 0; c < d[0].length; c++) {\r\n // row.push(null);\r\n // }\r\n\r\n // //删除选中行\r\n // d.splice(st, slen);\r\n\r\n // //删除多少行,增加多少行空白行 \r\n // for (let r = 0; r < slen; r++) {\r\n // d.push(row);\r\n // }\r\n\r\n //删除选中行\r\n d.splice(st, slen);\r\n\r\n //删除多少行,增加多少行空白行 \r\n for (let r = 0; r < slen; r++) {\r\n let row = [];\r\n for (let c = 0; c < d[0].length; c++) {\r\n row.push(null);\r\n }\r\n d.push(row);\r\n }\r\n }\r\n else {\r\n type1 = \"c\";\r\n\r\n //列宽配置变动\r\n if(cfg[\"columnlen\"] == null){\r\n cfg[\"columnlen\"] = {};\r\n }\r\n\r\n let columnlen_new = {};\r\n for(let c in cfg[\"columnlen\"]){\r\n if(c < st){\r\n columnlen_new[c] = cfg[\"columnlen\"][c];\r\n }\r\n else if(c > ed){\r\n columnlen_new[c - slen] = cfg[\"columnlen\"][c];\r\n }\r\n }\r\n\r\n cfg[\"columnlen\"] = columnlen_new;\r\n\r\n //隐藏列配置变动\r\n if(cfg[\"colhidden\"] == null){\r\n cfg[\"colhidden\"] = {};\r\n }\r\n\r\n let colhidden_new = {};\r\n for(let c in cfg[\"colhidden\"]){\r\n if(c < st){\r\n colhidden_new[c] = cfg[\"colhidden\"][c];\r\n }\r\n else if(c > ed){\r\n colhidden_new[c - slen] = cfg[\"colhidden\"][c];\r\n }\r\n }\r\n\r\n cfg[\"colhidden\"] = colhidden_new;\r\n\r\n //边框配置变动\r\n if(cfg[\"borderInfo\"] && cfg[\"borderInfo\"].length > 0){\r\n let borderInfo = [];\r\n\r\n for(let i = 0; i < cfg[\"borderInfo\"].length; i++){\r\n let rangeType = cfg[\"borderInfo\"][i].rangeType;\r\n\r\n if(rangeType == \"range\"){\r\n let borderRange = cfg[\"borderInfo\"][i].range;\r\n\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < borderRange.length; j++){\r\n let bd_c1 = borderRange[j].column[0],\r\n bd_c2 = borderRange[j].column[1];\r\n\r\n for(let c = st; c <= ed; c++){\r\n if(c < borderRange[j].column[0]){\r\n bd_c1 -= 1;\r\n bd_c2 -= 1;\r\n }\r\n else if(c <= borderRange[j].column[1]){\r\n bd_c2 -= 1;\r\n }\r\n } \r\n\r\n if(bd_c2 >= bd_c1){\r\n emptyRange.push({ \"row\": borderRange[j].row, \"column\": [bd_c1, bd_c2] });\r\n } \r\n }\r\n\r\n if(emptyRange.length > 0){\r\n let bd_obj = {\r\n \"rangeType\": \"range\",\r\n \"borderType\": cfg[\"borderInfo\"][i].borderType,\r\n \"style\": cfg[\"borderInfo\"][i].style,\r\n \"color\": cfg[\"borderInfo\"][i].color,\r\n \"range\": emptyRange\r\n }\r\n\r\n borderInfo.push(bd_obj);\r\n }\r\n }\r\n else if(rangeType == \"cell\"){\r\n let col_index = cfg[\"borderInfo\"][i].value.col_index;\r\n\r\n if(col_index < st){\r\n borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n else if(col_index > ed){\r\n cfg[\"borderInfo\"][i].value.col_index = col_index - (ed - st + 1);\r\n borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"] = borderInfo;\r\n }\r\n \r\n //空白列模板\r\n let addcol = [];\r\n for (let r = 0; r < slen; r++) {\r\n addcol.push(null);\r\n }\r\n\r\n for (let r = 0; r < d.length; r++) {\r\n let row = [].concat(d[r]);\r\n \r\n //删除选中列\r\n row.splice(st, slen);\r\n \r\n d[r] = row.concat(addcol);\r\n }\r\n }\r\n\r\n // 修改当前sheet页时刷新\r\n if (file.index == Store.currentSheetIndex) {\r\n jfrefreshgrid_adRC(\r\n d, \r\n cfg, \r\n \"delRC\", \r\n { \"index\": st, \"len\": ed - st + 1, \"rc\": type1 }, \r\n newCalcChain, \r\n newFilterObj, \r\n newCFarr, \r\n newAFarr, \r\n newFreezen,\r\n newDataVerification,\r\n newHyperlink\r\n );\r\n }\r\n else{\r\n file.data = d;\r\n file.config = cfg;\r\n file.calcChain = newCalcChain;\r\n file.filter = newFilterObj.filter;\r\n file.filter_select = newFilterObj.filter_select;\r\n file.luckysheet_conditionformat_save = newCFarr;\r\n file.luckysheet_alternateformat_save = newAFarr;\r\n file.dataVerification = newDataVerification;\r\n file.hyperlink = newHyperlink;\r\n }\r\n}\r\n\r\n//删除单元格\r\nfunction luckysheetDeleteCell(type, str, edr, stc, edc, sheetIndex) {\r\n sheetIndex = sheetIndex || Store.currentSheetIndex;\r\n if(!checkProtectionNotEnable(sheetIndex)){\r\n return;\r\n }\r\n\r\n let curOrder = getSheetIndex(sheetIndex);\r\n let file = Store.luckysheetfile[curOrder];\r\n\r\n let d = $.extend(true, [], file.data);\r\n\r\n let rlen = edr - str + 1;\r\n let clen = edc - stc + 1;\r\n let cfg = $.extend(true, {}, Store.config);\r\n\r\n //合并单元格配置变动\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n let merge_new = {};\r\n for(let m in cfg[\"merge\"]){\r\n let mc = cfg[\"merge\"][m];\r\n\r\n let r = mc.r,\r\n c = mc.c,\r\n rs = mc.rs,\r\n cs = mc.cs;\r\n\r\n if(type == \"moveLeft\"){\r\n if(str > r + rs - 1 || edr < r || stc > c + cs - 1){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n else if(str <= r && edr >= r + rs - 1 && edc < c){\r\n merge_new[r + \"_\" + (c - clen)] = { \"r\": r, \"c\": c - clen, \"rs\": rs, \"cs\": cs };\r\n }\r\n else{\r\n for(let r_i = r; r_i <= r + rs - 1; r_i++){\r\n for(let c_i = c; c_i <= c + cs - 1; c_i++){\r\n delete d[r_i][c_i].mc;\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"moveUp\"){\r\n if(stc > c + cs - 1 || edc < c || str > r + rs - 1){\r\n merge_new[r + \"_\" + c] = { \"r\": r, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n else if(stc <= c && edc >= c + cs - 1 && edr < r){\r\n merge_new[(r - rlen) + \"_\" + c] = { \"r\": r - rlen, \"c\": c, \"rs\": rs, \"cs\": cs };\r\n }\r\n else{\r\n for(let r_i = r; r_i <= r + rs - 1; r_i++){\r\n for(let c_i = c; c_i <= c + cs - 1; c_i++){\r\n delete d[r_i][c_i].mc;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n cfg[\"merge\"] = merge_new;\r\n\r\n //公式配置变动\r\n let calcChain = file.calcChain;\r\n let newCalcChain = [];\r\n if(calcChain != null && calcChain.length > 0){\r\n for(let i = 0; i < calcChain.length; i++){\r\n let calc = $.extend(true, {}, calcChain[i]);\r\n let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = getcellFormula(calc_r, calc_c, calc_i);\r\n\r\n if(calc_r < str || calc_r > edr || calc_c < stc || calc_c > edc){\r\n let functionStr;\r\n\r\n if(type == 'moveLeft'){\r\n functionStr = \"=\" + formula.functionStrChange(calc_funcStr, \"del\", \"col\", null, stc, clen);\r\n \r\n if(calc_c > edc && calc_r >= str && calc_r <= edr){\r\n calc.c = calc_c - clen;\r\n }\r\n }\r\n else if(type == 'moveUp'){\r\n functionStr = \"=\" + formula.functionStrChange(calc_funcStr, \"del\", \"row\", null, str, rlen);\r\n \r\n if(calc_r > edr && calc_c >= stc && calc_c <= edc){\r\n calc.r = calc_r - rlen;\r\n }\r\n }\r\n\r\n if(d[calc_r][calc_c] && d[calc_r][calc_c].f == calc_funcStr){\r\n d[calc_r][calc_c].f = functionStr;\r\n }\r\n\r\n newCalcChain.push(calc);\r\n }\r\n }\r\n }\r\n\r\n //筛选配置变动\r\n let filter_select = file.filter_select;\r\n let filter = file.filter;\r\n let newFilterObj = null;\r\n if(filter_select != null && JSON.stringify(filter_select) != \"{}\"){\r\n newFilterObj = { \"filter_select\": null, \"filter\": null };\r\n\r\n let f_r1 = filter_select.row[0], f_r2 = filter_select.row[1];\r\n let f_c1 = filter_select.column[0], f_c2 = filter_select.column[1];\r\n \r\n if(type == 'moveUp'){\r\n if(f_c1 >= stc && f_c2 <= edc){\r\n if(f_r1 > edr){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1 - rlen, f_r2 - rlen],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n }\r\n else if(f_r2 < str){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n }\r\n else if(f_r1 < str){\r\n if(f_r2 > edr){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2 - rlen],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n }\r\n else{\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, str - 1],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n }\r\n }\r\n\r\n if(newFilterObj.filter_select != null && filter != null){\r\n for(let k in filter){\r\n let f_rowhidden = filter[k].rowhidden;\r\n let f_rowhidden_new = {};\r\n \r\n for(let n in f_rowhidden){\r\n if(n < str){\r\n f_rowhidden_new[n] = 0;\r\n }\r\n else if(n > edr){\r\n f_rowhidden_new[n - slen] = 0;\r\n }\r\n }\r\n\r\n if(newFilterObj.filter == null){\r\n newFilterObj.filter = {};\r\n }\r\n newFilterObj.filter[k] = $.extend(true, {}, filter[k]);\r\n \r\n if(JSON.stringify(f_rowhidden_new) != \"{}\"){\r\n newFilterObj.filter[k].rowhidden = f_rowhidden_new;\r\n }\r\n \r\n newFilterObj.filter[k].str = newFilterObj.filter_select.row[0];\r\n newFilterObj.filter[k].edr = newFilterObj.filter_select.row[1];\r\n }\r\n }\r\n }\r\n else if(f_r1 >= str && f_r2 <= edr){\r\n if(f_c1 > edc){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n }\r\n else if(f_c1 >= stc){\r\n if(f_c2 > edc){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [stc, f_c2 - clen]\r\n }\r\n }\r\n }\r\n else{\r\n if(f_c2 < stc){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n }\r\n else if(f_c2 <= edc){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, stc - 1]\r\n }\r\n }\r\n else{\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2 - clen]\r\n }\r\n }\r\n }\r\n\r\n if(newFilterObj.filter_select != null && filter != null){\r\n for(let k in filter){\r\n let f_stc = newFilterObj.filter_select.column[0];\r\n let f_edc = newFilterObj.filter_select.column[1];\r\n let f_cindex = filter[k].cindex;\r\n\r\n if(f_cindex < stc || f_cindex > edc){\r\n if(newFilterObj.filter == null){\r\n newFilterObj.filter = {};\r\n }\r\n\r\n if(f_cindex > edc){\r\n f_cindex -= clen;\r\n }\r\n\r\n let k2 = f_cindex - f_stc;\r\n\r\n newFilterObj.filter[k2] = $.extend(true, {}, filter[k]);\r\n newFilterObj.filter[k2].cindex = f_cindex;\r\n newFilterObj.filter[k2].stc = f_stc;\r\n newFilterObj.filter[k2].edc = f_edc;\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n\r\n if(filter != null){\r\n newFilterObj.filter = filter;\r\n }\r\n }\r\n }\r\n else if(type == 'moveLeft'){\r\n if(f_r1 >= str && f_r2 <= edr){\r\n if(f_c1 > edc){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1 - clen, f_c2 - clen]\r\n }\r\n }\r\n else if(f_c2 < stc){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n }\r\n else if(f_c1 < stc){\r\n if(f_c2 > edc){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2 - clen]\r\n }\r\n }\r\n else{\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, stc - 1]\r\n }\r\n }\r\n }\r\n\r\n if(newFilterObj.filter_select != null && filter != null){\r\n for(let k in filter){\r\n let f_stc = newFilterObj.filter_select.column[0];\r\n let f_edc = newFilterObj.filter_select.column[1];\r\n let f_cindex = filter[k].cindex;\r\n\r\n if(f_cindex < stc || f_cindex > edc){\r\n if(newFilterObj.filter == null){\r\n newFilterObj.filter = {};\r\n }\r\n\r\n if(f_cindex > edc){\r\n f_cindex -= clen;\r\n }\r\n\r\n let k2 = f_cindex - f_stc;\r\n\r\n newFilterObj.filter[k2] = $.extend(true, {}, filter[k]);\r\n newFilterObj.filter[k2].cindex = f_cindex;\r\n newFilterObj.filter[k2].stc = f_stc;\r\n newFilterObj.filter[k2].edc = f_edc;\r\n }\r\n }\r\n }\r\n }\r\n else if(f_c1 >= stc && f_c2 <= edc){\r\n if(f_r1 < str || f_r1 > edr){\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n\r\n if(filter != null){\r\n newFilterObj.filter = filter;\r\n }\r\n }\r\n }\r\n else{\r\n newFilterObj.filter_select = {\r\n \"row\": [f_r1, f_r2],\r\n \"column\": [f_c1, f_c2]\r\n }\r\n\r\n if(filter != null){\r\n newFilterObj.filter = filter;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(newFilterObj != null && newFilterObj.filter != null){\r\n if(cfg[\"rowhidden\"] == null){\r\n cfg[\"rowhidden\"] = {};\r\n }\r\n\r\n for(let k in newFilterObj.filter){\r\n let f_rowhidden = newFilterObj.filter[k].rowhidden;\r\n\r\n for(let n in f_rowhidden){\r\n cfg[\"rowhidden\"][n] = 0;\r\n }\r\n }\r\n }\r\n\r\n //条件格式配置变动\r\n let CFarr = file.luckysheet_conditionformat_save;\r\n let newCFarr = [];\r\n if(CFarr != null && CFarr.length > 0){\r\n for(let i = 0; i < CFarr.length; i++){\r\n let cf_range = CFarr[i].cellrange;\r\n let cf_new_range = [];\r\n\r\n for(let j = 0; j < cf_range.length; j++){\r\n let CFr1 = cf_range[j].row[0],\r\n CFr2 = cf_range[j].row[1],\r\n CFc1 = cf_range[j].column[0],\r\n CFc2 = cf_range[j].column[1];\r\n \r\n if(!(str <= CFr1 && edr >= CFr2 && stc <= CFc1 && edc >= CFc2)){\r\n cf_new_range = getMoveRange(type, str, edr, stc, edc, CFr1, CFr2, CFc1, CFc2, rlen, clen);\r\n }\r\n }\r\n\r\n if(cf_new_range.length > 0){\r\n let cf = $.extend(true, {}, CFarr[i]);\r\n cf.cellrange = cf_new_range;\r\n\r\n newCFarr.push(cf);\r\n }\r\n }\r\n }\r\n\r\n //数据验证配置变动\r\n let dataVerification = file.dataVerification;\r\n let newDataVerification = {};\r\n if(dataVerification != null){\r\n for(let key in dataVerification){\r\n let r = Number(key.split('_')[0]),\r\n c = Number(key.split('_')[1]);\r\n let item = dataVerification[key];\r\n\r\n if(r < str || r > edr || c < stc || c > edc){\r\n if(type == \"moveLeft\"){\r\n if(c > edc && r >= str && r <= edr){\r\n newDataVerification[r + \"_\" + (c - clen)] = item;\r\n }\r\n else{\r\n newDataVerification[r + \"_\" + c] = item;\r\n }\r\n }\r\n else if(type == \"moveUp\"){\r\n if(r > edr && c >= stc && c <= edc){\r\n newDataVerification[(r - rlen) + \"_\" + c] = item;\r\n }\r\n else{\r\n newDataVerification[r + \"_\" + c] = item;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n //超链接配置变动\r\n let hyperlink = file.hyperlink;\r\n let newHyperlink = {};\r\n if(hyperlink != null){\r\n for(let key in hyperlink){\r\n let r = Number(key.split('_')[0]),\r\n c = Number(key.split('_')[1]);\r\n let item = hyperlink[key];\r\n\r\n if(r < str || r > edr || c < stc || c > edc){\r\n if(type == \"moveLeft\"){\r\n if(c > edc && r >= str && r <= edr){\r\n newHyperlink[r + \"_\" + (c - clen)] = item;\r\n }\r\n else{\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n }\r\n else if(type == \"moveUp\"){\r\n if(r > edr && c >= stc && c <= edc){\r\n newHyperlink[(r - rlen) + \"_\" + c] = item;\r\n }\r\n else{\r\n newHyperlink[r + \"_\" + c] = item;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n //边框配置变动\r\n if(cfg[\"borderInfo\"] && cfg[\"borderInfo\"].length > 0){\r\n let borderInfo = []; \r\n\r\n for(let i = 0; i < cfg[\"borderInfo\"].length; i++){\r\n let rangeType = cfg[\"borderInfo\"][i].rangeType;\r\n\r\n if(rangeType == \"range\"){\r\n let borderRange = cfg[\"borderInfo\"][i].range;\r\n\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < borderRange.length; j++){\r\n let bd_r1 = borderRange[j].row[0],\r\n bd_r2 = borderRange[j].row[1],\r\n bd_c1 = borderRange[j].column[0],\r\n bd_c2 = borderRange[j].column[1];\r\n\r\n if(!(str <= bd_r1 && edr >= bd_r2 && stc <= bd_c1 && edc >= bd_c2)){\r\n emptyRange = getMoveRange(type, str, edr, stc, edc, bd_r1, bd_r2, bd_c1, bd_c2, rlen, clen);\r\n }\r\n }\r\n\r\n if(emptyRange.length > 0){\r\n let bd_obj = {\r\n \"rangeType\": \"range\",\r\n \"borderType\": cfg[\"borderInfo\"][i].borderType,\r\n \"style\": cfg[\"borderInfo\"][i].style,\r\n \"color\": cfg[\"borderInfo\"][i].color,\r\n \"range\": emptyRange\r\n }\r\n\r\n borderInfo.push(bd_obj);\r\n }\r\n }\r\n else if(rangeType == \"cell\"){\r\n let row_index = cfg[\"borderInfo\"][i].value.row_index;\r\n let col_index = cfg[\"borderInfo\"][i].value.col_index;\r\n\r\n if(row_index < str || row_index > edr || col_index < stc || col_index > edc){\r\n if(type == 'moveLeft'){\r\n if(col_index > edc && row_index >= str && row_index <= edr){\r\n col_index -= clen;\r\n cfg[\"borderInfo\"][i].value.col_index = col_index;\r\n }\r\n }\r\n else if(type == 'moveUp'){\r\n if(row_index > edr && col_index >= stc && col_index <= edc){\r\n row_index -= rlen;\r\n cfg[\"borderInfo\"][i].value.row_index = row_index;\r\n }\r\n }\r\n \r\n borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"] = borderInfo;\r\n }\r\n \r\n //空白列模板\r\n let addcol = [];\r\n for (let c = stc; c <= edc; c++) {\r\n addcol.push(null);\r\n }\r\n\r\n if(type == 'moveUp'){//上移\r\n let data = [];\r\n\r\n for(let r = str; r <= d.length - 1; r++){\r\n let row = [];\r\n\r\n for(let c = stc; c <= edc; c++){\r\n row.push(d[r][c]);\r\n }\r\n\r\n data.push(row);\r\n }\r\n\r\n data.splice(0, rlen);\r\n\r\n //空白行模板\r\n let addrow = [];\r\n for (let r = str; r <= edr; r++) {\r\n addrow.push(addcol);\r\n }\r\n\r\n data = data.concat(addrow);\r\n\r\n for(let r = str; r <= d.length - 1; r++){\r\n for(let c = stc; c <= edc; c++){\r\n d[r][c] = data[r - str][c - stc];\r\n }\r\n }\r\n }\r\n else if(type == 'moveLeft'){//左移\r\n for(let r = str; r <= edr; r++){\r\n d[r].splice(stc, clen);\r\n d[r] = d[r].concat(addcol);\r\n }\r\n }\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n jfrefreshgrid_deleteCell(\r\n d,\r\n cfg,\r\n { type: type, 'str': str, 'edr': edr, 'stc': stc, 'edc': edc },\r\n newCalcChain,\r\n newFilterObj,\r\n newCFarr,\r\n newDataVerification,\r\n newHyperlink\r\n );\r\n }\r\n else{\r\n file.data = d;\r\n file.config = cfg;\r\n file.calcChain = newCalcChain;\r\n file.filter = newFilterObj.filter;\r\n file.filter_select = newFilterObj.filter_select;\r\n file.luckysheet_conditionformat_save = newCFarr;\r\n file.dataVerification = newDataVerification;\r\n file.hyperlink = newHyperlink;\r\n }\r\n}\r\n\r\nfunction getMoveRange(type, str, edr, stc, edc, r1, r2, c1, c2, rlen, clen) {\r\n let newRange = [];\r\n\r\n if(type == \"moveLeft\"){\r\n if(str > r2 || edr < r1 || stc > c2){\r\n newRange.push({\r\n \"row\": [r1, r2],\r\n \"column\": [c1, c2]\r\n });\r\n }\r\n else if(edc < c1){\r\n if(str <= r1 && edr >= r2){\r\n newRange.push({\r\n \"row\": [r1, r2],\r\n \"column\": [c1 - clen, c2 - clen]\r\n });\r\n }\r\n else if(str > r1 && edr < r2){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [str, edr], \"column\": [c1 - clen, c2 - clen] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(str > r1){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [str, r2], \"column\": [c1 - clen, c2 - clen] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edr < r2){\r\n let range= [\r\n { \"row\": [r1, edr], \"column\": [c1 - clen, c2 - clen] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(edc >= c1){\r\n if(stc <= c1 && edc >= c2){\r\n if(str > r1 && edr < r2){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(str > r1){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edr < r2){\r\n let range= [\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(stc > c1 && edc < c2){\r\n if(str <= r1 && edr >= r2){\r\n newRange.push({\r\n \"row\": [r1, r2],\r\n \"column\": [c1, c2 - clen]\r\n });\r\n }\r\n else if(str > r1 && edr < r2){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [str, edr], \"column\": [c1, c2 - clen] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(str > r1){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [str, r2], \"column\": [c1, c2 - clen] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edr < r2){\r\n let range= [\r\n { \"row\": [r1, edr], \"column\": [c1, c2 - clen] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(stc > c1){\r\n if(str <= r1 && edr >= r2){\r\n newRange.push({\r\n \"row\": [r1, r2],\r\n \"column\": [c1, stc - 1]\r\n });\r\n }\r\n else if(str > r1 && edr < r2){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [str, edr], \"column\": [c1, stc - 1] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(str > r1){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [str, r2], \"column\": [c1, stc - 1] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edr < r2){\r\n let range= [\r\n { \"row\": [r1, edr], \"column\": [c1, stc - 1] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(edc < c2){\r\n if(str <= r1 && edr >= r2){\r\n newRange.push({\r\n \"row\": [r1, r2],\r\n \"column\": [c1 - clen, c2 - clen]\r\n });\r\n }\r\n else if(str > r1 && edr < r2){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [str, edr], \"column\": [c1 - clen, c2 - clen] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(str > r1){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, c2] },\r\n { \"row\": [str, r2], \"column\": [c1 - clen, c2 - clen] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edr < r2){\r\n let range= [\r\n { \"row\": [r1, edr], \"column\": [c1 - clen, c2 - clen] },\r\n { \"row\": [edr + 1, r2], \"column\": [c1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"moveUp\"){\r\n if(stc > c2 || edc < c1 || str > r2){\r\n newRange.push({\r\n \"row\": [r1, r2],\r\n \"column\": [c1, c2]\r\n });\r\n }\r\n else if(edr < r1){\r\n if(stc <= c1 && edc >= c2){\r\n newRange.push({\r\n \"row\": [r1 - rlen, r2 - rlen],\r\n \"column\": [c1, c2]\r\n });\r\n }\r\n else if(stc > c1 && edc < c2){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n { \"row\": [r1 - rlen, r2 - rlen], \"column\": [stc, edc] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(stc > c1){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1 - rlen, r2 - rlen], \"column\": [stc, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edc < c2){\r\n let range= [\r\n { \"row\": [r1 - rlen, r2 - rlen], \"column\": [c1, edc] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(edr >= r1){\r\n if(str <= r1 && edr >= r2){\r\n if(stc > c1 && edc < c2){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(stc > c1){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edc < c2){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(str > r1 && edr < r2){\r\n if(stc <= c1 && edc >= c2){\r\n newRange.push({\r\n \"row\": [r1, r2 - rlen],\r\n \"column\": [c1, c2]\r\n });\r\n }\r\n else if(stc > c1 && edc < c2){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n { \"row\": [r1, r2 - rlen], \"column\": [stc, edc] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(stc > c1){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1, r2 - rlen], \"column\": [stc, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edc < c2){\r\n let range= [\r\n { \"row\": [r1, r2 - rlen], \"column\": [c1, edc] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(str > r1){\r\n if(stc <= c1 && edc >= c2){\r\n newRange.push({\r\n \"row\": [r1, str - 1],\r\n \"column\": [c1, c2]\r\n });\r\n }\r\n else if(stc > c1 && edc < c2){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n { \"row\": [r1, str - 1], \"column\": [stc, edc] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(stc > c1){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1, str - 1], \"column\": [stc, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edc < c2){\r\n let range= [\r\n { \"row\": [r1, str - 1], \"column\": [c1, edc] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n else if(edr < r2){\r\n if(stc <= c1 && edc >= c2){\r\n newRange.push({\r\n \"row\": [r1 - rlen, r2 - rlen],\r\n \"column\": [c1, c2]\r\n });\r\n }\r\n else if(stc > c1 && edc < c2){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n { \"row\": [r1 - rlen, r2 - rlen], \"column\": [stc, edc] }\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(stc > c1){\r\n let range= [\r\n { \"row\": [r1, r2], \"column\": [c1, stc - 1] },\r\n { \"row\": [r1 - rlen, r2 - rlen], \"column\": [stc, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n else if(edc < c2){\r\n let range= [\r\n { \"row\": [r1 - rlen, r2 - rlen], \"column\": [c1, edc] },\r\n { \"row\": [r1, r2], \"column\": [edc + 1, c2] },\r\n ];\r\n newRange = newRange.concat(range);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return newRange;\r\n}\r\n\r\nexport {\r\n luckysheetextendtable,\r\n luckysheetextendData,\r\n luckysheetdeletetable,\r\n luckysheetDeleteCell,\r\n}","import server from '../controllers/server';\r\nimport { luckysheetlodingHTML, luckyColor } from '../controllers/constant';\r\nimport sheetmanage from '../controllers/sheetmanage';\r\nimport luckysheetformula from './formula';\r\nimport imageCtrl from '../controllers/imageCtrl';\r\nimport dataVerificationCtrl from '../controllers/dataVerificationCtrl';\r\nimport pivotTable from '../controllers/pivotTable';\r\nimport luckysheetFreezen from '../controllers/freezen';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { luckysheetextendData } from './extend';\r\nimport luckysheetConfigsetting from '../controllers/luckysheetConfigsetting';\r\nimport editor from './editor';\r\nimport luckysheetcreatesheet from './createsheet';\r\nimport Store from '../store';\r\n\r\nconst defaultConfig = {\r\n defaultStore:{\r\n container: null, \r\n luckysheetfile: null, \r\n defaultcolumnNum: 60, \r\n defaultrowNum: 84, \r\n fullscreenmode: true,\r\n devicePixelRatio: 1,\r\n \r\n currentSheetIndex: 0,\r\n calculateSheetIndex: 0,\r\n flowdata: [],\r\n config: {},\r\n \r\n visibledatarow: [],\r\n visibledatacolumn: [],\r\n ch_width: 0,\r\n rh_height: 0,\r\n \r\n cellmainWidth: 0,\r\n cellmainHeight: 0,\r\n toolbarHeight: 0,\r\n infobarHeight: 0,\r\n calculatebarHeight: 0,\r\n rowHeaderWidth: 46,\r\n columnHeaderHeight: 20,\r\n cellMainSrollBarSize: 12,\r\n sheetBarHeight: 31,\r\n statisticBarHeight: 23,\r\n luckysheetTableContentHW: [0, 0], \r\n \r\n defaultcollen: 73,\r\n defaultrowlen: 19,\r\n \r\n jfcountfuncTimeout: null, \r\n jfautoscrollTimeout: null,\r\n \r\n luckysheet_select_status: false,\r\n luckysheet_select_save: [{ \"row\": [0, 0], \"column\": [0, 0] }],\r\n luckysheet_selection_range: [],\r\n \r\n luckysheet_copy_save: {}, //复制粘贴\r\n luckysheet_paste_iscut: false,\r\n \r\n filterchage: true, //筛选\r\n luckysheet_filter_save: { \"row\": [], \"column\": [] },\r\n \r\n luckysheet_sheet_move_status: false,\r\n luckysheet_sheet_move_data: [],\r\n luckysheet_scroll_status: false,\r\n \r\n luckysheetisrefreshdetail: true,\r\n luckysheetisrefreshtheme: true,\r\n luckysheetcurrentisPivotTable: false,\r\n \r\n luckysheet_rows_selected_status: false, //行列标题相关参\r\n luckysheet_cols_selected_status: false, \r\n luckysheet_rows_change_size: false,\r\n luckysheet_rows_change_size_start: [],\r\n luckysheet_cols_change_size: false,\r\n luckysheet_cols_change_size_start: [],\r\n luckysheet_cols_dbclick_timeout: null,\r\n luckysheet_cols_dbclick_times: 0,\r\n \r\n luckysheetCellUpdate: [],\r\n \r\n luckysheet_shiftpositon: null,\r\n \r\n iscopyself: true,\r\n \r\n orderbyindex: 0, //排序下标\r\n \r\n luckysheet_model_move_state: false, //模态框拖动\r\n luckysheet_model_xy: [0, 0],\r\n luckysheet_model_move_obj: null,\r\n \r\n luckysheet_cell_selected_move: false, //选区拖动替换\r\n luckysheet_cell_selected_move_index: [],\r\n \r\n luckysheet_cell_selected_extend: false, //选区下拉\r\n luckysheet_cell_selected_extend_index: [],\r\n luckysheet_cell_selected_extend_time: null,\r\n \r\n clearjfundo: true,\r\n jfredo: [],\r\n jfundo: [],\r\n lang: 'en', //language\r\n createChart: '',\r\n highlightChart: '',\r\n zIndex: 15,\r\n chartparam: {\r\n luckysheetCurrentChart: null, //current chart_id\r\n luckysheetCurrentChartActive: false,\r\n luckysheetCurrentChartMove: null, // Debounce state\r\n luckysheetCurrentChartMoveTimeout: null,//拖动图表框的节流定时器\r\n luckysheetCurrentChartMoveObj: null, //chart DOM object\r\n luckysheetCurrentChartMoveXy: null, //上一次操作结束的图表信息,x,y: chart框位置,scrollLeft1,scrollTop1: 滚动条位置\r\n luckysheetCurrentChartMoveWinH: null, //左右滚动条滑动距离\r\n luckysheetCurrentChartMoveWinW: null, //上下滚动条滑动距离\r\n luckysheetCurrentChartResize: null,\r\n luckysheetCurrentChartResizeObj: null,\r\n luckysheetCurrentChartResizeXy: null,\r\n luckysheetCurrentChartResizeWinH: null,\r\n luckysheetCurrentChartResizeWinW: null,\r\n luckysheetInsertChartTosheetChange: true, // 正在执行撤销\r\n luckysheetCurrentChartZIndexRank : 100,\r\n luckysheet_chart_redo_click:false, //撤销重做时标识\r\n luckysheetCurrentChartMaxState: false, //图表全屏状态\r\n jfrefreshchartall: '',\r\n changeChartCellData: '',\r\n renderChart: '',\r\n getChartJson: ''\r\n },\r\n functionList:null, //function list explanation\r\n luckysheet_function:null,\r\n chart_selection: {},\r\n currentChart: '',\r\n scrollRefreshSwitch:true,\r\n \r\n measureTextCache:{},\r\n measureTextCellInfoCache:{},\r\n measureTextCacheTimeOut:null,\r\n cellOverflowMapCache:{},\r\n \r\n zoomRatio:1,\r\n \r\n visibledatacolumn_unique:null,\r\n visibledatarow_unique:null,\r\n \r\n showGridLines:true,\r\n \r\n toobarObject: {}, //toolbar constant\r\n inlineStringEditCache:null,\r\n inlineStringEditRange:null,\r\n \r\n fontList:[],\r\n\r\n currentSheetView:\"viewNormal\",\r\n \r\n }, \r\n defaultFormula:{\r\n searchFunctionCell: null,\r\n functionlistPosition: {},\r\n rangechangeindex: null,\r\n rangestart: false,\r\n rangetosheet: null,\r\n rangeSetValueTo: null,\r\n func_selectedrange: {}, //函数选区范围\r\n rangedrag_column_start: false,\r\n rangedrag_row_start: false,\r\n rangeResizeObj: null,\r\n rangeResize: null,\r\n rangeResizeIndex: null,\r\n rangeResizexy: null,\r\n rangeResizeWinH: null,\r\n rangeResizeWinW: null,\r\n rangeResizeTo: null,\r\n rangeMovexy: null,\r\n rangeMove: false,\r\n rangeMoveObj: null,\r\n rangeMoveIndex: null,\r\n rangeMoveRangedata: null,\r\n functionHTMLIndex: 0,\r\n functionRangeIndex: null,\r\n execvertex: {},\r\n execFunctionGroupData: null,\r\n execFunctionExist: null,\r\n formulaContainSheetList:{},\r\n cellTextToIndexList:{},\r\n isFunctionRangeSave: false,\r\n execvertex: {},\r\n execFunctionGroupData: null,\r\n execFunctionExist: null,\r\n formulaContainSheetList:{},\r\n formulaContainCellList:{},\r\n cellTextToIndexList:{},\r\n execFunctionGlobalData:{},\r\n groupValuesRefreshData: [],\r\n functionResizeData: {},\r\n functionResizeStatus: false,\r\n functionResizeTimeout: null,\r\n data_parm_index: 0 //选择公式后参数索引标记\r\n },\r\n defaultSheet:{\r\n sheetMaxIndex: 0,\r\n nulldata: null,\r\n mergeCalculationSheet:{},\r\n checkLoadSheetIndexToDataIndex:{},\r\n CacheNotLoadControll:[],\r\n },\r\n defaultPivotTable:{\r\n pivotDatas: null,\r\n pivotSheetIndex: 0,\r\n pivotDataSheetIndex: 0,\r\n celldata: null,\r\n origindata: null,\r\n pivot_data_type: {},\r\n pivot_select_save: null,\r\n column: null,\r\n row: null,\r\n values: null,\r\n filter: null,\r\n showType: null,\r\n rowhidden: null,\r\n selected: null,\r\n caljs: null,\r\n initial: true,\r\n filterparm: null,\r\n luckysheet_pivotTable_select_state: false,\r\n jgridCurrentPivotInput: null,\r\n movestate: false,\r\n moveitemposition: [],\r\n movesave: {},\r\n drawPivotTable: true,\r\n pivotTableBoundary: [12, 6],\r\n },\r\n defaultImage:{\r\n imgItem: {\r\n type: '3', //1移动并调整单元格大小 2移动并且不调整单元格的大小 3不要移动单元格并调整其大小\r\n src: '', //图片url\r\n originWidth: null, //图片原始宽度\r\n originHeight: null, //图片原始高度\r\n default: {\r\n width: null, //图片 宽度\r\n height: null, //图片 高度\r\n left: null, //图片离表格左边的 位置\r\n top: null, //图片离表格顶部的 位置\r\n },\r\n crop: {\r\n width: null, //图片裁剪后 宽度\r\n height: null, //图片裁剪后 高度\r\n offsetLeft: 0, //图片裁剪后离未裁剪时 左边的位移\r\n offsetTop: 0, //图片裁剪后离未裁剪时 顶部的位移\r\n },\r\n isFixedPos: false, //固定位置\r\n fixedLeft: null, //固定位置 左位移\r\n fixedTop: null, //固定位置 右位移\r\n border: {\r\n width: 0, //边框宽度\r\n radius: 0, //边框半径\r\n style: 'solid', //边框类型\r\n color: '#000', //边框颜色\r\n }\r\n },\r\n images: null,\r\n currentImgId: null,\r\n currentWinW: null,\r\n currentWinH: null,\r\n resize: null, \r\n resizeXY: null,\r\n move: false,\r\n moveXY: null,\r\n cropChange: null, \r\n cropChangeXY: null,\r\n cropChangeObj: null,\r\n copyImgItemObj: null,\r\n },\r\n defaultDataVerification:{\r\n defaultItem: {\r\n type: 'dropdown', //类型\r\n type2: null, //\r\n value1: '', //\r\n value2: '', //\r\n checked: false,\r\n remote: false, //自动远程获取选项\r\n prohibitInput: false, //输入数据无效时禁止输入\r\n hintShow: false, //选中单元格时显示提示语\r\n hintText: '', //\r\n },\r\n curItem: null,\r\n dataVerification: null,\r\n selectRange: [],\r\n selectStatus: false,\r\n }\r\n}\r\n\r\nconst method = {\r\n //翻页\r\n addDataAjax: function(param, index, url, func){\r\n let _this = this;\r\n\r\n if(index == null){\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n if(url == null){\r\n url = server.loadSheetUrl;\r\n }\r\n\r\n $(\"#luckysheet-grid-window-1\").append(luckysheetlodingHTML());\r\n param.currentPage++;\r\n \r\n let dataType = 'application/json;charset=UTF-8';\r\n let token = sessionStorage.getItem('x-auth-token');\r\n\r\n $.ajax({\r\n method: 'POST',\r\n url: url,\r\n headers: { \"x-auth-token\": token },\r\n data: JSON.stringify(param),\r\n contentType: dataType,\r\n success: function(d) {\r\n //d可能为json字符串\r\n if(typeof d == \"string\"){\r\n d = JSON.parse(d);\r\n }\r\n\r\n let dataset = d.data;\r\n \r\n let newData = dataset.celldata;\r\n luckysheetextendData(dataset[\"row\"], newData);\r\n\r\n setTimeout(function(){\r\n $(\"#luckysheetloadingdata\").fadeOut().remove();\r\n }, 500);\r\n\r\n if(func && typeof(func)==\"function\"){ \r\n func(dataset);\r\n }\r\n }\r\n })\r\n },\r\n //重载\r\n reload: function(param, index, url, func){\r\n let _this = this;\r\n\r\n if(index == null){\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n if(url == null){\r\n url = server.loadSheetUrl;\r\n }\r\n\r\n $(\"#luckysheet-grid-window-1\").append(luckysheetlodingHTML());\r\n\r\n let arg = {\"gridKey\" : server.gridKey, \"index\": index};\r\n param = $.extend(true, param, arg);\r\n let file = Store.luckysheetfile[getSheetIndex(index)];\r\n\r\n $.post(url, param, function (d) {\r\n let dataset = new Function(\"return \" + d)();\r\n file.celldata = dataset[index.toString()];\r\n let data = sheetmanage.buildGridData(file);\r\n\r\n setTimeout(function(){\r\n $(\"#luckysheetloadingdata\").fadeOut().remove();\r\n }, 500);\r\n\r\n file[\"data\"] = data;\r\n Store.flowdata = data;\r\n editor.webWorkerFlowDataCache(data);//worker存数据\r\n\r\n luckysheetcreatesheet(data[0].length, data.length, data, null, false);\r\n file[\"load\"] = \"1\";\r\n\r\n Store.luckysheet_select_save.length = 0;\r\n Store.luckysheet_selection_range = [];\r\n\r\n server.saveParam(\"shs\", null, Store.currentSheetIndex);\r\n\r\n sheetmanage.changeSheet(index);\r\n\r\n if(func && typeof(func)==\"function\"){ \r\n func();\r\n }\r\n });\r\n },\r\n clearSheetByIndex: function(i){\r\n let index = getSheetIndex(i);\r\n let sheetfile = Store.luckysheetfile[index];\r\n\r\n if(!sheetfile.isPivotTable){\r\n sheetfile.data = [];\r\n sheetfile.row = Store.defaultrowNum;\r\n sheetfile.column = Store.defaultcolumnNum;\r\n\r\n sheetfile.chart = [];\r\n sheetfile.config = null;\r\n sheetfile.filter = null;\r\n sheetfile.filter_select = null;\r\n sheetfile.celldata = [];\r\n sheetfile.pivotTable = {};\r\n sheetfile.calcChain = [];\r\n sheetfile.status = 0;\r\n sheetfile.load = 0;\r\n\r\n Store.flowdata = [];\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n $(\"#\"+ Store.container +\" .luckysheet-data-visualization-chart\").remove();\r\n $(\"#\"+ Store.container +\" .luckysheet-datavisual-selection-set\").remove();\r\n\r\n $(\"#luckysheet-row-count-show, #luckysheet-formula-functionrange-select, #luckysheet-row-count-show, #luckysheet-column-count-show, #luckysheet-change-size-line, #luckysheet-cell-selected-focus, #luckysheet-selection-copy, #luckysheet-cell-selected-extend, #luckysheet-cell-selected-move, #luckysheet-cell-selected\").hide();\r\n\r\n delete sheetfile.load;\r\n }\r\n else {\r\n delete Store.luckysheetfile[index];\r\n }\r\n },\r\n clear: function(index){\r\n let _this = this;\r\n\r\n if(index == \"all\"){\r\n for(let i = 0; i < Store.luckysheetfile.length; i++){\r\n let sheetfile = Store.luckysheetfile[i];\r\n _this.clearSheetByIndex(sheetfile.index);\r\n }\r\n \r\n }\r\n else{\r\n if(index == null){\r\n index = Store.currentSheetIndex;\r\n }\r\n _this.clearSheetByIndex(index);\r\n }\r\n\r\n sheetmanage.changeSheet(Store.luckysheetfile[0].index);\r\n },\r\n destroy:function(){\r\n $(\"#\" + Store.container).empty();\r\n $(\"body > .luckysheet-cols-menu\").remove();\r\n\r\n $(\"#luckysheet-modal-dialog-mask, #luckysheetTextSizeTest, #luckysheet-icon-morebtn-div\").remove();\r\n $(\"#luckysheet-input-box\").parent().remove();\r\n $(\"#luckysheet-formula-help-c\").remove();\r\n $(\".chartSetting, .luckysheet-modal-dialog-slider\").remove();\r\n\r\n //document event release\r\n $(document).off(\".luckysheetEvent\");\r\n $(document).off(\".luckysheetProtection\");\r\n \r\n //参数重置\r\n luckysheetFreezen.initialHorizontal = true;\r\n luckysheetFreezen.initialVertical = true;\r\n\r\n let defaultStore = $.extend(true, {}, defaultConfig.defaultStore);\r\n for(let key in defaultStore){\r\n if(key in Store){\r\n Store[key] = defaultStore[key];\r\n }\r\n }\r\n\r\n let defaultFormula = $.extend(true, {}, defaultConfig.defaultFormula);\r\n for(let key in defaultFormula){\r\n if(key in luckysheetformula){\r\n luckysheetformula[key] = defaultFormula[key];\r\n }\r\n }\r\n\r\n let defaultSheet = $.extend(true, {}, defaultConfig.defaultSheet);\r\n for(let key in defaultSheet){\r\n if(key in sheetmanage){\r\n sheetmanage[key] = defaultSheet[key];\r\n }\r\n }\r\n\r\n let defaultPivotTable = $.extend(true, {}, defaultConfig.defaultPivotTable);\r\n for(let key in defaultPivotTable){\r\n if(key in pivotTable){\r\n pivotTable[key] = defaultPivotTable[key];\r\n }\r\n }\r\n\r\n let defaultImage = $.extend(true, {}, defaultConfig.defaultImage);\r\n for(let key in defaultImage){\r\n if(key in imageCtrl){\r\n imageCtrl[key] = defaultImage[key];\r\n }\r\n }\r\n\r\n let defaultDataVerification = $.extend(true, {}, defaultConfig.defaultDataVerification);\r\n for(let key in defaultDataVerification){\r\n if(key in dataVerificationCtrl){\r\n dataVerificationCtrl[key] = defaultDataVerification[key];\r\n }\r\n }\r\n\r\n // remove proxy\r\n Store.asyncLoad = ['core'];\r\n },\r\n editorChart:function(c){\r\n let chart_selection_color = luckyColor[0];\r\n let chart_id = \"luckysheetEditMode-datav-chart\";\r\n let chart_selection_id = chart_id + \"_selection\";\r\n c.chart_id = chart_id;\r\n let chartTheme = c.chartTheme;\r\n chartTheme = chartTheme == null ? \"default0000\" : chartTheme;\r\n\r\n luckysheet.insertChartTosheet(c.sheetIndex, c.dataSheetIndex, c.option, c.chartType, c.selfOption, c.defaultOption, c.row, c.column, chart_selection_color, chart_id, chart_selection_id, c.chartStyle, c.rangeConfigCheck, c.rangeRowCheck, c.rangeColCheck, c.chartMarkConfig, c.chartTitleConfig, c.winWidth, c.winHeight, c.scrollLeft, c.scrollTop, chartTheme, c.myWidth, c.myHeight, c.myLeft!=null?parseFloat(c.myLeft):null, c.myTop!=null?parseFloat(c.myTop):null, c.myindexrank, true);\r\n\r\n $(\"#\"+chart_id).find(\".luckysheet-modal-controll-update\").click();\r\n },\r\n /**\r\n * 获取单元格的值\r\n * @param {name} 函数名称\r\n * @param {arguments} 函数参数\r\n */\r\n createHookFunction:function(){\r\n let hookName = arguments[0];\r\n if(luckysheetConfigsetting.hook && luckysheetConfigsetting.hook[hookName]!=null && (typeof luckysheetConfigsetting.hook[hookName] == \"function\")){\r\n var args = Array.prototype.slice.apply(arguments);\r\n args.shift();\r\n let ret = luckysheetConfigsetting.hook[hookName].apply(this, args);\r\n if(ret===false){\r\n return false;\r\n }\r\n else{\r\n return true;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n}\r\n\r\nexport default method;","import { datagridgrowth } from './getdata';\r\nimport editor from './editor';\r\nimport rhchInit from './rhchInit';\r\nimport formula from './formula';\r\nimport { luckysheetrefreshgrid } from './refresh';\r\nimport sheetmanage from '../controllers/sheetmanage';\r\nimport Store from '../store';\r\n\r\nexport default function luckysheetcreatesheet(colwidth, rowheight, data, cfg, active) {\r\n if(active == null){\r\n active = true;\r\n }\r\n\r\n Store.visibledatarow = [];\r\n Store.visibledatacolumn = [];\r\n Store.ch_width = 0;\r\n Store.rh_height = 0;\r\n Store.zoomRatio = 1;\r\n\r\n if(cfg != null){\r\n Store.config = cfg;\r\n }\r\n else{\r\n Store.config = {};\r\n }\r\n\r\n if (data.length == 0) {\r\n Store.flowdata = datagridgrowth(data, rowheight, colwidth);\r\n }\r\n else if (data.length < rowheight && data[0].length < colwidth) {\r\n Store.flowdata = datagridgrowth(data, rowheight - data.length, colwidth - data[0].length);\r\n }\r\n else if (data.length < rowheight) {\r\n Store.flowdata = datagridgrowth(data, rowheight - data.length, 0);\r\n }\r\n else if (data[0].length < colwidth) {\r\n Store.flowdata = datagridgrowth(data, 0, colwidth - data[0].length);\r\n }\r\n else {\r\n Store.flowdata = data;\r\n }\r\n\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n rhchInit(rowheight, colwidth);\r\n\r\n if(active){\r\n sheetmanage.showSheet();\r\n\r\n setTimeout(function () {\r\n sheetmanage.restoreCache();\r\n formula.execFunctionGroup();\r\n sheetmanage.restoreSheetAll(Store.currentSheetIndex);\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n}\r\n","import { rowLocation, colLocation, mouseposition } from '../global/location';\r\nimport editor from '../global/editor';\r\nimport formula from '../global/formula';\r\nimport { luckysheetRangeLast } from '../global/cursorPos';\r\nimport { luckysheetrefreshgrid } from '../global/refresh';\r\nimport { setluckysheet_scroll_status } from '../methods/set';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { getObjType } from '../utils/util';\r\nimport luckysheetFreezen from './freezen';\r\nimport menuButton from './menuButton';\r\nimport {checkProtectionAuthorityNormal} from './protection';\r\nimport server from './server';\r\nimport Store from '../store';\r\nimport method from '../global/method';\r\n\r\n//批注\r\nconst luckysheetPostil = {\r\n defaultWidth: 144,\r\n defaultHeight: 84,\r\n currentObj: null,\r\n currentWinW: null,\r\n currentWinH: null,\r\n resize: null,\r\n resizeXY: null,\r\n move: false,\r\n moveXY: null,\r\n init: function(){\r\n let _this = this;\r\n\r\n //点击批注框 聚焦\r\n $(\"#luckysheet-postil-showBoxs\").off(\"mousedown.showPs\").on(\"mousedown.showPs\", \".luckysheet-postil-show\", function(event){\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\",false)){\r\n return;\r\n }\r\n \r\n _this.currentObj = $(this).find(\".luckysheet-postil-show-main\");\r\n\r\n if($(this).hasClass(\"luckysheet-postil-show-active\")){\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n _this.removeActivePs();\r\n\r\n $(this).addClass(\"luckysheet-postil-show-active\");\r\n $(this).find(\".luckysheet-postil-dialog-resize\").show();\r\n $(this).find(\".arrowCanvas\").css(\"z-index\", 200);\r\n $(this).find(\".luckysheet-postil-show-main\").css(\"z-index\", 200);\r\n\r\n event.stopPropagation();\r\n });\r\n $(\"#luckysheet-postil-showBoxs\").off(\"mouseup.showPs\").on(\"mouseup.showPs\", \".luckysheet-postil-show\", function(event){\r\n if(event.which == \"3\"){\r\n event.stopPropagation();\r\n }\r\n });\r\n\r\n //批注框 改变大小\r\n $(\"#luckysheet-postil-showBoxs\").off(\"mousedown.resize\").on(\"mousedown.resize\", \".luckysheet-postil-show .luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item\", function(event){\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\",false)){\r\n return;\r\n }\r\n \r\n _this.currentObj = $(this).closest(\".luckysheet-postil-show-main\");\r\n _this.currentWinW = $(\"#luckysheet-cell-main\")[0].scrollWidth;\r\n _this.currentWinH = $(\"#luckysheet-cell-main\")[0].scrollHeight;\r\n\r\n _this.resize = $(this).data(\"type\");\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop(), \r\n scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let x = mouse[0] + scrollLeft;\r\n let y = mouse[1] + scrollTop;\r\n\r\n let position = _this.currentObj.position();\r\n let width = _this.currentObj.width();\r\n let height = _this.currentObj.height();\r\n\r\n _this.resizeXY = [\r\n x, \r\n y, \r\n width, \r\n height, \r\n position.left + scrollLeft, \r\n position.top + scrollTop, \r\n scrollLeft, \r\n scrollTop\r\n ];\r\n\r\n setluckysheet_scroll_status(true);\r\n\r\n if($(this).closest(\".luckysheet-postil-show\").hasClass(\"luckysheet-postil-show-active\")){\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n _this.removeActivePs();\r\n\r\n $(this).closest(\".luckysheet-postil-show\").addClass(\"luckysheet-postil-show-active\");\r\n $(this).closest(\".luckysheet-postil-show\").find(\".luckysheet-postil-dialog-resize\").show();\r\n $(this).closest(\".luckysheet-postil-show\").find(\".arrowCanvas\").css(\"z-index\", 200);\r\n $(this).closest(\".luckysheet-postil-show\").find(\".luckysheet-postil-show-main\").css(\"z-index\", 200);\r\n\r\n event.stopPropagation();\r\n });\r\n\r\n //批注框 移动\r\n $(\"#luckysheet-postil-showBoxs\").off(\"mousedown.move\").on(\"mousedown.move\", \".luckysheet-postil-show .luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item\", function(event){\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\",false)){\r\n return;\r\n }\r\n \r\n _this.currentObj = $(this).closest(\".luckysheet-postil-show-main\");\r\n _this.currentWinW = $(\"#luckysheet-cell-main\")[0].scrollWidth;\r\n _this.currentWinH = $(\"#luckysheet-cell-main\")[0].scrollHeight;\r\n\r\n _this.move = true;\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop(), \r\n scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n\r\n let offset = _this.currentObj.offset();\r\n let position = _this.currentObj.position();\r\n\r\n _this.moveXY = [\r\n event.pageX - offset.left, \r\n event.pageY - offset.top, \r\n position.left, \r\n position.top, \r\n scrollLeft, \r\n scrollTop\r\n ];\r\n\r\n setluckysheet_scroll_status(true);\r\n\r\n if($(this).closest(\".luckysheet-postil-show\").hasClass(\"luckysheet-postil-show-active\")){\r\n event.stopPropagation();\r\n return;\r\n }\r\n\r\n _this.removeActivePs();\r\n\r\n $(this).closest(\".luckysheet-postil-show\").addClass(\"luckysheet-postil-show-active\");\r\n $(this).closest(\".luckysheet-postil-show\").find(\".luckysheet-postil-dialog-resize\").show();\r\n $(this).closest(\".luckysheet-postil-show\").find(\".arrowCanvas\").css(\"z-index\", 200);\r\n $(this).closest(\".luckysheet-postil-show\").find(\".luckysheet-postil-show-main\").css(\"z-index\", 200);\r\n\r\n event.stopPropagation();\r\n });\r\n },\r\n overshow: function(event){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-postil-overshow\").remove();\r\n\r\n if($(event.target).closest(\"#luckysheet-cell-main\").length == 0){\r\n return;\r\n }\r\n\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let x = mouse[0];\r\n let y = mouse[1];\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n\r\n if(luckysheetFreezen.freezenverticaldata != null && mouse[0] < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){\r\n offsetX = scrollLeft;\r\n } else {\r\n x += scrollLeft;\r\n }\r\n\r\n if(luckysheetFreezen.freezenhorizontaldata != null && mouse[1] < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){\r\n offsetY = scrollTop;\r\n } else {\r\n y += scrollTop;\r\n }\r\n\r\n let row_index = rowLocation(y)[2];\r\n let col_index = colLocation(x)[2];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, row_index, col_index);\r\n if(!!margeset){\r\n row_index = margeset.row[2];\r\n col_index = margeset.column[2];\r\n }\r\n\r\n if(Store.flowdata[row_index] == null || Store.flowdata[row_index][col_index] == null || Store.flowdata[row_index][col_index].ps == null){\r\n return;\r\n }\r\n\r\n let postil = Store.flowdata[row_index][col_index].ps;\r\n\r\n if(postil[\"isshow\"] || $(\"#luckysheet-postil-show_\"+ row_index +\"_\"+ col_index).length > 0){\r\n return;\r\n }\r\n\r\n let value = postil[\"value\"] == null ? \"\" : postil[\"value\"];\r\n\r\n let row = Store.visibledatarow[row_index], \r\n row_pre = row_index - 1 == -1 ? 0 : Store.visibledatarow[row_index - 1];\r\n let col = Store.visibledatacolumn[col_index], \r\n col_pre = col_index - 1 == -1 ? 0 : Store.visibledatacolumn[col_index - 1];\r\n\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let toX = col + offsetX;\r\n let toY = row_pre + offsetY;\r\n\r\n let fromX = toX + 18 * Store.zoomRatio;\r\n let fromY = toY - 18 * Store.zoomRatio;\r\n\r\n if(fromY < 0){\r\n fromY = 2;\r\n }\r\n\r\n let width = _this.defaultWidth * Store.zoomRatio\r\n let height = _this.defaultHeight * Store.zoomRatio\r\n\r\n let size = _this.getArrowCanvasSize(fromX, fromY, toX, toY);\r\n\r\n let html = '
' +\r\n '' +\r\n '
'+ _this.htmlEscape(value) +'
' +\r\n '
';\r\n\r\n $(html).appendTo($(\"#luckysheet-cell-main\"));\r\n\r\n let ctx = $(\"#luckysheet-postil-overshow .arrowCanvas\").get(0).getContext(\"2d\");\r\n\r\n _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);\r\n },\r\n getArrowCanvasSize: function(fromX, fromY, toX, toY){\r\n let left = toX - 5;\r\n \r\n if(fromX < toX){\r\n left = fromX - 5;\r\n }\r\n\r\n let top = toY - 5;\r\n \r\n if(fromY < toY){\r\n top = fromY - 5;\r\n }\r\n\r\n let width = Math.abs(fromX - toX) + 10;\r\n let height = Math.abs(fromY - toY) + 10;\r\n\r\n let x1 = width - 5;\r\n let x2 = 5;\r\n \r\n if(fromX < toX){\r\n x1 = 5;\r\n x2 = width - 5;\r\n }\r\n\r\n let y1 = height - 5;\r\n let y2 = 5;\r\n\r\n if(fromY < toY){\r\n y1 = 5;\r\n y2 = height - 5;\r\n }\r\n\r\n return [left, top, width, height, x1, y1, x2, y2];\r\n },\r\n drawArrow: function(ctx, fromX, fromY, toX, toY, theta, headlen, width, color){\r\n theta = getObjType(theta) == \"undefined\" ? 30 : theta;\r\n headlen = getObjType(headlen) == \"undefined\" ? 6 : headlen;\r\n width = getObjType(width) == \"undefined\" ? 1 : width;\r\n color = getObjType(color) == \"undefined\" ? \"#000\" : color;\r\n\r\n // 计算各角度和对应的P2,P3坐标\r\n let angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI, \r\n angle1 = (angle + theta) * Math.PI / 180, \r\n angle2 = (angle - theta) * Math.PI / 180, \r\n topX = headlen * Math.cos(angle1), \r\n topY = headlen * Math.sin(angle1), \r\n botX = headlen * Math.cos(angle2), \r\n botY = headlen * Math.sin(angle2);\r\n\r\n ctx.save();\r\n ctx.beginPath();\r\n\r\n let arrowX = fromX - topX,\r\n arrowY = fromY - topY;\r\n\r\n ctx.moveTo(arrowX, arrowY); \r\n ctx.moveTo(fromX, fromY); \r\n ctx.lineTo(toX, toY); \r\n \r\n ctx.lineWidth = width;\r\n ctx.strokeStyle = color; \r\n ctx.stroke();\r\n\r\n arrowX = toX + topX; \r\n arrowY = toY + topY; \r\n ctx.moveTo(arrowX, arrowY); \r\n ctx.lineTo(toX, toY); \r\n arrowX = toX + botX; \r\n arrowY = toY + botY; \r\n ctx.lineTo(arrowX, arrowY); \r\n \r\n ctx.fillStyle = color;\r\n ctx.fill(); \r\n ctx.restore();\r\n },\r\n buildAllPs: function(data){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-cell-main #luckysheet-postil-showBoxs\").empty();\r\n\r\n for(let r = 0; r < data.length; r++){\r\n for(let c = 0; c < data[0].length; c++){\r\n if(data[r][c] != null && data[r][c].ps != null){\r\n let postil = data[r][c].ps;\r\n _this.buildPs(r, c, postil);\r\n }\r\n }\r\n }\r\n\r\n _this.init();\r\n },\r\n buildPs: function(r, c, postil){\r\n if($(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).length > 0){\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).remove();\r\n }\r\n\r\n if(postil == null){\r\n return;\r\n }\r\n\r\n let _this = this;\r\n let isshow = postil[\"isshow\"] == null ? false : postil[\"isshow\"];\r\n\r\n if(isshow){\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let toX = col;\r\n let toY = row_pre;\r\n\r\n let left = postil[\"left\"] == null ? toX + 18 * Store.zoomRatio : postil[\"left\"] * Store.zoomRatio;\r\n let top = postil[\"top\"] == null ? toY - 18 * Store.zoomRatio : postil[\"top\"] * Store.zoomRatio;\r\n let width = postil[\"width\"] == null ? _this.defaultWidth * Store.zoomRatio : postil[\"width\"] * Store.zoomRatio;\r\n let height = postil[\"height\"] == null ? _this.defaultHeight * Store.zoomRatio : postil[\"height\"] * Store.zoomRatio;\r\n let value = postil[\"value\"] == null ? \"\" : postil[\"value\"];\r\n\r\n if(top < 0){\r\n top = 2;\r\n }\r\n\r\n let size = _this.getArrowCanvasSize(left, top, toX, toY);\r\n\r\n let html = '
' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' + \r\n '
' +\r\n _this.htmlEscape(value) +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
';\r\n\r\n $(html).appendTo($(\"#luckysheet-cell-main #luckysheet-postil-showBoxs\"));\r\n\r\n let ctx = $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c +\" .arrowCanvas\").get(0).getContext(\"2d\");\r\n\r\n _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);\r\n }\r\n },\r\n newPs: function(r, c){\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\")){\r\n return;\r\n }\r\n\r\n // Hook function\r\n if(!method.createHookFunction('commentInsertBefore',r,c, )){\r\n return;\r\n }\r\n\r\n let _this = this;\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let toX = col;\r\n let toY = row_pre;\r\n\r\n let fromX = toX + 18 * Store.zoomRatio;\r\n let fromY = toY - 18 * Store.zoomRatio;\r\n\r\n if(fromY < 0){\r\n fromY = 2;\r\n }\r\n\r\n let width = _this.defaultWidth * Store.zoomRatio;\r\n let height = _this.defaultHeight * Store.zoomRatio;\r\n\r\n let size = _this.getArrowCanvasSize(fromX, fromY, toX, toY);\r\n\r\n let html = '
' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' + \r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
';\r\n\r\n $(html).appendTo($(\"#luckysheet-cell-main #luckysheet-postil-showBoxs\"));\r\n\r\n let ctx = $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c +\" .arrowCanvas\").get(0).getContext(\"2d\");\r\n\r\n _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);\r\n\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c +\" .formulaInputFocus\").focus();\r\n\r\n _this.init();\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let rc = [];\r\n\r\n if(d[r][c] == null){\r\n d[r][c] = {};\r\n }\r\n\r\n d[r][c].ps = { \"left\": null, \"top\": null, \"width\": null, \"height\": null, \"value\": \"\", \"isshow\": false };\r\n rc.push(r + \"_\" + c);\r\n\r\n _this.ref(d, rc);\r\n\r\n // Hook function\r\n setTimeout(() => {\r\n method.createHookFunction('commentInsertAfter',r,c, d[r][c])\r\n }, 0);\r\n },\r\n editPs: function(r, c){\r\n let _this = this;\r\n\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\")){\r\n return;\r\n }\r\n\r\n if($(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).length > 0){\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).show();\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).addClass(\"luckysheet-postil-show-active\");\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).find(\".luckysheet-postil-dialog-resize\").show();\r\n }\r\n else{\r\n let postil = Store.flowdata[r][c].ps;\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let toX = col;\r\n let toY = row_pre;\r\n\r\n let left = postil[\"left\"] == null ? toX + 18 * Store.zoomRatio : postil[\"left\"] * Store.zoomRatio;\r\n let top = postil[\"top\"] == null ? toY - 18 * Store.zoomRatio : postil[\"top\"] * Store.zoomRatio;\r\n let width = postil[\"width\"] == null ? _this.defaultWidth * Store.zoomRatio : postil[\"width\"] * Store.zoomRatio;\r\n let height = postil[\"height\"] == null ? _this.defaultHeight * Store.zoomRatio : postil[\"height\"] * Store.zoomRatio;\r\n let value = postil[\"value\"] == null ? \"\" : postil[\"value\"];\r\n\r\n if(top < 0){\r\n top = 2;\r\n }\r\n\r\n let size = _this.getArrowCanvasSize(left, top, toX, toY);\r\n\r\n let html = '
' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' + \r\n '
' +\r\n _this.htmlEscape(value) +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
';\r\n\r\n $(html).appendTo($(\"#luckysheet-cell-main #luckysheet-postil-showBoxs\"));\r\n\r\n let ctx = $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c +\" .arrowCanvas\").get(0).getContext(\"2d\");\r\n\r\n _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);\r\n }\r\n\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c +\" .formulaInputFocus\").focus();\r\n luckysheetRangeLast($(\"#luckysheet-postil-show_\"+ r +\"_\"+ c +\" .formulaInputFocus\").get(0));\r\n\r\n _this.init();\r\n },\r\n delPs: function(r, c){\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"editObjects\")){\r\n return;\r\n }\r\n\r\n // Hook function\r\n if(!method.createHookFunction('commentDeleteBefore',r,c,Store.flowdata[r][c])){\r\n return;\r\n }\r\n\r\n if($(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).length > 0){\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).remove();\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let rc = [];\r\n\r\n delete d[r][c].ps;\r\n rc.push(r + \"_\" + c);\r\n\r\n this.ref(d, rc);\r\n\r\n // Hook function\r\n setTimeout(() => {\r\n method.createHookFunction('commentDeleteAfter',r,c, Store.flowdata[r][c])\r\n }, 0);\r\n },\r\n showHidePs: function(r, c){\r\n let _this = this;\r\n\r\n let postil = Store.flowdata[r][c].ps;\r\n let isshow = postil[\"isshow\"];\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let rc = [];\r\n\r\n if(isshow){\r\n d[r][c].ps.isshow = false;\r\n\r\n $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c).remove();\r\n }\r\n else{\r\n d[r][c].ps.isshow = true;\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n let toX = col;\r\n let toY = row_pre;\r\n\r\n if(luckysheetFreezen.freezenverticaldata != null && toX < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){\r\n toX += scrollLeft;\r\n }\r\n if(luckysheetFreezen.freezenhorizontaldata != null && toY < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){\r\n toY += scrollTop;\r\n }\r\n\r\n let left = postil[\"left\"] == null ? toX + 18 * Store.zoomRatio : postil[\"left\"] * Store.zoomRatio;\r\n let top = postil[\"top\"] == null ? toY - 18 * Store.zoomRatio : postil[\"top\"] * Store.zoomRatio;\r\n let width = postil[\"width\"] == null ? _this.defaultWidth * Store.zoomRatio : postil[\"width\"] * Store.zoomRatio;\r\n let height = postil[\"height\"] == null ? _this.defaultHeight * Store.zoomRatio : postil[\"height\"] * Store.zoomRatio;\r\n let value = postil[\"value\"] == null ? \"\" : postil[\"value\"];\r\n\r\n if(top < 0){\r\n top = 2;\r\n }\r\n\r\n let size = _this.getArrowCanvasSize(left, top, toX, toY);\r\n\r\n let html = '
' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' + \r\n '
' +\r\n _this.htmlEscape(value) +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
';\r\n\r\n $(html).appendTo($(\"#luckysheet-cell-main #luckysheet-postil-showBoxs\"));\r\n\r\n let ctx = $(\"#luckysheet-postil-show_\"+ r +\"_\"+ c +\" .arrowCanvas\").get(0).getContext(\"2d\");\r\n\r\n _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);\r\n\r\n _this.init();\r\n }\r\n\r\n rc.push(r + \"_\" + c);\r\n\r\n _this.ref(d, rc);\r\n },\r\n showHideAllPs: function(){\r\n let _this = this;\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let isAllShow = true;\r\n let allPs = [];\r\n\r\n for(let r = 0; r < d.length; r++){\r\n for(let c = 0; c < d[0].length; c++){\r\n if(d[r] != null && d[r][c] != null && d[r][c].ps != null){\r\n allPs.push(r + \"_\" + c);\r\n\r\n if(!d[r][c].ps.isshow){\r\n isAllShow = false;\r\n }\r\n }\r\n }\r\n }\r\n\r\n let rc = [];\r\n if(allPs.length > 0){\r\n if(isAllShow){ //全部显示,操作为隐藏所有批注\r\n $(\"#luckysheet-cell-main #luckysheet-postil-showBoxs\").empty();\r\n\r\n for(let i = 0; i < allPs.length; i++){\r\n let rowIndex = allPs[i].split(\"_\")[0];\r\n let colIndex = allPs[i].split(\"_\")[1];\r\n\r\n let postil = d[rowIndex][colIndex].ps;\r\n\r\n if(postil[\"isshow\"]){\r\n d[rowIndex][colIndex].ps.isshow = false;\r\n rc.push(allPs[i]);\r\n }\r\n }\r\n }\r\n else{ //部分显示或全部隐藏,操作位显示所有批注\r\n for(let i = 0; i < allPs.length; i++){\r\n let rowIndex = allPs[i].split(\"_\")[0];\r\n let colIndex = allPs[i].split(\"_\")[1];\r\n\r\n let postil = d[rowIndex][colIndex].ps;\r\n\r\n if(!postil[\"isshow\"]){\r\n let row = Store.visibledatarow[rowIndex], \r\n row_pre = rowIndex - 1 == -1 ? 0 : Store.visibledatarow[rowIndex - 1];\r\n let col = Store.visibledatacolumn[colIndex], \r\n col_pre = colIndex - 1 == -1 ? 0 : Store.visibledatacolumn[colIndex - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, rowIndex, colIndex);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n \r\n let toX = col;\r\n let toY = row_pre;\r\n \r\n if(luckysheetFreezen.freezenverticaldata != null && toX < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){\r\n toX += scrollLeft;\r\n }\r\n if(luckysheetFreezen.freezenhorizontaldata != null && toY < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){\r\n toY += scrollTop;\r\n }\r\n\r\n let left = postil[\"left\"] == null ? toX + 18 * Store.zoomRatio : postil[\"left\"] * Store.zoomRatio;\r\n let top = postil[\"top\"] == null ? toY - 18 * Store.zoomRatio : postil[\"top\"] * Store.zoomRatio;\r\n let width = postil[\"width\"] == null ? _this.defaultWidth * Store.zoomRatio : postil[\"width\"] * Store.zoomRatio;\r\n let height = postil[\"height\"] == null ? _this.defaultHeight * Store.zoomRatio : postil[\"height\"] * Store.zoomRatio;\r\n let value = postil[\"value\"] == null ? \"\" : postil[\"value\"];\r\n\r\n if(top < 0){\r\n top = 2;\r\n }\r\n\r\n let size = _this.getArrowCanvasSize(left, top, toX, toY);\r\n\r\n let html = '
' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' + \r\n '
' +\r\n _this.htmlEscape(value) +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
';\r\n\r\n $(html).appendTo($(\"#luckysheet-cell-main #luckysheet-postil-showBoxs\"));\r\n\r\n let ctx = $(\"#luckysheet-postil-show_\"+ rowIndex +\"_\"+ colIndex +\" .arrowCanvas\").get(0).getContext(\"2d\");\r\n\r\n _this.drawArrow(ctx, size[4], size[5], size[6], size[7]);\r\n\r\n d[rowIndex][colIndex].ps.isshow = true;\r\n rc.push(allPs[i]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n _this.ref(d, rc);\r\n _this.init();\r\n },\r\n removeActivePs: function(){\r\n if($(\"#luckysheet-postil-showBoxs .luckysheet-postil-show-active\").length > 0){\r\n \r\n\r\n let id = $(\"#luckysheet-postil-showBoxs .luckysheet-postil-show-active\").attr(\"id\");\r\n let r = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[0];\r\n let c = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[1];\r\n\r\n let value = $(\"#\" + id).find(\".formulaInputFocus\").text();\r\n\r\n // Hook function\r\n if(!method.createHookFunction('commentUpdateBefore',r,c,value)){\r\n return;\r\n }\r\n\r\n const previousCell = $.extend(true,{},Store.flowdata[r][c]);\r\n\r\n $(\"#\" + id).removeClass(\"luckysheet-postil-show-active\");\r\n $(\"#\" + id).find(\".luckysheet-postil-dialog-resize\").hide();\r\n $(\"#\" + id).find(\".arrowCanvas\").css(\"z-index\", 100);\r\n $(\"#\" + id).find(\".luckysheet-postil-show-main\").css(\"z-index\", 100);\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let rc = [];\r\n\r\n d[r][c].ps.value = value;\r\n rc.push(r + \"_\" + c);\r\n\r\n this.ref(d, rc);\r\n\r\n if(!d[r][c].ps.isshow){\r\n $(\"#\" + id).remove();\r\n }\r\n // Hook function\r\n setTimeout(() => {\r\n method.createHookFunction('commentUpdateAfter',r,c, previousCell, d[r][c])\r\n }, 0);\r\n }\r\n },\r\n ref: function(data, rc){\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n \r\n Store.jfredo.push({ \r\n \"type\": \"postil\", \r\n \"data\": Store.flowdata, \r\n \"curdata\": data, \r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"rc\": rc \r\n });\r\n }\r\n\r\n //flowdata\r\n Store.flowdata = data;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = Store.flowdata;\r\n // formula.execFunctionGroupData = Store.flowdata;\r\n\r\n //共享编辑模式\r\n if(server.allowUpdate){\r\n for(let i = 0; i < rc.length; i++){\r\n let r = rc[i].split(\"_\")[0];\r\n let c = rc[i].split(\"_\")[1];\r\n\r\n server.saveParam(\"v\", Store.currentSheetIndex, Store.flowdata[r][c], { \"r\": r, \"c\": c });\r\n }\r\n }\r\n \r\n //刷新表格\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n },\r\n positionSync: function(){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-postil-showBoxs .luckysheet-postil-show\").each(function(i, e){\r\n let id = $(e).attr(\"id\");\r\n\r\n let r = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[0];\r\n let c = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[1];\r\n\r\n let cell = Store.flowdata[r][c];\r\n \r\n if(cell != null && cell.ps != null){\r\n _this.buildPs(r, c, cell.ps);\r\n }\r\n else{\r\n $(\"#\" + id).hide();\r\n }\r\n });\r\n },\r\n htmlEscape: function(text){\r\n return text.replace(/[<>\"&]/g, function(match, pos, originalText){\r\n console.log(match, pos, originalText)\r\n switch(match){\r\n case '<': {\r\n return '<';\r\n }\r\n case '>': {\r\n return '>';\r\n }\r\n case '&': {\r\n return '&';\r\n }\r\n case '\\\"': {\r\n return '"';\r\n }\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default luckysheetPostil;","import { getSheetIndex } from '../methods/get';\r\nimport { getObjType } from '../utils/util';\r\nimport Store from '../store';\r\n\r\n//获取表格边框数据计算值\r\nfunction getBorderInfoComputeRange(dataset_row_st,dataset_row_ed,dataset_col_st,dataset_col_ed,sheetIndex) {\r\n let borderInfoCompute = {};\r\n\r\n let cfg, data; \r\n if(sheetIndex == null){\r\n cfg = Store.config;\r\n data = Store.flowdata;\r\n }\r\n else{\r\n cfg = Store.luckysheetfile[getSheetIndex(sheetIndex)].config;\r\n data = Store.luckysheetfile[getSheetIndex(sheetIndex)].data;\r\n }\r\n\r\n let borderInfo = cfg[\"borderInfo\"];\r\n\r\n if(borderInfo != null && borderInfo.length > 0){\r\n for(let i = 0; i < borderInfo.length; i++){\r\n let rangeType = borderInfo[i].rangeType;\r\n\r\n if(rangeType == \"range\"){\r\n let borderType = borderInfo[i].borderType;\r\n let borderColor = borderInfo[i].color;\r\n let borderStyle = borderInfo[i].style;\r\n\r\n let borderRange = borderInfo[i].range;\r\n\r\n for(let j = 0; j < borderRange.length; j++){\r\n let bd_r1 = borderRange[j].row[0], bd_r2 = borderRange[j].row[1];\r\n let bd_c1 = borderRange[j].column[0], bd_c2 = borderRange[j].column[1];\r\n\r\n if(bd_r1dataset_row_ed){\r\n bd_r2 = dataset_row_ed;\r\n }\r\n\r\n if(bd_c1dataset_col_ed){\r\n bd_c2 = dataset_col_ed;\r\n }\r\n\r\n if(borderType == \"border-left\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n \r\n if(borderInfoCompute[bd_r + \"_\" + bd_c1] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c1] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c1].l = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_c_left = bd_c1 - 1;\r\n\r\n if(bd_c_left >= 0 && borderInfoCompute[bd_r + \"_\" + bd_c_left]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == \"object\" && data[bd_r][bd_c_left].mc != null){\r\n let cell_left = data[bd_r][bd_c_left];\r\n\r\n let mc = cfg[\"merge\"][cell_left.mc.r + \"_\" + cell_left.mc.c];\r\n\r\n if(mc.c + mc.cs - 1 == bd_c_left){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-right\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n \r\n if(borderInfoCompute[bd_r + \"_\" + bd_c2] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c2] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c2].r = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_c_right = bd_c2 + 1;\r\n\r\n if(bd_c_right < data[0].length && borderInfoCompute[bd_r + \"_\" + bd_c_right]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == \"object\" && data[bd_r][bd_c_right].mc != null){\r\n let cell_right = data[bd_r][bd_c_right];\r\n\r\n let mc = cfg[\"merge\"][cell_right.mc.r + \"_\" + cell_right.mc.c];\r\n\r\n if(mc.c == bd_c_right){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-top\"){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r1] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(borderInfoCompute[bd_r1 + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r1 + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r1 + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_r_top = bd_r1 - 1;\r\n\r\n if(bd_r_top >= 0 && borderInfoCompute[bd_r_top + \"_\" + bd_c]){\r\n if(data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == \"object\" && data[bd_r_top][bd_c].mc != null){\r\n let cell_top = data[bd_r_top][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell_top.mc.r + \"_\" + cell_top.mc.c];\r\n\r\n if(mc.r + mc.rs - 1 == bd_r_top){\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-bottom\"){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r2] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(borderInfoCompute[bd_r2 + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r2 + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r2 + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_r_bottom = bd_r2 + 1;\r\n\r\n if(bd_r_bottom < data.length && borderInfoCompute[bd_r_bottom + \"_\" + bd_c]){\r\n if(data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == \"object\" && data[bd_r_bottom][bd_c].mc != null){\r\n let cell_bottom = data[bd_r_bottom][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell_bottom.mc.r + \"_\" + cell_bottom.mc.c];\r\n\r\n if(mc.r == bd_r_bottom){\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-all\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c];\r\n\r\n if(mc.r == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n \r\n if(mc.r + mc.rs - 1 == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n\r\n if(mc.c == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n \r\n if(mc.c + mc.cs - 1 == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n\r\n if(bd_r == bd_r1){\r\n let bd_r_top = bd_r1 - 1;\r\n\r\n if(bd_r_top >= 0 && borderInfoCompute[bd_r_top + \"_\" + bd_c]){\r\n if(data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == \"object\" && data[bd_r_top][bd_c].mc != null){\r\n let cell_top = data[bd_r_top][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell_top.mc.r + \"_\" + cell_top.mc.c];\r\n\r\n if(mc.r + mc.rs - 1 == bd_r_top){\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n }\r\n \r\n if(bd_r == bd_r2){\r\n let bd_r_bottom = bd_r2 + 1;\r\n\r\n if(bd_r_bottom < data.length && borderInfoCompute[bd_r_bottom + \"_\" + bd_c]){\r\n if(data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == \"object\" && data[bd_r_bottom][bd_c].mc != null){\r\n let cell_bottom = data[bd_r_bottom][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell_bottom.mc.r + \"_\" + cell_bottom.mc.c];\r\n\r\n if(mc.r == bd_r_bottom){\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n \r\n if(bd_c == bd_c1){\r\n let bd_c_left = bd_c1 - 1;\r\n\r\n if(bd_c_left >= 0 && borderInfoCompute[bd_r + \"_\" + bd_c_left]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == \"object\" && data[bd_r][bd_c_left].mc != null){\r\n let cell_left = data[bd_r][bd_c_left];\r\n\r\n let mc = cfg[\"merge\"][cell_left.mc.r + \"_\" + cell_left.mc.c];\r\n\r\n if(mc.c + mc.cs - 1 == bd_c_left){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n \r\n if(bd_c == bd_c2){\r\n let bd_c_right = bd_c2 + 1;\r\n\r\n if(bd_c_right < data[0].length && borderInfoCompute[bd_r + \"_\" + bd_c_right]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == \"object\" && data[bd_r][bd_c_right].mc != null){\r\n let cell_right = data[bd_r][bd_c_right];\r\n\r\n let mc = cfg[\"merge\"][cell_right.mc.r + \"_\" + cell_right.mc.c];\r\n\r\n if(mc.c == bd_c_right){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-outside\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(!(bd_r == bd_r1 || bd_r == bd_r2 || bd_c == bd_c1 || bd_c == bd_c2)){\r\n continue;\r\n }\r\n\r\n if(bd_r == bd_r1){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_r_top = bd_r1 - 1;\r\n\r\n if(bd_r_top >= 0 && borderInfoCompute[bd_r_top + \"_\" + bd_c]){\r\n if(data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == \"object\" && data[bd_r_top][bd_c].mc != null){\r\n let cell_top = data[bd_r_top][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell_top.mc.r + \"_\" + cell_top.mc.c];\r\n\r\n if(mc.r + mc.rs - 1 == bd_r_top){\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n }\r\n\r\n if(bd_r == bd_r2){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_r_bottom = bd_r2 + 1;\r\n\r\n if(bd_r_bottom < data.length && borderInfoCompute[bd_r_bottom + \"_\" + bd_c]){\r\n if(data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == \"object\" && data[bd_r_bottom][bd_c].mc != null){\r\n let cell_bottom = data[bd_r_bottom][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell_bottom.mc.r + \"_\" + cell_bottom.mc.c];\r\n\r\n if(mc.r == bd_r_bottom){\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n\r\n if(bd_c == bd_c1){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_c_left = bd_c1 - 1;\r\n\r\n if(bd_c_left >= 0 && borderInfoCompute[bd_r + \"_\" + bd_c_left]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == \"object\" && data[bd_r][bd_c_left].mc != null){\r\n let cell_left = data[bd_r][bd_c_left];\r\n\r\n let mc = cfg[\"merge\"][cell_left.mc.r + \"_\" + cell_left.mc.c];\r\n\r\n if(mc.c + mc.cs - 1 == bd_c_left){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n\r\n if(bd_c == bd_c2){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n\r\n let bd_c_right = bd_c2 + 1;\r\n\r\n if(bd_c_right < data[0].length && borderInfoCompute[bd_r + \"_\" + bd_c_right]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == \"object\" && data[bd_r][bd_c_right].mc != null){\r\n let cell_right = data[bd_r][bd_c_right];\r\n\r\n let mc = cfg[\"merge\"][cell_right.mc.r + \"_\" + cell_right.mc.c];\r\n\r\n if(mc.c == bd_c_right){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": borderColor, \"style\": borderStyle }; \r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-inside\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(bd_r == bd_r1 && bd_c == bd_c1){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_r == bd_r2 && bd_c == bd_c1){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_r == bd_r1 && bd_c == bd_c2){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_r == bd_r2 && bd_c == bd_c2){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_r == bd_r1){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c];\r\n\r\n if(mc.c == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.c + mc.cs - 1 == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_r == bd_r2){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c];\r\n\r\n if(mc.c == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.c + mc.cs - 1 == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_c == bd_c1){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c];\r\n\r\n if(mc.r == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.r + mc.rs - 1 == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_c == bd_c2){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c];\r\n\r\n if(mc.r == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.r + mc.rs - 1 == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c];\r\n\r\n if(mc.r == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.r + mc.rs - 1 == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n\r\n if(mc.c == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.c + mc.cs - 1 == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n } \r\n }\r\n }\r\n }\r\n else if(borderType == \"border-horizontal\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(bd_r == bd_r1){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_r == bd_r2){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c];\r\n\r\n if(mc.r == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.r + mc.rs - 1 == bd_r){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-vertical\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(bd_c == bd_c1){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else if(bd_c == bd_c2){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c] || {};\r\n\r\n if(mc.c == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n else if(mc.c + mc.cs - 1 == bd_c){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n else{\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": borderColor, \"style\": borderStyle };\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": borderColor, \"style\": borderStyle };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(borderType == \"border-none\"){\r\n for(let bd_r = bd_r1; bd_r <= bd_r2; bd_r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n\r\n for(let bd_c = bd_c1; bd_c <= bd_c2; bd_c++){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] != null){\r\n delete borderInfoCompute[bd_r + \"_\" + bd_c];\r\n }\r\n\r\n if(bd_r == bd_r1){\r\n let bd_r_top = bd_r1 - 1;\r\n\r\n if(bd_r_top >= 0 && borderInfoCompute[bd_r_top + \"_\" + bd_c]){\r\n delete borderInfoCompute[bd_r_top + \"_\" + bd_c].b;\r\n }\r\n }\r\n \r\n if(bd_r == bd_r2){\r\n let bd_r_bottom = bd_r2 + 1;\r\n\r\n if(bd_r_bottom < data.length && borderInfoCompute[bd_r_bottom + \"_\" + bd_c]){\r\n delete borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t;\r\n }\r\n }\r\n \r\n if(bd_c == bd_c1){\r\n let bd_c_left = bd_c1 - 1;\r\n\r\n if(bd_c_left >= 0 && borderInfoCompute[bd_r + \"_\" + bd_c_left]){\r\n delete borderInfoCompute[bd_r + \"_\" + bd_c_left].r;\r\n }\r\n }\r\n \r\n if(bd_c == bd_c2){\r\n let bd_c_right = bd_c2 + 1;\r\n\r\n if(bd_c_right < data[0].length && borderInfoCompute[bd_r + \"_\" + bd_c_right]){\r\n delete borderInfoCompute[bd_r + \"_\" + bd_c_right].l;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(rangeType == \"cell\"){\r\n let value = borderInfo[i].value;\r\n\r\n let bd_r = value.row_index, bd_c = value.col_index;\r\n\r\n if(bd_r < dataset_row_st || bd_r > dataset_row_ed || bd_c < dataset_col_st || bd_c > dataset_col_ed){\r\n continue;\r\n }\r\n\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][bd_r] != null) {\r\n continue;\r\n }\r\n\r\n if(value.l != null || value.r != null || value.t != null || value.b != null){\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c] == null){\r\n borderInfoCompute[bd_r + \"_\" + bd_c] = {};\r\n }\r\n\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c]) == \"object\" && data[bd_r][bd_c].mc != null){\r\n let cell = data[bd_r][bd_c];\r\n let mc = cfg[\"merge\"][cell.mc.r + \"_\" + cell.mc.c] || {};\r\n\r\n if(value.l != null && bd_c == mc.c){ //左边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": value.l.color, \"style\": value.l.style };\r\n\r\n let bd_c_left = bd_c - 1;\r\n\r\n if(bd_c_left >= 0 && borderInfoCompute[bd_r + \"_\" + bd_c_left]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == \"object\" && data[bd_r][bd_c_left].mc != null){\r\n let cell_left = data[bd_r][bd_c_left];\r\n\r\n let mc_l = cfg[\"merge\"][cell_left.mc.r + \"_\" + cell_left.mc.c];\r\n\r\n if(mc_l.c + mc_l.cs - 1 == bd_c_left){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": value.l.color, \"style\": value.l.style }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": value.l.color, \"style\": value.l.style }; \r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = null;\r\n }\r\n\r\n if(value.r != null && bd_c == mc.c + mc.cs - 1){ //右边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": value.r.color, \"style\": value.r.style };\r\n\r\n let bd_c_right = bd_c + 1;\r\n\r\n if(bd_c_right < data[0].length && borderInfoCompute[bd_r + \"_\" + bd_c_right]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == \"object\" && data[bd_r][bd_c_right].mc != null){\r\n let cell_right = data[bd_r][bd_c_right];\r\n\r\n let mc_r = cfg[\"merge\"][cell_right.mc.r + \"_\" + cell_right.mc.c];\r\n\r\n if(mc_r.c == bd_c_right){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": value.r.color, \"style\": value.r.style }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": value.r.color, \"style\": value.r.style }; \r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = null;\r\n }\r\n\r\n if(value.t != null && bd_r == mc.r){ //上边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": value.t.color, \"style\": value.t.style };\r\n\r\n let bd_r_top = bd_r - 1;\r\n\r\n if(bd_r_top >= 0 && borderInfoCompute[bd_r_top + \"_\" + bd_c]){\r\n if(data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == \"object\" && data[bd_r_top][bd_c].mc != null){\r\n let cell_top = data[bd_r_top][bd_c];\r\n\r\n let mc_t = cfg[\"merge\"][cell_top.mc.r + \"_\" + cell_top.mc.c];\r\n\r\n if(mc_t.r + mc_t.rs - 1 == bd_r_top){\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": value.t.color, \"style\": value.t.style };\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": value.t.color, \"style\": value.t.style };\r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = null;\r\n }\r\n\r\n if(value.b != null && bd_r == mc.r + mc.rs - 1){ //下边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": value.b.color, \"style\": value.b.style };\r\n\r\n let bd_r_bottom = bd_r + 1;\r\n\r\n if(bd_r_bottom < data.length && borderInfoCompute[bd_r_bottom + \"_\" + bd_c]){\r\n if(data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == \"object\" && data[bd_r_bottom][bd_c].mc != null){\r\n let cell_bottom = data[bd_r_bottom][bd_c];\r\n \r\n let mc_b = cfg[\"merge\"][cell_bottom.mc.r + \"_\" + cell_bottom.mc.c];\r\n\r\n if(mc_b.r == bd_r_bottom){\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": value.b.color, \"style\": value.b.style }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": value.b.color, \"style\": value.b.style }; \r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = null;\r\n }\r\n }\r\n else{\r\n if(value.l != null){ //左边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = { \"color\": value.l.color, \"style\": value.l.style };\r\n\r\n let bd_c_left = bd_c - 1;\r\n\r\n if(bd_c_left >= 0 && borderInfoCompute[bd_r + \"_\" + bd_c_left]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_left]) == \"object\" && data[bd_r][bd_c_left].mc != null){\r\n let cell_left = data[bd_r][bd_c_left];\r\n\r\n let mc_l = cfg[\"merge\"][cell_left.mc.r + \"_\" + cell_left.mc.c];\r\n\r\n if(mc_l.c + mc_l.cs - 1 == bd_c_left){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": value.l.color, \"style\": value.l.style }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_left].r = { \"color\": value.l.color, \"style\": value.l.style }; \r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].l = null;\r\n }\r\n\r\n if(value.r != null){ //右边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = { \"color\": value.r.color, \"style\": value.r.style };\r\n\r\n let bd_c_right = bd_c + 1;\r\n\r\n if(bd_c_right < data[0].length && borderInfoCompute[bd_r + \"_\" + bd_c_right]){\r\n if(data[bd_r] != null && getObjType(data[bd_r][bd_c_right]) == \"object\" && data[bd_r][bd_c_right].mc != null){\r\n let cell_right = data[bd_r][bd_c_right];\r\n\r\n let mc_r = cfg[\"merge\"][cell_right.mc.r + \"_\" + cell_right.mc.c];\r\n\r\n if(mc_r.c == bd_c_right){\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": value.r.color, \"style\": value.r.style }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c_right].l = { \"color\": value.r.color, \"style\": value.r.style }; \r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].r = null;\r\n }\r\n\r\n if(value.t != null){ //上边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = { \"color\": value.t.color, \"style\": value.t.style };\r\n\r\n let bd_r_top = bd_r - 1;\r\n\r\n if(bd_r_top >= 0 && borderInfoCompute[bd_r_top + \"_\" + bd_c]){\r\n if(data[bd_r_top] != null && getObjType(data[bd_r_top][bd_c]) == \"object\" && data[bd_r_top][bd_c].mc != null){\r\n let cell_top = data[bd_r_top][bd_c];\r\n\r\n let mc_t = cfg[\"merge\"][cell_top.mc.r + \"_\" + cell_top.mc.c];\r\n\r\n if(mc_t.r + mc_t.rs - 1 == bd_r_top){\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": value.t.color, \"style\": value.t.style };\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_top + \"_\" + bd_c].b = { \"color\": value.t.color, \"style\": value.t.style };\r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].t = null;\r\n }\r\n\r\n if(value.b != null){ //下边框\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = { \"color\": value.b.color, \"style\": value.b.style };\r\n\r\n let bd_r_bottom = bd_r + 1;\r\n\r\n if(bd_r_bottom < data.length && borderInfoCompute[bd_r_bottom + \"_\" + bd_c]){\r\n if(data[bd_r_bottom] != null && getObjType(data[bd_r_bottom][bd_c]) == \"object\" && data[bd_r_bottom][bd_c].mc != null){\r\n let cell_bottom = data[bd_r_bottom][bd_c];\r\n \r\n let mc_b = cfg[\"merge\"][cell_bottom.mc.r + \"_\" + cell_bottom.mc.c];\r\n\r\n if(mc_b.r == bd_r_bottom){\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": value.b.color, \"style\": value.b.style }; \r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r_bottom + \"_\" + bd_c].t = { \"color\": value.b.color, \"style\": value.b.style }; \r\n }\r\n }\r\n }\r\n else{\r\n borderInfoCompute[bd_r + \"_\" + bd_c].b = null;\r\n }\r\n }\r\n }\r\n else{\r\n delete borderInfoCompute[bd_r + \"_\" + bd_c];\r\n }\r\n }\r\n }\r\n }\r\n\r\n return borderInfoCompute;\r\n}\r\n\r\nfunction getBorderInfoCompute(sheetIndex) {\r\n let borderInfoCompute = {};\r\n\r\n let cfg, data; \r\n if(sheetIndex == null){\r\n cfg = Store.config;\r\n data = Store.flowdata;\r\n }\r\n else{\r\n cfg = Store.luckysheetfile[getSheetIndex(sheetIndex)].config;\r\n data = Store.luckysheetfile[getSheetIndex(sheetIndex)].data;\r\n }\r\n\r\n borderInfoCompute = getBorderInfoComputeRange(0, data.length,0, data[0].length, sheetIndex);\r\n\r\n return borderInfoCompute;\r\n}\r\n\r\nexport {\r\n getBorderInfoCompute,\r\n getBorderInfoComputeRange\r\n}","import { rowLocationByIndex, colLocationByIndex } from '../global/location';\r\nimport { countfunc } from '../global/count';\r\nimport { getBorderInfoCompute } from '../global/border';\r\nimport { isRealNum } from '../global/validate';\r\nimport { genarate, update } from '../global/format';\r\nimport { jfrefreshgrid } from '../global/refresh';\r\nimport editor from '../global/editor';\r\nimport formula from '../global/formula';\r\nimport conditionformat from './conditionformat';\r\nimport {checkProtectionLockedRangeList} from './protection';\r\nimport { selectHightlightShow } from './select';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { getObjType, replaceHtml } from '../utils/util';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport dayjs from 'dayjs'\r\n\r\n//选区下拉\r\nconst luckysheetDropCell = {\r\n iconHtml: '
'+\r\n '
'+\r\n '
',\r\n typeListHtml: '
'+\r\n '
'+\r\n '
'+\r\n '${copyCell}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${sequence}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${onlyFormat}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${noFormat}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${day}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${workDay}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${month}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${year}'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '${chineseNumber}'+\r\n '
'+\r\n '
'+\r\n '
',\r\n copyRange: {}, //复制范围\r\n applyRange: {}, //应用范围\r\n applyType: null, //0复制单元格,1填充序列,2仅填充格式,3不带格式填充,4以天数填充,5以工作日填充,6以月填充,7以年填充,8以中文小写数字序列填充\r\n direction: null, //down-往下拖拽,right-往右拖拽,up-往上拖拽,left-往左拖拽\r\n chnNumChar: {\"零\": 0, \"一\": 1, \"二\": 2, \"三\": 3, \"四\": 4, \"五\": 5, \"六\": 6, \"七\": 7, \"八\": 8, \"九\": 9},\r\n chnNameValue: {\r\n \"十\": {value: 10, secUnit: false},\r\n \"百\": {value: 100, secUnit: false},\r\n \"千\": {value: 1000, secUnit: false},\r\n \"万\": {value: 10000, secUnit: true},\r\n \"亿\": {value: 100000000, secUnit: true}\r\n },\r\n ChineseToNumber: function(chnStr){\r\n let _this = this;\r\n\r\n let rtn = 0;\r\n let section = 0;\r\n let number = 0;\r\n let secUnit = false;\r\n let str = chnStr.split(\"\");\r\n\r\n for(let i = 0; i < str.length; i++){\r\n let num = _this.chnNumChar[str[i]];\r\n\r\n if(typeof num != \"undefined\"){\r\n number = num;\r\n\r\n if(i == str.length - 1){\r\n section += number;\r\n }\r\n }\r\n else{\r\n let unit = _this.chnNameValue[str[i]].value;\r\n secUnit = _this.chnNameValue[str[i]].secUnit;\r\n\r\n if(secUnit){\r\n section = (section + number) * unit;\r\n rtn += section;\r\n section = 0;\r\n }\r\n else{\r\n section += (number * unit);\r\n }\r\n\r\n number = 0;\r\n }\r\n }\r\n\r\n return rtn + section;\r\n },\r\n chnNumChar2: [\"零\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"七\", \"八\", \"九\"],\r\n chnUnitSection: [\"\", \"万\", \"亿\", \"万亿\", \"亿亿\"],\r\n chnUnitChar: [\"\", \"十\", \"百\", \"千\"],\r\n SectionToChinese: function(section){\r\n let _this = this;\r\n\r\n let strIns = '', chnStr = '';\r\n let unitPos = 0;\r\n let zero = true;\r\n\r\n while(section > 0){\r\n let v = section % 10;\r\n\r\n if(v == 0){\r\n if(!zero){\r\n zero = true;\r\n chnStr = _this.chnNumChar2[v] + chnStr;\r\n }\r\n }\r\n else{\r\n zero = false;\r\n strIns = _this.chnNumChar2[v];\r\n strIns += _this.chnUnitChar[unitPos];\r\n chnStr = strIns + chnStr;\r\n }\r\n\r\n unitPos++;\r\n section = Math.floor(section / 10);\r\n }\r\n\r\n return chnStr;\r\n },\r\n NumberToChinese: function(num){\r\n let _this = this;\r\n\r\n let unitPos = 0;\r\n let strIns = '', chnStr = '';\r\n let needZero = false;\r\n\r\n if(num == 0){\r\n return _this.chnNumChar2[0];\r\n }\r\n while(num > 0){\r\n let section = num % 10000;\r\n\r\n if(needZero){\r\n chnStr = _this.chnNumChar2[0] + chnStr;\r\n }\r\n\r\n strIns = _this.SectionToChinese(section);\r\n strIns += (section != 0) ? _this.chnUnitSection[unitPos] : _this.chnUnitSection[0];\r\n chnStr = strIns + chnStr;\r\n needZero = (section < 1000) && (section > 0);\r\n num = Math.floor(num / 10000);\r\n unitPos++;\r\n }\r\n\r\n return chnStr;\r\n },\r\n isChnNumber: function(txt){\r\n let _this = this;\r\n\r\n let isChnNumber = true;\r\n\r\n if(txt.length == 1){\r\n if(txt == \"日\" || (txt in _this.chnNumChar)){\r\n isChnNumber = true;\r\n }\r\n else{\r\n isChnNumber = false;\r\n }\r\n }\r\n else{\r\n let str = txt.split(\"\");\r\n for(let i = 0; i < str.length; i++){\r\n if(!((str[i] in _this.chnNumChar) || (str[i] in _this.chnNameValue))){\r\n isChnNumber = false;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return isChnNumber;\r\n },\r\n isExtendNumber: function(txt){\r\n let reg = /0|([1-9]+[0-9]*)/g;\r\n let isExtendNumber = reg.test(txt);\r\n\r\n if(isExtendNumber){\r\n let match = txt.match(reg);\r\n let matchTxt = match[match.length - 1];\r\n let matchIndex = txt.lastIndexOf(matchTxt);\r\n let beforeTxt = txt.substr(0, matchIndex);\r\n let afterTxt = txt.substr(matchIndex + matchTxt.length);\r\n\r\n return [isExtendNumber, Number(matchTxt), beforeTxt, afterTxt];\r\n }\r\n else {\r\n return [isExtendNumber]\r\n }\r\n },\r\n isChnWeek1: function(txt){\r\n let _this = this;\r\n\r\n let isChnWeek1;\r\n if(txt.length == 1){\r\n if(txt == \"日\" || _this.ChineseToNumber(txt) < 7){\r\n isChnWeek1 = true;\r\n }\r\n else{\r\n isChnWeek1 = false;\r\n }\r\n }\r\n else{\r\n isChnWeek1 = false;\r\n }\r\n\r\n return isChnWeek1;\r\n },\r\n isChnWeek2: function(txt){\r\n let isChnWeek2;\r\n if(txt.length == 2){\r\n if(txt == \"周一\" || txt == \"周二\" || txt == \"周三\" || txt == \"周四\" || txt == \"周五\" || txt == \"周六\" || txt == \"周日\"){\r\n isChnWeek2 = true;\r\n }\r\n else{\r\n isChnWeek2 = false;\r\n }\r\n }\r\n else{\r\n isChnWeek2 = false;\r\n }\r\n\r\n return isChnWeek2;\r\n },\r\n isChnWeek3: function(txt){\r\n let isChnWeek3;\r\n if(txt.length == 3){\r\n if(txt == \"星期一\" || txt == \"星期二\" || txt == \"星期三\" || txt == \"星期四\" || txt == \"星期五\" || txt == \"星期六\" || txt == \"星期日\"){\r\n isChnWeek3 = true;\r\n }\r\n else{\r\n isChnWeek3 = false;\r\n }\r\n }\r\n else{\r\n isChnWeek3 = false;\r\n }\r\n\r\n return isChnWeek3;\r\n },\r\n createIcon: function(){\r\n let _this = this;\r\n\r\n let copy_r = _this.copyRange[\"row\"][1],\r\n copy_c = _this.copyRange[\"column\"][1];\r\n let apply_r = _this.applyRange[\"row\"][1],\r\n apply_c = _this.applyRange[\"column\"][1];\r\n\r\n let row_index, col_index;\r\n if(apply_r >= copy_r && apply_c >= copy_c){\r\n row_index = apply_r;\r\n col_index = apply_c;\r\n }\r\n else{\r\n row_index = copy_r;\r\n col_index = copy_c;\r\n }\r\n\r\n let row = rowLocationByIndex(row_index)[1],\r\n row_pre = rowLocationByIndex(row_index)[0];\r\n let col = colLocationByIndex(col_index)[1],\r\n col_pre = colLocationByIndex(col_index)[0];\r\n\r\n $(\"#luckysheet-dropCell-icon\").remove();\r\n $(\"#luckysheet-cell-main\").append(_this.iconHtml);\r\n $(\"#luckysheet-dropCell-icon\").css({\"left\": col, \"top\": row});\r\n\r\n //点击icon\r\n $(\"#luckysheet-dropCell-icon\").mouseover(function(){\r\n $(this).css(\"background-color\", \"#ffe8e8\");\r\n }).mouseleave(function(){\r\n $(this).css(\"background-color\", \"#f1f1f1\");\r\n }).mousedown(function(event){\r\n $(\"#luckysheet-dropCell-typeList\").remove();\r\n const _locale = locale();\r\n const locale_dropCell = _locale.dropCell;\r\n $(\"body\").append(replaceHtml(_this.typeListHtml,{\r\n copyCell:locale_dropCell.copyCell,\r\n sequence:locale_dropCell.sequence,\r\n onlyFormat:locale_dropCell.onlyFormat,\r\n noFormat:locale_dropCell.noFormat,\r\n day:locale_dropCell.day,\r\n workDay:locale_dropCell.workDay,\r\n month:locale_dropCell.month,\r\n year:locale_dropCell.year,\r\n chineseNumber:locale_dropCell.chineseNumber,\r\n }));\r\n\r\n let typeItemHide = _this.typeItemHide();\r\n if(!typeItemHide[0] && !typeItemHide[1] && !typeItemHide[2] && !typeItemHide[3] && !typeItemHide[4] && !typeItemHide[5] && !typeItemHide[6]){\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=1]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=4]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=5]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=6]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=7]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=8]\").hide();\r\n }\r\n\r\n if(!typeItemHide[2]){\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=4]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=5]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=6]\").hide();\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=7]\").hide();\r\n }\r\n\r\n if(!typeItemHide[3]){\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=8]\").hide();\r\n }\r\n\r\n let left = $(this).offset().left;\r\n let top = $(this).offset().top + 25;\r\n let winH = $(window).height(), winW = $(window).width();\r\n let menuW = $(\"#luckysheet-dropCell-typeList\").width(),\r\n menuH = $(\"#luckysheet-dropCell-typeList\").height();\r\n\r\n if (left + menuW > winW) {\r\n left = left - menuW;\r\n }\r\n\r\n if (top + menuH > winH) {\r\n top = top - menuH - 38;\r\n }\r\n\r\n if (top < 0) {\r\n top = 0;\r\n }\r\n\r\n $(\"#luckysheet-dropCell-typeList\").css({\"left\": left, \"top\": top}).show();\r\n $(\"#luckysheet-dropCell-icon\").mouseleave(function(){ $(this).css(\"backgroundColor\", \"#ffe8e8\") });\r\n\r\n let type = _this.applyType;\r\n $(\"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem[data-type=\"+ type +\"]\").find(\"span\").append('');\r\n event.stopPropagation();\r\n });\r\n\r\n //点击数据填充类型\r\n $(document).off(\"click.dCtypeList\").on(\"click.dCtypeList\", \"#luckysheet-dropCell-typeList .luckysheet-cols-menuitem\", function(){\r\n $(\"#luckysheet-dropCell-typeList .fa-check\").remove();\r\n $(this).find(\"span\").append('');\r\n\r\n let type = $(this).attr(\"data-type\");\r\n _this.applyType = type;\r\n\r\n _this.update();\r\n\r\n $(\"#luckysheet-dropCell-typeList\").hide();\r\n $(\"#luckysheet-dropCell-icon\").css(\"backgroundColor\", \"#f1f1f1\");\r\n $(\"#luckysheet-dropCell-icon\").mouseleave(function(){ $(this).css(\"backgroundColor\", \"#f1f1f1\") });\r\n\r\n countfunc();\r\n });\r\n },\r\n typeItemHide: function(){\r\n let _this = this;\r\n\r\n let copyRange = _this.copyRange;\r\n let str_r = copyRange[\"row\"][0], end_r = copyRange[\"row\"][1];\r\n let str_c = copyRange[\"column\"][0], end_c = copyRange[\"column\"][1];\r\n\r\n let hasNumber = false,\r\n hasExtendNumber = false,\r\n hasDate = false,\r\n hasChn = false,\r\n hasChnWeek1 = false,\r\n hasChnWeek2 = false,\r\n hasChnWeek3 = false;\r\n\r\n for(let r = str_r; r <= end_r; r++){\r\n for(let c = str_c; c <= end_c; c++){\r\n if(!!Store.flowdata[r][c]){\r\n let cell = Store.flowdata[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"v\"] != null && cell[\"f\"] == null){\r\n if(cell[\"ct\"] != null && cell[\"ct\"].t == \"n\"){\r\n hasNumber = true;\r\n }\r\n else if(cell[\"ct\"] != null && cell[\"ct\"].t == \"d\"){\r\n hasDate = true;\r\n }\r\n else if(_this.isExtendNumber(cell[\"m\"])[0]){\r\n hasExtendNumber = true;\r\n }\r\n else if(_this.isChnNumber(cell[\"m\"]) && cell[\"m\"] != \"日\"){\r\n hasChn = true;\r\n }\r\n else if(cell[\"m\"] == \"日\"){\r\n hasChnWeek1 = true;\r\n }\r\n else if(_this.isChnWeek2(cell[\"m\"])){\r\n hasChnWeek2 = true;\r\n }\r\n else if(_this.isChnWeek3(cell[\"m\"])){\r\n hasChnWeek3 = true;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return [hasNumber, hasExtendNumber, hasDate, hasChn, hasChnWeek1, hasChnWeek2, hasChnWeek3];\r\n },\r\n update: function(){\r\n let _this = this;\r\n\r\n if(!checkProtectionLockedRangeList([_this.applyRange], Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n if(Store.allowEdit===false){\r\n return;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n let borderInfoCompute = getBorderInfoCompute();\r\n let dataVerification = $.extend(true, {}, file[\"dataVerification\"]);\r\n\r\n let direction = _this.direction;\r\n let type = _this.applyType;\r\n\r\n //复制范围\r\n let copyRange = _this.copyRange;\r\n let copy_str_r = copyRange[\"row\"][0], copy_end_r = copyRange[\"row\"][1];\r\n let copy_str_c = copyRange[\"column\"][0], copy_end_c = copyRange[\"column\"][1];\r\n let copyData = _this.getCopyData(d, copy_str_r, copy_end_r, copy_str_c, copy_end_c, direction);\r\n\r\n let csLen;\r\n if(direction == \"down\" || direction == \"up\"){\r\n csLen = copy_end_r - copy_str_r + 1;\r\n }\r\n else if(direction == \"right\" || direction == \"left\"){\r\n csLen = copy_end_c - copy_str_c + 1;\r\n }\r\n\r\n //应用范围\r\n let applyRange = _this.applyRange;\r\n let apply_str_r = applyRange[\"row\"][0], apply_end_r = applyRange[\"row\"][1];\r\n let apply_str_c = applyRange[\"column\"][0], apply_end_c = applyRange[\"column\"][1];\r\n\r\n if(direction == \"down\" || direction == \"up\"){\r\n let asLen = apply_end_r - apply_str_r + 1;\r\n\r\n for(let i = apply_str_c; i <= apply_end_c; i++){\r\n let copyD = copyData[i - apply_str_c];\r\n\r\n let applyData = _this.getApplyData(copyD, csLen, asLen);\r\n\r\n if(direction == \"down\"){\r\n for(let j = apply_str_r; j <= apply_end_r; j++){\r\n let cell = applyData[j - apply_str_r];\r\n\r\n if(cell.f != null){\r\n let f = \"=\" + formula.functionCopy(cell.f, \"down\", j - apply_str_r + 1);\r\n let v = formula.execfunction(f, j, i);\r\n\r\n formula.execFunctionGroup(j, i, v[1], undefined, d);\r\n\r\n cell.f = v[2];\r\n cell.v = v[1];\r\n\r\n if(cell.spl != null){\r\n cell.spl = v[3].data;\r\n }\r\n else{\r\n if(isRealNum(cell.v) && !/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(cell.v)){\r\n if(cell.v == Infinity || cell.v == -Infinity){\r\n cell.m = cell.v.toString();\r\n }\r\n else{\r\n if(cell.v.toString().indexOf(\"e\") > -1){\r\n let len = cell.v.toString().split(\".\")[1].split(\"e\")[0].length;\r\n if(len > 5){\r\n len = 5;\r\n }\r\n\r\n cell.m = cell.v.toExponential(len).toString();\r\n }\r\n else{\r\n let mask = genarate(Math.round(cell.v * 1000000000) / 1000000000);\r\n cell.m = mask[0].toString();\r\n }\r\n }\r\n\r\n cell.ct = { \"fa\": \"General\", \"t\": \"n\" };\r\n }\r\n else{\r\n let mask = genarate(cell.v);\r\n cell.m = mask[0].toString();\r\n cell.ct = mask[1];\r\n }\r\n }\r\n }\r\n\r\n d[j][i] = cell;\r\n\r\n //边框\r\n let bd_r = copy_str_r + (j - apply_str_r) % csLen;\r\n let bd_c = i;\r\n\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": j,\r\n \"col_index\": i,\r\n \"l\": borderInfoCompute[bd_r + \"_\" + bd_c].l,\r\n \"r\": borderInfoCompute[bd_r + \"_\" + bd_c].r,\r\n \"t\": borderInfoCompute[bd_r + \"_\" + bd_c].t,\r\n \"b\": borderInfoCompute[bd_r + \"_\" + bd_c].b\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n else if(borderInfoCompute[j + \"_\" + i]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": j,\r\n \"col_index\": i,\r\n \"l\": null,\r\n \"r\": null,\r\n \"t\": null,\r\n \"b\": null\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n //数据验证\r\n if(dataVerification[bd_r + \"_\" + bd_c]){\r\n dataVerification[j + \"_\" + i] = dataVerification[bd_r + \"_\" + bd_c];\r\n }\r\n }\r\n }\r\n if(direction == \"up\"){\r\n for(let j = apply_end_r; j >= apply_str_r; j--){\r\n let cell = applyData[apply_end_r - j];\r\n\r\n if(cell.f != null){\r\n let f = \"=\" + formula.functionCopy(cell.f, \"up\", apply_end_r - j + 1);\r\n let v = formula.execfunction(f, j, i);\r\n\r\n formula.execFunctionGroup(j, i, v[1], undefined, d);\r\n\r\n cell.f = v[2];\r\n cell.v = v[1];\r\n\r\n if(cell.spl != null){\r\n cell.spl = v[3].data;\r\n }\r\n else{\r\n if(isRealNum(cell.v) && !/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(cell.v)){\r\n if(cell.v == Infinity || cell.v == -Infinity){\r\n cell.m = cell.v.toString();\r\n }\r\n else{\r\n if(cell.v.toString().indexOf(\"e\") > -1){\r\n let len = cell.v.toString().split(\".\")[1].split(\"e\")[0].length;\r\n if(len > 5){\r\n len = 5;\r\n }\r\n\r\n cell.m = cell.v.toExponential(len).toString();\r\n }\r\n else{\r\n let mask = genarate(Math.round(cell.v * 1000000000) / 1000000000);\r\n cell.m = mask[0].toString();\r\n }\r\n }\r\n\r\n cell.ct = { \"fa\": \"General\", \"t\": \"n\" };\r\n }\r\n else{\r\n let mask = genarate(cell.v);\r\n cell.m = mask[0].toString();\r\n cell.ct = mask[1];\r\n }\r\n }\r\n }\r\n\r\n d[j][i] = cell;\r\n\r\n //边框\r\n let bd_r = copy_end_r - (apply_end_r - j) % csLen;\r\n let bd_c = i;\r\n\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": j,\r\n \"col_index\": i,\r\n \"l\": borderInfoCompute[bd_r + \"_\" + bd_c].l,\r\n \"r\": borderInfoCompute[bd_r + \"_\" + bd_c].r,\r\n \"t\": borderInfoCompute[bd_r + \"_\" + bd_c].t,\r\n \"b\": borderInfoCompute[bd_r + \"_\" + bd_c].b\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n else if(borderInfoCompute[j + \"_\" + i]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": j,\r\n \"col_index\": i,\r\n \"l\": null,\r\n \"r\": null,\r\n \"t\": null,\r\n \"b\": null\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n //数据验证\r\n if(dataVerification[bd_r + \"_\" + bd_c]){\r\n dataVerification[j + \"_\" + i] = dataVerification[bd_r + \"_\" + bd_c];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(direction == \"right\" || direction == \"left\"){\r\n let asLen = apply_end_c - apply_str_c + 1;\r\n\r\n for(let i = apply_str_r; i <= apply_end_r; i++){\r\n let copyD = copyData[i - apply_str_r];\r\n\r\n let applyData = _this.getApplyData(copyD, csLen, asLen);\r\n\r\n if(direction == \"right\"){\r\n for(let j = apply_str_c; j <= apply_end_c; j++){\r\n let cell = applyData[j - apply_str_c];\r\n\r\n if(cell.f != null){\r\n let f = \"=\" + formula.functionCopy(cell.f, \"right\", j - apply_str_c + 1);\r\n let v = formula.execfunction(f, i, j);\r\n\r\n formula.execFunctionGroup(j, i, v[1], undefined, d);\r\n\r\n cell.f = v[2];\r\n cell.v = v[1];\r\n\r\n if(cell.spl != null){\r\n cell.spl = v[3].data;\r\n }\r\n else{\r\n if(isRealNum(cell.v) && !/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(cell.v)){\r\n if(cell.v == Infinity || cell.v == -Infinity){\r\n cell.m = cell.v.toString();\r\n }\r\n else{\r\n if(cell.v.toString().indexOf(\"e\") > -1){\r\n let len = cell.v.toString().split(\".\")[1].split(\"e\")[0].length;\r\n if(len > 5){\r\n len = 5;\r\n }\r\n\r\n cell.m = cell.v.toExponential(len).toString();\r\n }\r\n else{\r\n let mask = genarate(Math.round(cell.v * 1000000000) / 1000000000);\r\n cell.m = mask[0].toString();\r\n }\r\n }\r\n\r\n cell.ct = { \"fa\": \"General\", \"t\": \"n\" };\r\n }\r\n else{\r\n let mask = genarate(cell.v);\r\n cell.m = mask[0].toString();\r\n cell.ct = mask[1];\r\n }\r\n }\r\n }\r\n\r\n d[i][j] = cell;\r\n\r\n //边框\r\n let bd_r = i;\r\n let bd_c = copy_str_c + (j - apply_str_c) % csLen;\r\n\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": i,\r\n \"col_index\": j,\r\n \"l\": borderInfoCompute[bd_r + \"_\" + bd_c].l,\r\n \"r\": borderInfoCompute[bd_r + \"_\" + bd_c].r,\r\n \"t\": borderInfoCompute[bd_r + \"_\" + bd_c].t,\r\n \"b\": borderInfoCompute[bd_r + \"_\" + bd_c].b\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n else if(borderInfoCompute[i + \"_\" + j]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": i,\r\n \"col_index\": j,\r\n \"l\": null,\r\n \"r\": null,\r\n \"t\": null,\r\n \"b\": null\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n //数据验证\r\n if(dataVerification[bd_r + \"_\" + bd_c]){\r\n dataVerification[i + \"_\" + j] = dataVerification[bd_r + \"_\" + bd_c];\r\n }\r\n }\r\n }\r\n if(direction == \"left\"){\r\n for(let j = apply_end_c; j >= apply_str_c; j--){\r\n let cell = applyData[apply_end_c - j];\r\n\r\n if(cell.f != null){\r\n let f = \"=\" + formula.functionCopy(cell.f, \"left\", apply_end_c - j + 1);\r\n let v = formula.execfunction(f, i, j);\r\n\r\n formula.execFunctionGroup(j, i, v[1], undefined, d);\r\n\r\n cell.f = v[2];\r\n cell.v = v[1];\r\n\r\n if(cell.spl != null){\r\n cell.spl = v[3].data;\r\n }\r\n else{\r\n if(isRealNum(cell.v) && !/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(cell.v)){\r\n if(cell.v == Infinity || cell.v == -Infinity){\r\n cell.m = cell.v.toString();\r\n }\r\n else{\r\n if(cell.v.toString().indexOf(\"e\") > -1){\r\n let len = cell.v.toString().split(\".\")[1].split(\"e\")[0].length;\r\n if(len > 5){\r\n len = 5;\r\n }\r\n\r\n cell.m = cell.v.toExponential(len).toString();\r\n }\r\n else{\r\n let mask = genarate(Math.round(cell.v * 1000000000) / 1000000000);\r\n cell.m = mask[0].toString();\r\n }\r\n }\r\n\r\n cell.ct = { \"fa\": \"General\", \"t\": \"n\" };\r\n }\r\n else{\r\n let mask = genarate(cell.v);\r\n cell.m = mask[0].toString();\r\n cell.ct = mask[1];\r\n }\r\n }\r\n }\r\n\r\n d[i][j] = cell;\r\n\r\n //边框\r\n let bd_r = i;\r\n let bd_c = copy_end_c - (apply_end_c - j) % csLen;\r\n\r\n if(borderInfoCompute[bd_r + \"_\" + bd_c]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": i,\r\n \"col_index\": j,\r\n \"l\": borderInfoCompute[bd_r + \"_\" + bd_c].l,\r\n \"r\": borderInfoCompute[bd_r + \"_\" + bd_c].r,\r\n \"t\": borderInfoCompute[bd_r + \"_\" + bd_c].t,\r\n \"b\": borderInfoCompute[bd_r + \"_\" + bd_c].b\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n else if(borderInfoCompute[i + \"_\" + j]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": i,\r\n \"col_index\": j,\r\n \"l\": null,\r\n \"r\": null,\r\n \"t\": null,\r\n \"b\": null\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n //数据验证\r\n if(dataVerification[bd_r + \"_\" + bd_c]){\r\n dataVerification[i + \"_\" + j] = dataVerification[bd_r + \"_\" + bd_c];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n //条件格式\r\n let cdformat = $.extend(true, [], file[\"luckysheet_conditionformat_save\"]);\r\n if(cdformat != null && cdformat.length > 0){\r\n for(let i = 0; i < cdformat.length; i++){\r\n let cdformat_cellrange = cdformat[i].cellrange;\r\n\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < cdformat_cellrange.length; j++){\r\n let range = conditionformat.CFSplitRange(cdformat_cellrange[j], {\"row\": copyRange[\"row\"], \"column\": copyRange[\"column\"]}, {\"row\": applyRange[\"row\"], \"column\": applyRange[\"column\"]}, \"operatePart\");\r\n if(range.length > 0){\r\n emptyRange = emptyRange.concat(range);\r\n }\r\n }\r\n\r\n if(emptyRange.length > 0){\r\n cdformat[i].cellrange.push(applyRange);\r\n }\r\n }\r\n }\r\n\r\n //刷新一次表格\r\n let allParam = {\r\n \"cfg\": cfg,\r\n \"cdformat\": cdformat,\r\n \"dataVerification\": dataVerification\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n\r\n selectHightlightShow();\r\n },\r\n getCopyData: function(d, r1, r2, c1, c2, direction){\r\n let _this = this;\r\n\r\n let copyData = [];\r\n\r\n let a1, a2, b1, b2;\r\n if(direction == \"down\" || direction == \"up\"){\r\n a1 = c1;\r\n a2 = c2;\r\n b1 = r1;\r\n b2 = r2;\r\n }\r\n else if(direction == \"right\" || direction == \"left\"){\r\n a1 = r1;\r\n a2 = r2;\r\n b1 = c1;\r\n b2 = c2;\r\n }\r\n\r\n for(let a = a1; a <= a2; a++){\r\n let obj = {};\r\n\r\n let arrData = [];\r\n let arrIndex = [];\r\n let text = \"\";\r\n let extendNumberBeforeStr = null;\r\n let extendNumberAfterStr = null;\r\n let isSameStr = true;\r\n\r\n for(let b = b1; b <= b2; b++){\r\n //单元格\r\n let data;\r\n if(direction == \"down\" || direction == \"up\"){\r\n data = d[b][a];\r\n }\r\n else if(direction == \"right\" || direction == \"left\"){\r\n data = d[a][b];\r\n }\r\n\r\n //单元格值类型\r\n let str;\r\n if(!!data && !!data[\"v\"] && data[\"f\"] == null){\r\n if(!!data[\"ct\"] && data[\"ct\"][\"t\"] == \"n\"){\r\n str = \"number\";\r\n extendNumberBeforeStr = null;\r\n extendNumberAfterStr = null;\r\n }\r\n else if(!!data[\"ct\"] && data[\"ct\"][\"t\"] == \"d\"){\r\n str = \"date\";\r\n extendNumberBeforeStr = null;\r\n extendNumberAfterStr = null;\r\n }\r\n else if(_this.isExtendNumber(data[\"m\"])[0]){\r\n str = \"extendNumber\";\r\n\r\n let isExtendNumber = _this.isExtendNumber(data[\"m\"]);\r\n\r\n if(extendNumberBeforeStr == null || extendNumberAfterStr == null){\r\n isSameStr = true;\r\n extendNumberBeforeStr = isExtendNumber[2];\r\n extendNumberAfterStr = isExtendNumber[3];\r\n }\r\n else {\r\n if(isExtendNumber[2] != extendNumberBeforeStr || isExtendNumber[3] != extendNumberAfterStr){\r\n isSameStr = false;\r\n extendNumberBeforeStr = isExtendNumber[2];\r\n extendNumberAfterStr = isExtendNumber[3];\r\n }\r\n else {\r\n isSameStr = true;\r\n }\r\n }\r\n }\r\n else if(_this.isChnNumber(data[\"m\"])){\r\n str = \"chnNumber\";\r\n extendNumberBeforeStr = null;\r\n extendNumberAfterStr = null;\r\n }\r\n else if(_this.isChnWeek2(data[\"m\"])){\r\n str = \"chnWeek2\";\r\n extendNumberBeforeStr = null;\r\n extendNumberAfterStr = null;\r\n }\r\n else if(_this.isChnWeek3(data[\"m\"])){\r\n str = \"chnWeek3\";\r\n extendNumberBeforeStr = null;\r\n extendNumberAfterStr = null;\r\n }\r\n else{\r\n str = \"other\";\r\n extendNumberBeforeStr = null;\r\n extendNumberAfterStr = null;\r\n }\r\n }\r\n else{\r\n str = \"other\";\r\n extendNumberBeforeStr = null;\r\n extendNumberAfterStr = null;\r\n }\r\n\r\n if(str == \"extendNumber\"){\r\n if(b == b1){\r\n if(b1 == b2){\r\n text = str;\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n text = str;\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n }\r\n }\r\n else if(b == b2){\r\n if(text == str && isSameStr){\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n else{\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n\r\n text = str;\r\n arrData = [];\r\n arrData.push(data);\r\n arrIndex = [];\r\n arrIndex.push(b - b1 + 1);\r\n\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n }\r\n else{\r\n if(text == str && isSameStr){\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n }\r\n else{\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n\r\n text = str;\r\n arrData = [];\r\n arrData.push(data);\r\n arrIndex = [];\r\n arrIndex.push(b - b1 + 1);\r\n }\r\n }\r\n }\r\n else{\r\n if(b == b1){\r\n if(b1 == b2){\r\n text = str;\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n text = str;\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n }\r\n }\r\n else if(b == b2){\r\n if(text == str){\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n else{\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n\r\n text = str;\r\n arrData = [];\r\n arrData.push(data);\r\n arrIndex = [];\r\n arrIndex.push(b - b1 + 1);\r\n\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n }\r\n else{\r\n if(text == str){\r\n arrData.push(data);\r\n arrIndex.push(b - b1 + 1);\r\n }\r\n else{\r\n if(text in obj){\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n else{\r\n obj[text] = [];\r\n obj[text].push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n\r\n text = str;\r\n arrData = [];\r\n arrData.push(data);\r\n arrIndex = [];\r\n arrIndex.push(b - b1 + 1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n copyData.push(obj);\r\n }\r\n\r\n return copyData;\r\n },\r\n getApplyData: function(copyD, csLen, asLen){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n\r\n let direction = _this.direction;\r\n let type = _this.applyType;\r\n\r\n let num = Math.floor(asLen / csLen);\r\n let rsd = asLen % csLen;\r\n\r\n //纯数字类型\r\n let copyD_number = copyD[\"number\"];\r\n let applyD_number = [];\r\n if(!!copyD_number){\r\n for(let i = 0; i < copyD_number.length; i++){\r\n let s = _this.getLenS(copyD_number[i][\"index\"], rsd);\r\n let len = copyD_number[i][\"index\"].length * num + s;\r\n\r\n let arrData;\r\n if(type == \"1\" || type == \"3\"){\r\n arrData = _this.getDataByType(copyD_number[i][\"data\"], len, direction, type, \"number\");\r\n }\r\n else if(type == \"2\"){\r\n arrData = _this.getDataByType(copyD_number[i][\"data\"], len, direction, type);\r\n }\r\n else{\r\n arrData = _this.getDataByType(copyD_number[i][\"data\"], len, direction, \"0\");\r\n }\r\n\r\n let arrIndex = _this.getDataIndex(csLen, asLen, copyD_number[i][\"index\"]);\r\n applyD_number.push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n\r\n //扩展数字型(即一串字符最后面的是数字)\r\n let copyD_extendNumber = copyD[\"extendNumber\"];\r\n let applyD_extendNumber = [];\r\n if(!!copyD_extendNumber){\r\n for(let i = 0; i < copyD_extendNumber.length; i++){\r\n let s = _this.getLenS(copyD_extendNumber[i][\"index\"], rsd);\r\n let len = copyD_extendNumber[i][\"index\"].length * num + s;\r\n\r\n let arrData;\r\n if(type == \"1\" || type == \"3\"){\r\n arrData = _this.getDataByType(copyD_extendNumber[i][\"data\"], len, direction, type, \"extendNumber\");\r\n }\r\n else if(type == \"2\"){\r\n arrData = _this.getDataByType(copyD_extendNumber[i][\"data\"], len, direction, type);\r\n }\r\n else{\r\n arrData = _this.getDataByType(copyD_extendNumber[i][\"data\"], len, direction, \"0\");\r\n }\r\n\r\n let arrIndex = _this.getDataIndex(csLen, asLen, copyD_extendNumber[i][\"index\"]);\r\n applyD_extendNumber.push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n\r\n //日期类型\r\n let copyD_date = copyD[\"date\"];\r\n let applyD_date = [];\r\n if(!!copyD_date){\r\n for(let i = 0; i < copyD_date.length; i++){\r\n let s = _this.getLenS(copyD_date[i][\"index\"], rsd);\r\n let len = copyD_date[i][\"index\"].length * num + s;\r\n\r\n let arrData;\r\n if(type == \"1\" || type == \"3\"){\r\n arrData = _this.getDataByType(copyD_date[i][\"data\"], len, direction, type, \"date\");\r\n }\r\n else if(type == \"8\"){\r\n arrData = _this.getDataByType(copyD_date[i][\"data\"], len, direction, \"0\");\r\n }\r\n else{\r\n arrData = _this.getDataByType(copyD_date[i][\"data\"], len, direction, type);\r\n }\r\n\r\n let arrIndex = _this.getDataIndex(csLen, asLen, copyD_date[i][\"index\"]);\r\n applyD_date.push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n\r\n //中文小写数字 或 一~日\r\n let copyD_chnNumber = copyD[\"chnNumber\"];\r\n let applyD_chnNumber = [];\r\n if(!!copyD_chnNumber){\r\n for(let i = 0; i < copyD_chnNumber.length; i++){\r\n let s = _this.getLenS(copyD_chnNumber[i][\"index\"], rsd);\r\n let len = copyD_chnNumber[i][\"index\"].length * num + s;\r\n\r\n let arrData;\r\n if(type == \"1\" || type == \"3\"){\r\n arrData = _this.getDataByType(copyD_chnNumber[i][\"data\"], len, direction, type, \"chnNumber\");\r\n }\r\n else if(type == \"2\" || type == \"8\"){\r\n arrData = _this.getDataByType(copyD_chnNumber[i][\"data\"], len, direction, type);\r\n }\r\n else{\r\n arrData = _this.getDataByType(copyD_chnNumber[i][\"data\"], len, direction, \"0\");\r\n }\r\n\r\n let arrIndex = _this.getDataIndex(csLen, asLen, copyD_chnNumber[i][\"index\"]);\r\n applyD_chnNumber.push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n\r\n //周一~周日\r\n let copyD_chnWeek2 = copyD[\"chnWeek2\"];\r\n let applyD_chnWeek2 = [];\r\n if(!!copyD_chnWeek2){\r\n for(let i = 0; i < copyD_chnWeek2.length; i++){\r\n let s = _this.getLenS(copyD_chnWeek2[i][\"index\"], rsd);\r\n let len = copyD_chnWeek2[i][\"index\"].length * num + s;\r\n\r\n let arrData;\r\n if(type == \"1\" || type == \"3\"){\r\n arrData = _this.getDataByType(copyD_chnWeek2[i][\"data\"], len, direction, type, \"chnWeek2\");\r\n }\r\n else if(type == \"2\"){\r\n arrData = _this.getDataByType(copyD_chnWeek2[i][\"data\"], len, direction, type);\r\n }\r\n else{\r\n arrData = _this.getDataByType(copyD_chnWeek2[i][\"data\"], len, direction, \"0\");\r\n }\r\n\r\n let arrIndex = _this.getDataIndex(csLen, asLen, copyD_chnWeek2[i][\"index\"]);\r\n applyD_chnWeek2.push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n\r\n //星期一~星期日\r\n let copyD_chnWeek3 = copyD[\"chnWeek3\"];\r\n let applyD_chnWeek3 = [];\r\n if(!!copyD_chnWeek3){\r\n for(let i = 0; i < copyD_chnWeek3.length; i++){\r\n let s = _this.getLenS(copyD_chnWeek3[i][\"index\"], rsd);\r\n let len = copyD_chnWeek3[i][\"index\"].length * num + s;\r\n\r\n let arrData;\r\n if(type == \"1\" || type == \"3\"){\r\n arrData = _this.getDataByType(copyD_chnWeek3[i][\"data\"], len, direction, type, \"chnWeek3\");\r\n }\r\n else if(type == \"2\"){\r\n arrData = _this.getDataByType(copyD_chnWeek3[i][\"data\"], len, direction, type);\r\n }\r\n else{\r\n arrData = _this.getDataByType(copyD_chnWeek3[i][\"data\"], len, direction, \"0\");\r\n }\r\n\r\n let arrIndex = _this.getDataIndex(csLen, asLen, copyD_chnWeek3[i][\"index\"]);\r\n applyD_chnWeek3.push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n\r\n //其它\r\n let copyD_other = copyD[\"other\"];\r\n let applyD_other = [];\r\n if(!!copyD_other){\r\n for(let i = 0; i < copyD_other.length; i++){\r\n let s = _this.getLenS(copyD_other[i][\"index\"], rsd);\r\n let len = copyD_other[i][\"index\"].length * num + s;\r\n\r\n let arrData;\r\n if(type == \"2\" || type == \"3\"){\r\n arrData = _this.getDataByType(copyD_other[i][\"data\"], len, direction, type);\r\n }\r\n else{\r\n arrData = _this.getDataByType(copyD_other[i][\"data\"], len, direction, \"0\");\r\n }\r\n\r\n let arrIndex = _this.getDataIndex(csLen, asLen, copyD_other[i][\"index\"]);\r\n applyD_other.push({\"data\": arrData, \"index\": arrIndex});\r\n }\r\n }\r\n\r\n for(let x = 1; x <= asLen; x++){\r\n if(applyD_number.length > 0){\r\n for(let y = 0; y < applyD_number.length; y++){\r\n if(x in applyD_number[y][\"index\"]){\r\n applyData.push(applyD_number[y][\"data\"][applyD_number[y][\"index\"][x]]);\r\n }\r\n }\r\n }\r\n\r\n if(applyD_extendNumber.length > 0){\r\n for(let y = 0; y < applyD_extendNumber.length; y++){\r\n if(x in applyD_extendNumber[y][\"index\"]){\r\n applyData.push(applyD_extendNumber[y][\"data\"][applyD_extendNumber[y][\"index\"][x]]);\r\n }\r\n }\r\n }\r\n\r\n if(applyD_date.length > 0){\r\n for(let y = 0; y < applyD_date.length; y++){\r\n if(x in applyD_date[y][\"index\"]){\r\n applyData.push(applyD_date[y][\"data\"][applyD_date[y][\"index\"][x]]);\r\n }\r\n }\r\n }\r\n\r\n if(applyD_chnNumber.length > 0){\r\n for(let y = 0; y < applyD_chnNumber.length; y++){\r\n if(x in applyD_chnNumber[y][\"index\"]){\r\n applyData.push(applyD_chnNumber[y][\"data\"][applyD_chnNumber[y][\"index\"][x]]);\r\n }\r\n }\r\n }\r\n\r\n if(applyD_chnWeek2.length > 0){\r\n for(let y = 0; y < applyD_chnWeek2.length; y++){\r\n if(x in applyD_chnWeek2[y][\"index\"]){\r\n applyData.push(applyD_chnWeek2[y][\"data\"][applyD_chnWeek2[y][\"index\"][x]]);\r\n }\r\n }\r\n }\r\n\r\n if(applyD_chnWeek3.length > 0){\r\n for(let y = 0; y < applyD_chnWeek3.length; y++){\r\n if(x in applyD_chnWeek3[y][\"index\"]){\r\n applyData.push(applyD_chnWeek3[y][\"data\"][applyD_chnWeek3[y][\"index\"][x]]);\r\n }\r\n }\r\n }\r\n\r\n if(applyD_other.length > 0){\r\n for(let y = 0; y < applyD_other.length; y++){\r\n if(x in applyD_other[y][\"index\"]){\r\n applyData.push(applyD_other[y][\"data\"][applyD_other[y][\"index\"][x]]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return applyData;\r\n },\r\n getLenS: function(indexArr, rsd){\r\n let s = 0;\r\n\r\n for(let j = 0; j < indexArr.length; j++){\r\n if(indexArr[j] <= rsd){\r\n s++;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n\r\n return s;\r\n },\r\n getDataIndex: function(csLen, asLen, indexArr){\r\n let obj = {};\r\n\r\n let num = Math.floor(asLen / csLen);\r\n let rsd = asLen % csLen;\r\n\r\n let sum = 0;\r\n if(num > 0){\r\n for(let i = 1; i <= num; i++){\r\n for(let j = 0; j < indexArr.length; j++){\r\n obj[indexArr[j] + (i - 1) * csLen] = sum;\r\n sum++;\r\n }\r\n }\r\n for(let a = 0; a < indexArr.length; a++){\r\n if(indexArr[a] <= rsd){\r\n obj[indexArr[a] + csLen * num] = sum;\r\n sum++;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n }\r\n else{\r\n for(let a = 0; a < indexArr.length; a++){\r\n if(indexArr[a] <= rsd){\r\n obj[indexArr[a]] = sum;\r\n sum++;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return obj;\r\n },\r\n getDataByType: function(data, len, direction, type ,dataType){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n\r\n if(type == \"0\"){ //复制单元格\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n else if(type == \"1\"){ //填充序列\r\n if(dataType == \"number\"){\r\n //数据类型是 数字\r\n applyData = _this.FillSeries(data, len, direction);\r\n }\r\n else if(dataType == \"extendNumber\"){\r\n //扩展数字\r\n if(data.length == 1){\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillExtendNumber(data, len, step);\r\n }\r\n else{\r\n let dataNumArr = [];\r\n\r\n for(let i = 0; i < data.length; i++){\r\n let txt = data[i][\"m\"];\r\n dataNumArr.push(Number(_this.isExtendNumber(txt)[1]));\r\n }\r\n\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n dataNumArr.reverse();\r\n }\r\n\r\n if(_this.isEqualDiff(dataNumArr)){\r\n //等差数列,以等差为step\r\n let step = dataNumArr[1] - dataNumArr[0];\r\n applyData = _this.FillExtendNumber(data, len, step);\r\n }\r\n else{\r\n //不是等差数列,复制数据\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(dataType == \"date\"){\r\n //数据类型是 日期\r\n if(data.length == 1){\r\n //以一天为step\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillDays(data, len, step);\r\n }\r\n else{\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let judgeDate = _this.judgeDate(data);\r\n if(judgeDate[0] && judgeDate[3]){\r\n //日一样,月差为等差数列,以月差为step\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\");\r\n applyData = _this.FillMonths(data, len, step);\r\n }\r\n else if(!judgeDate[0] && judgeDate[2]){\r\n //日不一样,日差为等差数列,以日差为step\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"days\");\r\n applyData = _this.FillDays(data, len, step);\r\n }\r\n else{\r\n //其它,复制数据\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(dataType == \"chnNumber\"){\r\n //数据类型是 中文小写数字\r\n if(data.length == 1){\r\n if(data[0][\"m\"] == \"日\" || _this.ChineseToNumber(data[0][\"m\"]) < 7){\r\n //数字小于7,以周一~周日序列填充\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillChnWeek(data, len, step);\r\n }\r\n else{\r\n //数字大于7,以中文小写数字序列填充\r\n let step\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillChnNumber(data, len, step);\r\n }\r\n }\r\n else{\r\n let hasweek = false;\r\n for(let i = 0; i < data.length; i++){\r\n if(data[i][\"m\"] == \"日\"){\r\n hasweek = true;\r\n break;\r\n }\r\n }\r\n\r\n let dataNumArr = [];\r\n let weekIndex = 0;\r\n for(let i = 0; i < data.length; i++){\r\n if(data[i][\"m\"] == \"日\"){\r\n if(i == 0){\r\n dataNumArr.push(0);\r\n }\r\n else{\r\n weekIndex++;\r\n dataNumArr.push(weekIndex * 7);\r\n }\r\n }\r\n else if(hasweek && _this.ChineseToNumber(data[i][\"m\"]) > 0 && _this.ChineseToNumber(data[i][\"m\"]) < 7){\r\n dataNumArr.push(_this.ChineseToNumber(data[i][\"m\"]) + weekIndex * 7);\r\n }\r\n else{\r\n dataNumArr.push(_this.ChineseToNumber(data[i][\"m\"]));\r\n }\r\n }\r\n\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n dataNumArr.reverse();\r\n }\r\n\r\n if(_this.isEqualDiff(dataNumArr)){\r\n if(hasweek || (dataNumArr[dataNumArr.length - 1] < 6 && dataNumArr[0] > 0) || (dataNumArr[0] < 6 && dataNumArr[dataNumArr.length - 1] > 0)){\r\n //以周一~周日序列填充\r\n let step = dataNumArr[1] - dataNumArr[0];\r\n applyData = _this.FillChnWeek(data, len, step);\r\n }\r\n else{\r\n //以中文小写数字序列填充\r\n let step = dataNumArr[1] - dataNumArr[0];\r\n applyData = _this.FillChnNumber(data, len, step);\r\n }\r\n }\r\n else{\r\n //不是等差数列,复制数据\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(dataType == \"chnWeek2\"){\r\n //周一~周日\r\n if(data.length == 1){\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillChnWeek2(data, len, step);\r\n }\r\n else{\r\n let dataNumArr = [];\r\n let weekIndex = 0;\r\n\r\n for(let i = 0; i < data.length; i++){\r\n let lastTxt = data[i][\"m\"].substr(data[i][\"m\"].length - 1, 1);\r\n if(data[i][\"m\"] == \"周日\"){\r\n if(i == 0){\r\n dataNumArr.push(0);\r\n }\r\n else{\r\n weekIndex++;\r\n dataNumArr.push(weekIndex * 7);\r\n }\r\n }\r\n else{\r\n dataNumArr.push(_this.ChineseToNumber(lastTxt) + weekIndex * 7);\r\n }\r\n }\r\n\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n dataNumArr.reverse();\r\n }\r\n\r\n if(_this.isEqualDiff(dataNumArr)){\r\n //等差数列,以等差为step\r\n let step = dataNumArr[1] - dataNumArr[0];\r\n applyData = _this.FillChnWeek2(data, len, step);\r\n }\r\n else{\r\n //不是等差数列,复制数据\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(dataType == \"chnWeek3\"){\r\n //星期一~星期日\r\n if(data.length == 1){\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillChnWeek3(data, len, step);\r\n }\r\n else{\r\n let dataNumArr = [];\r\n let weekIndex = 0;\r\n\r\n for(let i = 0; i < data.length; i++){\r\n let lastTxt = data[i][\"m\"].substr(data[i][\"m\"].length - 1, 1);\r\n if(data[i][\"m\"] == \"星期日\"){\r\n if(i == 0){\r\n dataNumArr.push(0);\r\n }\r\n else{\r\n weekIndex++;\r\n dataNumArr.push(weekIndex * 7);\r\n }\r\n }\r\n else{\r\n dataNumArr.push(_this.ChineseToNumber(lastTxt) + weekIndex * 7);\r\n }\r\n }\r\n\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n dataNumArr.reverse();\r\n }\r\n\r\n if(_this.isEqualDiff(dataNumArr)){\r\n //等差数列,以等差为step\r\n let step = dataNumArr[1] - dataNumArr[0];\r\n applyData = _this.FillChnWeek3(data, len, step);\r\n }\r\n else{\r\n //不是等差数列,复制数据\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else{\r\n //数据类型是 其它\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n else if(type == \"2\"){ //仅填充格式\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n applyData = _this.FillOnlyFormat(data, len);\r\n }\r\n else if(type == \"3\"){ //不带格式填充\r\n let dataArr = _this.getDataByType(data, len, direction, \"1\" ,dataType);\r\n applyData = _this.FillWithoutFormat(dataArr);\r\n }\r\n else if(type == \"4\"){ //以天数填充\r\n if(data.length == 1){\r\n //以一天为step\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillDays(data, len, step);\r\n }\r\n else if(data.length == 2){\r\n //以日差为step\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"days\");\r\n applyData = _this.FillDays(data, len, step);\r\n }\r\n else{\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let judgeDate = _this.judgeDate(data);\r\n if(judgeDate[0] && judgeDate[3]){\r\n //日一样,且月差为等差数列,以月差为step\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\");\r\n applyData = _this.FillMonths(data, len, step);\r\n }\r\n else if(!judgeDate[0] && judgeDate[2]){\r\n //日不一样,且日差为等差数列,以日差为step\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"days\");\r\n applyData = _this.FillDays(data, len, step);\r\n }\r\n else{\r\n //日差不是等差数列,复制数据\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(type == \"5\"){ //以工作日填充\r\n if(data.length == 1){\r\n //以一天为step(若那天为休息日,则跳过)\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n let newLen = Math.round(len * 1.5);\r\n for(let i = 1; i <= newLen; i++){\r\n let d = $.extend(true, {}, data[0]);\r\n\r\n let day = dayjs(d[\"m\"]).add(i, \"days\").day();\r\n if(day == 0 || day == 6){\r\n continue;\r\n }\r\n\r\n let date = dayjs(d[\"m\"]).add(step * i, \"days\").format(\"YYYY-MM-DD\");\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n\r\n if(applyData.length == len){\r\n break;\r\n }\r\n }\r\n }\r\n else if(data.length == 2){\r\n if(dayjs(data[1][\"m\"]).date() == dayjs(data[0][\"m\"]).date() && dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\") != 0){\r\n //日一样,且月差大于一月,以月差为step(若那天为休息日,则向前取最近的工作日)\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\");\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let day = dayjs(data[data.length - 1]).add(step * i, \"months\").day(),\r\n date;\r\n if(day == 0){\r\n date = dayjs(data[data.length - 1]).add(step * i, \"months\").subtract(2, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else if(day == 6){\r\n date = dayjs(data[data.length - 1]).add(step * i, \"months\").subtract(1, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else{\r\n date = dayjs(data[data.length - 1]).add(step * i, \"months\").format(\"YYYY-MM-DD\");\r\n }\r\n\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n else{\r\n //日不一样\r\n if(Math.abs(dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]))) > 7){\r\n //若日差大于7天,以一月为step(若那天是休息日,则向前取最近的工作日)\r\n let step_month;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_month = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_month = -1;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_month * num, \"months\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let day = dayjs(d[\"m\"]).add(step, \"days\").day(),\r\n date;\r\n if(day == 0){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(2, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else if(day == 6){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(1, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else{\r\n date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n else{\r\n //若日差小于等于7天,以7天为step(若那天是休息日,则向前取最近的工作日)\r\n let step_day;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_day = 7;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_day = -7;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_day * num, \"days\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let day = dayjs(d[\"m\"]).add(step, \"days\").day(),\r\n date;\r\n if(day == 0){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(2, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else if(day == 6){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(1, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else{\r\n date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n let judgeDate = _this.judgeDate(data);\r\n if(judgeDate[0] && judgeDate[3]){\r\n //日一样,且月差为等差数列,以月差为step(若那天为休息日,则向前取最近的工作日)\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\");\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let day = dayjs(data[data.length - 1][\"m\"]).add(step * i, \"months\").day(),\r\n date;\r\n if(day == 0){\r\n date = dayjs(data[data.length - 1][\"m\"]).add(step * i, \"months\").subtract(2, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else if(day == 6){\r\n date = dayjs(data[data.length - 1][\"m\"]).add(step * i, \"months\").subtract(1, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else{\r\n date = dayjs(data[data.length - 1][\"m\"]).add(step * i, \"months\").format(\"YYYY-MM-DD\");\r\n }\r\n\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n else if(!judgeDate[0] && judgeDate[2]){\r\n //日不一样,且日差为等差数列\r\n if(Math.abs(dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]))) > 7){\r\n //若日差大于7天,以一月为step(若那天是休息日,则向前取最近的工作日)\r\n let step_month\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_month = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_month = -1;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_month * num, \"months\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let day = dayjs(d[\"m\"]).add(step, \"days\").day(),\r\n date;\r\n if(day == 0){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(2, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else if(day == 6){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(1, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else{\r\n date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n else{\r\n //若日差小于等于7天,以7天为step(若那天是休息日,则向前取最近的工作日)\r\n let step_day;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_day = 7;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_day = -7;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_day * num, \"days\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let day = dayjs(d[\"m\"]).add(step, \"days\").day(),\r\n date;\r\n if(day == 0){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(2, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else if(day == 6){\r\n date = dayjs(d[\"m\"]).add(step, \"days\").subtract(1, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n else{\r\n date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n }\r\n\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n }\r\n else{\r\n //日差不是等差数列,复制数据\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(type == \"6\"){ //以月填充\r\n if(data.length == 1){\r\n //以一月为step\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillMonths(data, len, step);\r\n }\r\n else if(data.length == 2){\r\n if(dayjs(data[1][\"m\"]).date() == dayjs(data[0][\"m\"]).date() && dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\") != 0){\r\n //日一样,且月差大于一月,以月差为step\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\");\r\n applyData = _this.FillMonths(data, len, step);\r\n }\r\n else{\r\n //以一月为step\r\n let step_month;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_month = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_month = -1;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_month * num, \"months\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n }\r\n else{\r\n let judgeDate = _this.judgeDate(data);\r\n if(judgeDate[0] && judgeDate[3]){\r\n //日一样,且月差为等差数列,以月差为step\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\");\r\n applyData = _this.FillMonths(data, len, step);\r\n }\r\n else if(!judgeDate[0] && judgeDate[2]){\r\n //日不一样,且日差为等差数列,以一月为step\r\n let step_month;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_month = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_month = -1;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_month * num, \"months\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n else{\r\n //日差不是等差数列,复制数据\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(type == \"7\"){ //以年填充\r\n if(data.length == 1){\r\n //以一年为step\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillYears(data, len, step);\r\n }\r\n else if(data.length == 2){\r\n if(dayjs(data[1][\"m\"]).date() == dayjs(data[0][\"m\"]).date() && dayjs(data[1][\"m\"]).month() == dayjs(data[0][\"m\"]).month() && dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"years\") != 0){\r\n //日月一样,且年差大于一年,以年差为step\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"years\");\r\n applyData = _this.FillYears(data, len, step);\r\n }\r\n else{\r\n //以一年为step\r\n let step_year;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_year = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_year = -1;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_year * num, \"years\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n }\r\n else{\r\n let judgeDate = _this.judgeDate(data);\r\n if(judgeDate[0] && judgeDate[1] && judgeDate[4]){\r\n //日月一样,且年差为等差数列,以年差为step\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n let step = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"years\");\r\n applyData = _this.FillYears(data, len, step);\r\n }\r\n else if((judgeDate[0] && judgeDate[3]) || judgeDate[2]){\r\n //日一样且月差为等差数列,或天差为等差数列,以一年为step\r\n let step_year;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step_year = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step_year = -1;\r\n data.reverse();\r\n }\r\n\r\n let step; //以数组第一个为对比\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = Math.ceil(i / data.length);\r\n if(index == 0){\r\n step = dayjs(d[\"m\"]).add(step_year * num, \"years\").diff(dayjs(d[\"m\"]), \"days\");\r\n }\r\n\r\n let date = dayjs(d[\"m\"]).add(step, \"days\").format(\"YYYY-MM-DD\");\r\n d[\"m\"] = date;\r\n d[\"v\"] = genarate(date)[2];\r\n applyData.push(d);\r\n }\r\n }\r\n else{\r\n //日差不是等差数列,复制数据\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n }\r\n\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n else if(type == \"8\"){ //以中文小写数字序列填充\r\n if(data.length == 1){\r\n let step;\r\n if(direction == \"down\" || direction == \"right\"){\r\n step = 1;\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n step = -1;\r\n }\r\n\r\n applyData = _this.FillChnNumber(data, len, step);\r\n }\r\n else{\r\n let dataNumArr = [];\r\n for(let i = 0; i < data.length; i++){\r\n dataNumArr.push(_this.ChineseToNumber(data[i][\"m\"]));\r\n }\r\n\r\n if(direction == \"up\" || direction == \"left\"){\r\n data.reverse();\r\n dataNumArr.reverse();\r\n }\r\n\r\n if(_this.isEqualDiff(dataNumArr)){\r\n let step = dataNumArr[1] - dataNumArr[0];\r\n applyData = _this.FillChnNumber(data, len, step);\r\n }\r\n else{\r\n //不是等差数列,复制数据\r\n applyData = _this.FillCopy(data, len);\r\n }\r\n }\r\n }\r\n\r\n return applyData;\r\n },\r\n FillCopy: function(data, len){\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillSeries: function(data, len, direction){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n\r\n let dataNumArr = [];\r\n for(let j = 0; j < data.length; j++){\r\n dataNumArr.push(Number(data[j][\"v\"]));\r\n }\r\n\r\n if(data.length > 2 && _this.isEqualRatio(dataNumArr)){\r\n //等比数列\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num;\r\n if(direction == \"down\" || direction == \"right\"){\r\n num = Number(data[data.length -1][\"v\"]) * Math.pow(Number(data[1][\"v\"]) / Number(data[0][\"v\"]), i);\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n num = Number(data[0][\"v\"]) / Math.pow(Number(data[1][\"v\"]) / Number(data[0][\"v\"]), i);\r\n }\r\n\r\n d[\"v\"] = num;\r\n d[\"m\"] = update(d[\"ct\"][\"fa\"], num);\r\n applyData.push(d);\r\n }\r\n }\r\n else{\r\n //线性数列\r\n let xArr = _this.getXArr(data.length);\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let y;\r\n if(direction == \"down\" || direction == \"right\"){\r\n y = _this.forecast(data.length + i, dataNumArr, xArr);\r\n }\r\n else if(direction == \"up\" || direction == \"left\"){\r\n y = _this.forecast(1 - i, dataNumArr, xArr);\r\n }\r\n\r\n d[\"v\"] = y;\r\n d[\"m\"] = update(d[\"ct\"][\"fa\"], y);\r\n applyData.push(d);\r\n }\r\n }\r\n\r\n return applyData;\r\n },\r\n FillExtendNumber: function(data, len, step){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n let reg = /0|([1-9]+[0-9]*)/g;\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let last = data[data.length - 1][\"m\"];\r\n let match = last.match(reg)\r\n let lastTxt = match[match.length -1];\r\n \r\n let num = Math.abs(Number(lastTxt) + step * i);\r\n let lastIndex = last.lastIndexOf(lastTxt);\r\n let valueTxt = last.substr(0, lastIndex) + num.toString() + last.substr(lastIndex + lastTxt.length);\r\n\r\n d[\"v\"] = valueTxt;\r\n d[\"m\"] = valueTxt;\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillOnlyFormat: function(data, len){\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n delete d[\"f\"];\r\n delete d[\"m\"];\r\n delete d[\"v\"];\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillWithoutFormat: function(dataArr){\r\n let applyData = [];\r\n\r\n for(let i = 0; i < dataArr.length; i++){\r\n let d = $.extend(true, {}, dataArr[i]);\r\n\r\n let obj;\r\n if(d[\"f\"] == null){\r\n obj = {\"m\": d[\"v\"].toString(), \"v\": d[\"v\"]};\r\n }\r\n else{\r\n obj = {\"f\": d[\"f\"], \"m\": d[\"v\"].toString(), \"v\": d[\"v\"]};\r\n }\r\n\r\n applyData.push(obj);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillDays: function(data, len, step){\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let date = update(\"yyyy-MM-dd\", d[\"v\"]);\r\n date = dayjs(date).add(step * i, \"days\").format(\"YYYY-MM-DD\");\r\n\r\n d[\"v\"] = genarate(date)[2];\r\n d[\"m\"] = update(d[\"ct\"][\"fa\"], d[\"v\"]);\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillMonths: function(data, len, step){\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let date = update(\"yyyy-MM-dd\", d[\"v\"]);\r\n date = dayjs(date).add(step * i, \"months\").format(\"YYYY-MM-DD\");\r\n\r\n d[\"v\"] = genarate(date)[2];\r\n d[\"m\"] = update(d[\"ct\"][\"fa\"], d[\"v\"]);\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillYears: function(data, len, step){\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let date = update(\"yyyy-MM-dd\", d[\"v\"]);\r\n date = dayjs(date).add(step * i, \"years\").format(\"YYYY-MM-DD\");\r\n\r\n d[\"v\"] = genarate(date)[2];\r\n d[\"m\"] = update(d[\"ct\"][\"fa\"], d[\"v\"]);\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillChnWeek: function(data, len, step){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num;\r\n if(data[data.length - 1][\"m\"] == \"日\"){\r\n num = 7 + step * i;\r\n }\r\n else{\r\n num = _this.ChineseToNumber(data[data.length - 1][\"m\"]) + step * i;\r\n }\r\n\r\n if(num < 0){\r\n num = Math.ceil(Math.abs(num) / 7) * 7 + num;\r\n }\r\n\r\n let rsd = num % 7;\r\n if(rsd == 0){\r\n d[\"m\"] = \"日\";\r\n d[\"v\"] = \"日\";\r\n }\r\n else if(rsd == 1){\r\n d[\"m\"] = \"一\";\r\n d[\"v\"] = \"一\";\r\n }\r\n else if(rsd == 2){\r\n d[\"m\"] = \"二\";\r\n d[\"v\"] = \"二\";\r\n }\r\n else if(rsd == 3){\r\n d[\"m\"] = \"三\";\r\n d[\"v\"] = \"三\";\r\n }\r\n else if(rsd == 4){\r\n d[\"m\"] = \"四\";\r\n d[\"v\"] = \"四\";\r\n }\r\n else if(rsd == 5){\r\n d[\"m\"] = \"五\";\r\n d[\"v\"] = \"五\";\r\n }\r\n else if(rsd == 6){\r\n d[\"m\"] = \"六\";\r\n d[\"v\"] = \"六\";\r\n }\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillChnWeek2: function(data, len, step){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num;\r\n if(data[data.length - 1][\"m\"] == \"周日\"){\r\n num = 7 + step * i;\r\n }\r\n else{\r\n let last = data[data.length - 1][\"m\"];\r\n let txt = last.substr(last.length - 1, 1);\r\n num = _this.ChineseToNumber(txt) + step * i;\r\n }\r\n\r\n if(num < 0){\r\n num = Math.ceil(Math.abs(num) / 7) * 7 + num;\r\n }\r\n\r\n let rsd = num % 7;\r\n if(rsd == 0){\r\n d[\"m\"] = \"周日\";\r\n d[\"v\"] = \"周日\";\r\n }\r\n else if(rsd == 1){\r\n d[\"m\"] = \"周一\";\r\n d[\"v\"] = \"周一\";\r\n }\r\n else if(rsd == 2){\r\n d[\"m\"] = \"周二\";\r\n d[\"v\"] = \"周二\";\r\n }\r\n else if(rsd == 3){\r\n d[\"m\"] = \"周三\";\r\n d[\"v\"] = \"周三\";\r\n }\r\n else if(rsd == 4){\r\n d[\"m\"] = \"周四\";\r\n d[\"v\"] = \"周四\";\r\n }\r\n else if(rsd == 5){\r\n d[\"m\"] = \"周五\";\r\n d[\"v\"] = \"周五\";\r\n }\r\n else if(rsd == 6){\r\n d[\"m\"] = \"周六\";\r\n d[\"v\"] = \"周六\";\r\n }\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillChnWeek3: function(data, len, step){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num;\r\n if(data[data.length - 1][\"m\"] == \"星期日\"){\r\n num = 7 + step * i;\r\n }\r\n else{\r\n let last = data[data.length - 1][\"m\"];\r\n let txt = last.substr(last.length - 1, 1);\r\n num = _this.ChineseToNumber(txt) + step * i;\r\n }\r\n\r\n if(num < 0){\r\n num = Math.ceil(Math.abs(num) / 7) * 7 + num;\r\n }\r\n\r\n let rsd = num % 7;\r\n if(rsd == 0){\r\n d[\"m\"] = \"星期日\";\r\n d[\"v\"] = \"星期日\";\r\n }\r\n else if(rsd == 1){\r\n d[\"m\"] = \"星期一\";\r\n d[\"v\"] = \"星期一\";\r\n }\r\n else if(rsd == 2){\r\n d[\"m\"] = \"星期二\";\r\n d[\"v\"] = \"星期二\";\r\n }\r\n else if(rsd == 3){\r\n d[\"m\"] = \"星期三\";\r\n d[\"v\"] = \"星期三\";\r\n }\r\n else if(rsd == 4){\r\n d[\"m\"] = \"星期四\";\r\n d[\"v\"] = \"星期四\";\r\n }\r\n else if(rsd == 5){\r\n d[\"m\"] = \"星期五\";\r\n d[\"v\"] = \"星期五\";\r\n }\r\n else if(rsd == 6){\r\n d[\"m\"] = \"星期六\";\r\n d[\"v\"] = \"星期六\";\r\n }\r\n\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n FillChnNumber: function(data, len, step){\r\n let _this = this;\r\n\r\n let applyData = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n let index = (i - 1) % data.length;\r\n let d = $.extend(true, {}, data[index]);\r\n\r\n let num = _this.ChineseToNumber(data[data.length - 1][\"m\"]) + step * i,\r\n txt;\r\n if(num <= 0){\r\n txt = \"零\";\r\n }\r\n else{\r\n txt = _this.NumberToChinese(num);\r\n }\r\n\r\n d[\"v\"] = txt;\r\n d[\"m\"] = txt.toString();\r\n applyData.push(d);\r\n }\r\n\r\n return applyData;\r\n },\r\n isEqualDiff: function(arr){\r\n let diff = true;\r\n let step = arr[1] - arr[0];\r\n\r\n for(let i = 1; i < arr.length; i++){\r\n if(arr[i] - arr[i - 1] != step){\r\n diff = false;\r\n break;\r\n }\r\n }\r\n\r\n return diff;\r\n },\r\n isEqualRatio: function(arr){\r\n let ratio = true;\r\n let step = arr[1] / arr[0];\r\n\r\n for(let i = 1; i < arr.length; i++){\r\n if(arr[i] / arr[i - 1] != step){\r\n ratio = false;\r\n break;\r\n }\r\n }\r\n\r\n return ratio;\r\n },\r\n getXArr: function(len){\r\n let xArr = [];\r\n\r\n for(let i = 1; i <= len; i++){\r\n xArr.push(i);\r\n }\r\n\r\n return xArr;\r\n },\r\n forecast: function(x, yArr, xArr){\r\n function getAverage(arr){\r\n let sum = 0;\r\n\r\n for(let i = 0; i < arr.length; i++){\r\n sum += arr[i];\r\n }\r\n\r\n return sum / arr.length;\r\n }\r\n\r\n let ax = getAverage(xArr); //x数组 平均值\r\n let ay = getAverage(yArr); //y数组 平均值\r\n\r\n let sum_d = 0, sum_n = 0;\r\n for(let j = 0; j < xArr.length; j++){\r\n //分母和\r\n sum_d += (xArr[j] - ax)*(yArr[j] - ay);\r\n //分子和\r\n sum_n += (xArr[j] - ax)*(xArr[j] - ax);\r\n }\r\n\r\n let b;\r\n if(sum_n == 0){\r\n b = 1;\r\n }\r\n else{\r\n b = sum_d / sum_n;\r\n }\r\n\r\n let a = ay - b * ax;\r\n\r\n return Math.round((a + b * x) * 100000) / 100000;\r\n },\r\n judgeDate: function(data){\r\n let isSameDay = true,\r\n isSameMonth = true,\r\n isEqualDiffDays = true,\r\n isEqualDiffMonths = true,\r\n isEqualDiffYears = true;\r\n let sameDay = dayjs(data[0][\"m\"]).date(),\r\n sameMonth = dayjs(data[0][\"m\"]).month();\r\n let equalDiffDays = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"days\");\r\n let equalDiffMonths = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"months\");\r\n let equalDiffYears = dayjs(data[1][\"m\"]).diff(dayjs(data[0][\"m\"]), \"years\");\r\n\r\n for(let i = 1; i < data.length; i++){\r\n //日是否一样\r\n if(dayjs(data[i][\"m\"]).date() != sameDay){\r\n isSameDay = false;\r\n }\r\n //月是否一样\r\n if(dayjs(data[i][\"m\"]).month() != sameMonth){\r\n isSameMonth = false;\r\n }\r\n //日差是否是 等差数列\r\n if(dayjs(data[i][\"m\"]).diff(dayjs(data[i - 1][\"m\"]), \"days\") != equalDiffDays){\r\n isEqualDiffDays = false;\r\n }\r\n //月差是否是 等差数列\r\n if(dayjs(data[i][\"m\"]).diff(dayjs(data[i - 1][\"m\"]), \"months\") != equalDiffMonths){\r\n isEqualDiffMonths = false;\r\n }\r\n //年差是否是 等差数列\r\n if(dayjs(data[i][\"m\"]).diff(dayjs(data[i - 1][\"m\"]), \"years\") != equalDiffYears){\r\n isEqualDiffYears = false;\r\n }\r\n }\r\n\r\n if(equalDiffDays == 0){\r\n isEqualDiffDays = false;\r\n }\r\n if(equalDiffMonths == 0){\r\n isEqualDiffMonths = false;\r\n }\r\n if(equalDiffYears == 0){\r\n isEqualDiffYears = false;\r\n }\r\n\r\n return [isSameDay, isSameMonth, isEqualDiffDays, isEqualDiffMonths, isEqualDiffYears];\r\n }\r\n}\r\n\r\nexport default luckysheetDropCell;\r\n","import { getSheetIndex } from '../methods/get';\r\nimport { luckysheet_searcharray } from './sheetSearch';\r\nimport { selectHightlightShow } from './select';\r\nimport { createFilterOptions } from './filter';\r\nimport server from './server';\r\nimport menuButton from './menuButton';\r\nimport luckysheetPostil from './postil';\r\nimport luckysheetDropCell from './dropCell';\r\nimport { rowLocationByIndex, colLocationByIndex } from '../global/location';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\nconst luckysheetFreezen = {\r\n freezenHorizontalHTML: '
 
',\r\n freezenVerticalHTML: '
 
',\r\n initialHorizontal: true,\r\n initialVertical: true,\r\n horizontalmovestate: false,\r\n horizontalmoveposition: null,\r\n verticalmovestate: false,\r\n verticalmoveposition: null,\r\n windowHeight: null,\r\n windowWidth: null,\r\n freezenhorizontaldata: null,\r\n freezenverticaldata: null,\r\n cutVolumn: function (arr, cutindex) {\r\n if(cutindex <= 0){\r\n return arr;\r\n }\r\n\r\n let pre = arr.slice(0, cutindex);\r\n let premax = pre[pre.length - 1];\r\n let ret = arr.slice(cutindex);\r\n \r\n // for (let i = 0; i < ret.length; i++) {\r\n // ret[i] -= premax;\r\n // }\r\n\r\n return ret;\r\n },\r\n cancelFreezenVertical: function (sheetIndex) {\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_freezen = _locale.freezen;\r\n\r\n $(\"#luckysheet-freezen-btn-vertical\").html(' '+locale_freezen.freezenColumn);\r\n _this.freezenverticaldata = null;\r\n let isvertical = $(\"#luckysheet-freezebar-vertical\").is(\":visible\");\r\n $(\"#luckysheet-freezebar-vertical\").hide();\r\n\r\n if (sheetIndex == null) {\r\n sheetIndex = Store.currentSheetIndex;\r\n }\r\n\r\n let currentSheet = Store.luckysheetfile[getSheetIndex(sheetIndex)];\r\n if (currentSheet.freezen != null) {\r\n currentSheet.freezen.vertical = null;\r\n }\r\n\r\n if(currentSheet.frozen != null && isvertical){\r\n server.saveParam(\"all\", sheetIndex, currentSheet.frozen, { \"k\": \"frozen\" });\r\n }\r\n },\r\n createFreezenVertical: function (freezenverticaldata, left) {\r\n let _this = this;\r\n\r\n if (_this.initialVertical) {\r\n _this.initialVertical = false;\r\n $(\"#luckysheet-grid-window-1\").append(_this.freezenVerticalHTML);\r\n\r\n $(\"#luckysheet-freezebar-vertical\").find(\".luckysheet-freezebar-vertical-drop\").hover(function () {\r\n $(this).parent().addClass(\"luckysheet-freezebar-hover\");\r\n }, function () {\r\n $(this).parent().removeClass(\"luckysheet-freezebar-hover\");\r\n });\r\n\r\n\r\n $(\"#luckysheet-freezebar-vertical\").find(\".luckysheet-freezebar-vertical-drop\").mousedown(function () {\r\n _this.verticalmovestate = true;\r\n _this.verticalmoveposition = $(this).position().left;\r\n _this.windowWidth = $(\"#luckysheet-grid-window-1\").width();\r\n\r\n $(this).parent().addClass(\"luckysheet-freezebar-active\");\r\n $(\"#luckysheet-freezebar-vertical\").find(\".luckysheet-freezebar-vertical-handle\").css(\"cursor\", \"-webkit-grabbing\");\r\n });\r\n\r\n let gridheight = $(\"#luckysheet-grid-window-1\").height();\r\n $(\"#luckysheet-freezebar-vertical\").find(\".luckysheet-freezebar-vertical-handle\").css({ \r\n \"height\": gridheight - 10, \r\n \"width\": \"4px\", \r\n \"cursor\": \"-webkit-grab\", \r\n \"top\": \"0px\" \r\n }).end().find(\".luckysheet-freezebar-vertical-drop\").css({ \r\n \"height\": gridheight - 10, \r\n \"width\": \"4px\", \r\n \"top\": \"0px\", \r\n \"cursor\": \"-webkit-grab\" \r\n });\r\n }\r\n\r\n if (freezenverticaldata == null) {\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let dataset_col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n if (dataset_col_st == -1) {\r\n dataset_col_st = 0;\r\n }\r\n\r\n left = Store.visibledatacolumn[dataset_col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n freezenverticaldata = [\r\n Store.visibledatacolumn[dataset_col_st], \r\n dataset_col_st + 1, \r\n scrollLeft, \r\n _this.cutVolumn(Store.visibledatacolumn, dataset_col_st + 1), \r\n left\r\n ];\r\n _this.saveFreezen(null, null, freezenverticaldata, left);\r\n }\r\n\r\n _this.freezenverticaldata = freezenverticaldata;\r\n\r\n // $(\"#luckysheet-freezen-btn-horizontal\").html(' '+locale().freezen.freezenCancel);\r\n\r\n // 解决freeze 不垂直居中的问题\r\n const freezeHTML = `\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${locale().freezen.freezenCancel}\r\n
\r\n
\r\n
\r\n `\r\n $(\"#luckysheet-freezen-btn-horizontal\").html(freezeHTML);\r\n\r\n $(\"#luckysheet-freezebar-vertical\").show().find(\".luckysheet-freezebar-vertical-handle\").css({ \"left\": left }).end().find(\".luckysheet-freezebar-vertical-drop\").css({ \"left\": left });\r\n },\r\n saveFreezen: function (freezenhorizontaldata, top, freezenverticaldata, left) {\r\n let currentSheet = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n if (currentSheet.freezen == null) {\r\n currentSheet.freezen = {};\r\n }\r\n\r\n if (freezenhorizontaldata != null) {\r\n if (currentSheet.freezen.horizontal == null) {\r\n currentSheet.freezen.horizontal = {};\r\n }\r\n\r\n currentSheet.freezen.horizontal.freezenhorizontaldata = freezenhorizontaldata;\r\n currentSheet.freezen.horizontal.top = top;\r\n }\r\n\r\n if (freezenverticaldata != null) {\r\n if (currentSheet.freezen.vertical == null) {\r\n currentSheet.freezen.vertical = {};\r\n }\r\n\r\n currentSheet.freezen.vertical.freezenverticaldata = freezenverticaldata;\r\n currentSheet.freezen.vertical.left = left;\r\n }\r\n\r\n // if(currentSheet.freezen != null){\r\n // server.saveParam(\"all\", Store.currentSheetIndex, currentSheet.freezen, { \"k\": \"freezen\" });\r\n // }\r\n\r\n // use new property frozen\r\n if(currentSheet.frozen != null){\r\n server.saveParam(\"all\", Store.currentSheetIndex, currentSheet.frozen, { \"k\": \"frozen\" });\r\n }\r\n },\r\n initialFreezen: function (sheetIndex) {\r\n let _this = this;\r\n\r\n // when init ,we get frozen, but here, we need freezen,so tranform it\r\n _this.frozenTofreezen();\r\n\r\n let currentSheet = Store.luckysheetfile[getSheetIndex(sheetIndex)];\r\n if (currentSheet.freezen != null && currentSheet.freezen.horizontal != null && currentSheet.freezen.horizontal.freezenhorizontaldata != null) {\r\n _this.createFreezenHorizontal(currentSheet.freezen.horizontal.freezenhorizontaldata, currentSheet.freezen.horizontal.top);\r\n }\r\n else {\r\n _this.cancelFreezenHorizontal(sheetIndex);\r\n }\r\n\r\n if (currentSheet.freezen != null && currentSheet.freezen.vertical != null && currentSheet.freezen.vertical.freezenverticaldata != null) {\r\n _this.createFreezenVertical(currentSheet.freezen.vertical.freezenverticaldata, currentSheet.freezen.vertical.left);\r\n }\r\n else {\r\n _this.cancelFreezenVertical(sheetIndex);\r\n }\r\n\r\n _this.createAssistCanvas();\r\n },\r\n changeFreezenIndex: function (originindex, type) {\r\n let _this = this;\r\n\r\n if (type == \"v\" && _this.freezenverticaldata != null) {\r\n let freezen_colindex = _this.freezenverticaldata[1];\r\n let offset = luckysheet_searcharray(Store.visibledatacolumn, $(\"#luckysheet-cell-main\").scrollLeft());\r\n\r\n if (originindex - offset < freezen_colindex) {\r\n originindex = originindex - offset;\r\n }\r\n }\r\n else if (type == \"h\" && _this.freezenhorizontaldata != null) {\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n let offset = luckysheet_searcharray(Store.visibledatarow, $(\"#luckysheet-cell-main\").scrollTop());\r\n \r\n if (originindex - offset < freezen_rowindex) {\r\n originindex = originindex - offset;\r\n }\r\n }\r\n \r\n return originindex;\r\n },\r\n scrollFreezen: function () {\r\n let _this = this;\r\n\r\n let row;\r\n let row_focus = Store.luckysheet_select_save[0][\"row_focus\"];\r\n if(row_focus == Store.luckysheet_select_save[0][\"row\"][0]){\r\n row = Store.luckysheet_select_save[0][\"row\"][1];\r\n }\r\n else if(row_focus == Store.luckysheet_select_save[0][\"row\"][1]){\r\n row = Store.luckysheet_select_save[0][\"row\"][0];\r\n }\r\n\r\n let column;\r\n let column_focus = Store.luckysheet_select_save[0][\"column_focus\"];\r\n if(column_focus == Store.luckysheet_select_save[0][\"column\"][0]){\r\n column = Store.luckysheet_select_save[0][\"column\"][1];\r\n }\r\n else if(column_focus == Store.luckysheet_select_save[0][\"column\"][1]){\r\n column = Store.luckysheet_select_save[0][\"column\"][0];\r\n }\r\n\r\n if (_this.freezenverticaldata != null) {\r\n let freezen_colindex = _this.freezenverticaldata[1]; \r\n\r\n let offset = luckysheet_searcharray(_this.freezenverticaldata[3], $(\"#luckysheet-cell-main\").scrollLeft());\r\n\r\n let top = _this.freezenverticaldata[4];\r\n\r\n freezen_colindex += offset;\r\n\r\n if(column>=Store.visibledatacolumn.length){\r\n column = Store.visibledatacolumn.length - 1;\r\n }\r\n\r\n if(freezen_colindex>=Store.visibledatacolumn.length){\r\n freezen_colindex = Store.visibledatacolumn.length - 1;\r\n }\r\n \r\n let column_px = Store.visibledatacolumn[column], freezen_px = Store.visibledatacolumn[freezen_colindex];\r\n\r\n if (column_px <= freezen_px+top) {\r\n console.log(1111);\r\n setTimeout(function () { $(\"#luckysheet-scrollbar-x\").scrollLeft(0); }, 100);\r\n }\r\n }\r\n\r\n if (_this.freezenhorizontaldata != null) {\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n \r\n let offset = luckysheet_searcharray(_this.freezenhorizontaldata[3], $(\"#luckysheet-cell-main\").scrollTop());\r\n\r\n let left = _this.freezenhorizontaldata[4];\r\n\r\n freezen_rowindex += offset;\r\n\r\n if(row>=Store.visibledatarow.length){\r\n row = Store.visibledatarow.length - 1;\r\n }\r\n\r\n if(freezen_rowindex>=Store.visibledatarow.length){\r\n freezen_rowindex = Store.visibledatarow.length - 1;\r\n }\r\n\r\n let row_px = Store.visibledatarow[row], freezen_px = Store.visibledatarow[freezen_rowindex];\r\n\r\n if (row_px <= freezen_px+left) {\r\n setTimeout(function () {$(\"#luckysheet-scrollbar-y\").scrollTop(0);}, 100);\r\n }\r\n }\r\n },\r\n cancelFreezenHorizontal: function (sheetIndex) {\r\n let _this = this;\r\n\r\n // $(\"#luckysheet-freezen-btn-horizontal\").html(' '+locale().freezen.default);\r\n\r\n // 解决freeze 不垂直居中的问题\r\n const freezeHTML = `\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${locale().freezen.default}\r\n
\r\n
\r\n
\r\n `\r\n\r\n $(\"#luckysheet-freezen-btn-horizontal\").html(freezeHTML);\r\n\r\n _this.freezenhorizontaldata = null;\r\n let ishorizontal = $(\"#luckysheet-freezebar-horizontal\").is(\":visible\");\r\n $(\"#luckysheet-freezebar-horizontal\").hide();\r\n\r\n if (sheetIndex == null) {\r\n sheetIndex = Store.currentSheetIndex;\r\n }\r\n\r\n let currentSheet = Store.luckysheetfile[getSheetIndex(sheetIndex)];\r\n if (currentSheet.freezen != null) {\r\n currentSheet.freezen.horizontal = null;\r\n }\r\n\r\n if(currentSheet.frozen != null && ishorizontal){\r\n server.saveParam(\"all\", sheetIndex, currentSheet.frozen, { \"k\": \"frozen\" });\r\n }\r\n },\r\n createFreezenHorizontal: function (freezenhorizontaldata, top) {\r\n let _this = this;\r\n\r\n if (_this.initialHorizontal) {\r\n _this.initialHorizontal = false;\r\n $(\"#luckysheet-grid-window-1\").append(_this.freezenHorizontalHTML);\r\n\r\n $(\"#luckysheet-freezebar-horizontal\").find(\".luckysheet-freezebar-horizontal-drop\").hover(function () {\r\n $(this).parent().addClass(\"luckysheet-freezebar-hover\");\r\n }, function () {\r\n $(this).parent().removeClass(\"luckysheet-freezebar-hover\");\r\n });\r\n\r\n $(\"#luckysheet-freezebar-horizontal\").find(\".luckysheet-freezebar-horizontal-drop\").mousedown(function () {\r\n _this.horizontalmovestate = true;\r\n _this.horizontalmoveposition = $(this).position().top;\r\n _this.windowHeight = $(\"#luckysheet-grid-window-1\").height();\r\n\r\n $(this).parent().addClass(\"luckysheet-freezebar-active\");\r\n $(\"#luckysheet-freezebar-horizontal\").find(\".luckysheet-freezebar-horizontal-handle\").css(\"cursor\", \"-webkit-grabbing\");\r\n });\r\n\r\n let gridwidth = $(\"#luckysheet-grid-window-1\").width();\r\n $(\"#luckysheet-freezebar-horizontal\").find(\".luckysheet-freezebar-horizontal-handle\").css({ \r\n \"width\": gridwidth - 10, \r\n \"height\": \"4px\", \r\n \"cursor\": \"-webkit-grab\", \r\n \"left\": \"0px\" \r\n }).end().find(\".luckysheet-freezebar-horizontal-drop\").css({ \r\n \"width\": gridwidth - 10, \r\n \"height\": \"4px\", \r\n \"left\": \"0px\", \r\n \"cursor\": \"-webkit-grab\" \r\n });\r\n }\r\n\r\n if (freezenhorizontaldata == null) {\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let dataset_row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n if (dataset_row_st == -1) {\r\n dataset_row_st = 0;\r\n }\r\n\r\n top = Store.visibledatarow[dataset_row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n freezenhorizontaldata = [\r\n Store.visibledatarow[dataset_row_st], \r\n dataset_row_st + 1, \r\n scrollTop, \r\n _this.cutVolumn(Store.visibledatarow, dataset_row_st + 1), \r\n top\r\n ];\r\n _this.saveFreezen(freezenhorizontaldata, top, null, null);\r\n }\r\n\r\n _this.freezenhorizontaldata = freezenhorizontaldata;\r\n\r\n // $(\"#luckysheet-freezen-btn-horizontal\").html(' '+locale().freezen.freezenCancel);\r\n\r\n // $(\"#luckysheet-freezen-btn-horizontal\").html(' '+locale().freezen.freezenCancel);\r\n\r\n const freezeHTML = `\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${locale().freezen.freezenCancel}\r\n
\r\n
\r\n
\r\n `\r\n\r\n $(\"#luckysheet-freezen-btn-horizontal\").html(freezeHTML);\r\n\r\n $(\"#luckysheet-freezebar-horizontal\").show().find(\".luckysheet-freezebar-horizontal-handle\").css({ \"top\": top }).end().find(\".luckysheet-freezebar-horizontal-drop\").css({ \"top\": top });\r\n },\r\n createAssistCanvas: function(){\r\n let _this = this;\r\n _this.removeAssistCanvas();\r\n\r\n if (_this.freezenverticaldata != null || _this.freezenhorizontaldata != null) {\r\n let freezen_horizon_px, freezen_horizon_ed, freezen_horizon_scrollTop;\r\n let freezen_vertical_px, freezen_vertical_ed, freezen_vertical_scrollTop;\r\n let drawWidth = Store.luckysheetTableContentHW[0], \r\n drawHeight = Store.luckysheetTableContentHW[1];\r\n\r\n //双向freezen\r\n if (_this.freezenverticaldata != null && _this.freezenhorizontaldata != null) {\r\n freezen_horizon_px = _this.freezenhorizontaldata[0];\r\n freezen_horizon_ed = _this.freezenhorizontaldata[1];\r\n freezen_horizon_scrollTop = _this.freezenhorizontaldata[2];\r\n\r\n freezen_vertical_px = _this.freezenverticaldata[0];\r\n freezen_vertical_ed = _this.freezenverticaldata[1];\r\n freezen_vertical_scrollTop = _this.freezenverticaldata[2];\r\n\r\n //3\r\n _this.createCanvas(\"freezen_3\", freezen_vertical_px - freezen_vertical_scrollTop, freezen_horizon_px - freezen_horizon_scrollTop + 1, Store.rowHeaderWidth - 1, Store.columnHeaderHeight - 1);\r\n //4\r\n _this.createCanvas(\"freezen_4\", drawWidth - freezen_vertical_px + freezen_vertical_scrollTop, freezen_horizon_px - freezen_horizon_scrollTop + 1, freezen_vertical_px - freezen_vertical_scrollTop + Store.rowHeaderWidth - 1, Store.columnHeaderHeight - 1);\r\n //7\r\n _this.createCanvas(\"freezen_7\", freezen_vertical_px - freezen_vertical_scrollTop, drawHeight - freezen_horizon_px + freezen_horizon_scrollTop - Store.columnHeaderHeight, Store.rowHeaderWidth - 1, freezen_horizon_px - freezen_horizon_scrollTop + Store.columnHeaderHeight - 1);\r\n }\r\n //水平freezen\r\n else if (_this.freezenhorizontaldata != null) {\r\n freezen_horizon_px = _this.freezenhorizontaldata[0];\r\n freezen_horizon_ed = _this.freezenhorizontaldata[1];\r\n freezen_horizon_scrollTop = _this.freezenhorizontaldata[2];\r\n\r\n _this.createCanvas(\"freezen_h\", drawWidth, freezen_horizon_px - freezen_horizon_scrollTop + 1, Store.rowHeaderWidth - 1, Store.columnHeaderHeight - 1);\r\n }\r\n //垂直freezen\r\n else if (_this.freezenverticaldata != null) {\r\n freezen_vertical_px = _this.freezenverticaldata[0];\r\n freezen_vertical_ed = _this.freezenverticaldata[1];\r\n freezen_vertical_scrollTop = _this.freezenverticaldata[2];\r\n\r\n _this.createCanvas(\"freezen_v\", freezen_vertical_px - freezen_vertical_scrollTop, drawHeight, Store.rowHeaderWidth - 1, Store.columnHeaderHeight - 1);\r\n }\r\n\r\n _this.scrollAdapt();\r\n }\r\n },\r\n createCanvas: function(id, width, height, left, top){\r\n let c = $(\"\").appendTo(\"#luckysheet-grid-window-1\").attr({\r\n \"id\": id, \r\n \"width\": Math.ceil(width * Store.devicePixelRatio), \r\n \"height\": Math.ceil(height * Store.devicePixelRatio)\r\n }).css({\r\n \"user-select\": \"none\",\r\n \"postion\": \"absolute\",\r\n \"left\": left, \r\n \"top\": top,\r\n \"width\": width, \r\n \"height\": height, \r\n \"z-index\": 10, \r\n \"pointer-events\": \"none\"\r\n });\r\n },\r\n removeAssistCanvas: function(){\r\n $(\"#luckysheet-grid-window-1 > canvas\").not($(\"#luckysheetTableContent\")).remove();\r\n $(\"#luckysheet-cell-selected\").css(\"z-index\", 15);\r\n },\r\n scrollAdapt: function(){\r\n let _this = this;\r\n\r\n //有冻结时 选区框 滚动适应\r\n if(Store.luckysheet_select_save != null && Store.luckysheet_select_save.length > 0){\r\n _this.scrollAdaptOfselect(); \r\n }\r\n\r\n //有冻结时 图表框 滚动适应\r\n if($(\"#luckysheet-cell-main .luckysheet-data-visualization-chart\").length > 0){\r\n\r\n // 当前sheet有图表才需要滚动适应\r\n const chart = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"chart\"];\r\n \r\n if(chart != null && chart.length > 0){\r\n _this.scrollAdaptOfchart();\r\n }\r\n }\r\n\r\n //有冻结时 批注框 滚动适应\r\n if($(\"#luckysheet-postil-showBoxs .luckysheet-postil-show\").length > 0){\r\n _this.scrollAdaptOfpostil(); \r\n }\r\n\r\n //有冻结时 下拉选区图标 滚动适应\r\n if($(\"#luckysheet-dropCell-icon\").length > 0){\r\n _this.scrollAdaptOfdpicon();\r\n }\r\n\r\n //有冻结时 筛选下拉按钮 滚动适应\r\n if($(\"#luckysheet-filter-options-sheet\"+ Store.currentSheetIndex +\" .luckysheet-filter-options\").length > 0){\r\n _this.scrollAdaptOffilteroptions();\r\n }\r\n },\r\n scrollAdaptOfselect: function(){\r\n let _this = this;\r\n\r\n if($(\"#luckysheet-row-count-show\").is(\":visible\")){\r\n $(\"#luckysheet-row-count-show\").hide();\r\n }\r\n\r\n if($(\"#luckysheet-column-count-show\").is(\":visible\")){\r\n $(\"#luckysheet-column-count-show\").hide();\r\n }\r\n\r\n $(\"#luckysheet-rows-h-selected\").empty();\r\n $(\"#luckysheet-cols-h-selected\").empty();\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n\r\n if (_this.freezenhorizontaldata != null && _this.freezenverticaldata != null) {\r\n let freezenTop = _this.freezenhorizontaldata[0];\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n let offTop = scrollTop - _this.freezenhorizontaldata[2];\r\n\r\n let freezenLeft = _this.freezenverticaldata[0];\r\n let freezen_colindex = _this.freezenverticaldata[1];\r\n let offLeft = scrollLeft - _this.freezenverticaldata[2];\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let obj = $.extend(true, {}, Store.luckysheet_select_save[s]);\r\n\r\n let r1 = obj.row[0], \r\n r2 = obj.row[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n\r\n let top_move = row_pre;\r\n let height_move = row - row_pre - 1;\r\n\r\n let rangeshow = true;\r\n\r\n if(r1 >= freezen_rowindex){//原选区在冻结区外\r\n if(top_move + height_move < freezenTop + offTop){\r\n rangeshow = false;\r\n }\r\n else if(top_move < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": freezenTop + offTop,\r\n \"height\": height_move - (freezenTop + offTop - top_move)\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": top_move,\r\n \"height\": height_move\r\n });\r\n }\r\n }\r\n else if(r2 >= freezen_rowindex){//原选区有一部分在冻结区内\r\n if(top_move + height_move < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": top_move + offTop,\r\n \"height\": freezenTop - top_move\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": top_move + offTop,\r\n \"height\": height_move - offTop\r\n });\r\n }\r\n }\r\n else{//原选区在冻结区内\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css(\"top\", top_move + offTop);\r\n }\r\n\r\n let c1 = obj.column[0], \r\n c2 = obj.column[1];\r\n\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n let left_move = col_pre;\r\n let width_move = col - col_pre - 1;\r\n\r\n if(c1 >= freezen_colindex){//原选区在冻结区外\r\n if(left_move + width_move < freezenLeft + offLeft){\r\n rangeshow = false;\r\n }\r\n else if(left_move < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": freezenLeft + offLeft,\r\n \"width\": width_move - (freezenLeft + offLeft - left_move)\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": left_move,\r\n \"width\": width_move\r\n });\r\n }\r\n }\r\n else if(c2 >= freezen_colindex){//原选区有一部分在冻结区内\r\n if(left_move + width_move < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": left_move + offLeft,\r\n \"width\": freezenLeft - left_move\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": left_move + offLeft,\r\n \"width\": width_move - offLeft\r\n });\r\n }\r\n }\r\n else{//原选区在冻结区内\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css(\"left\", left_move + offLeft);\r\n }\r\n\r\n if(!rangeshow){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).hide();\r\n }\r\n\r\n if(s == Store.luckysheet_select_save.length - 1){\r\n let rf = obj.row_focus == null ? r1 : obj.row_focus;\r\n let cf = obj.column_focus == null ? c1 : obj.column_focus;\r\n \r\n let row_f = Store.visibledatarow[rf], \r\n row_pre_f = rf - 1 == -1 ? 0 : Store.visibledatarow[rf - 1];\r\n let col_f = Store.visibledatacolumn[cf], \r\n col_pre_f = cf - 1 == -1 ? 0 : Store.visibledatacolumn[cf - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, rf, cf);\r\n if(!!margeset){\r\n row_f = margeset.row[1];\r\n row_pre_f = margeset.row[0];\r\n\r\n col_f = margeset.column[1];\r\n col_pre_f = margeset.column[0];\r\n }\r\n\r\n let top = row_pre_f;\r\n let height = row_f - row_pre_f - 1;\r\n\r\n let left = col_pre_f;\r\n let width = col_f - col_pre_f - 1;\r\n\r\n let focuscell = true;\r\n\r\n if(top >= freezenTop){\r\n if(top + height < freezenTop + offTop){\r\n focuscell = false;\r\n }\r\n else if(top < freezenTop + offTop){ \r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": freezenTop + offTop,\r\n \"height\": height - (freezenTop + offTop - top)\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": top,\r\n \"height\": height\r\n });\r\n }\r\n }\r\n else if(top + height >= freezenTop){\r\n if(top + height < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": top + offTop,\r\n \"height\": freezenTop - top\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": top + offTop,\r\n \"height\": height - offTop\r\n })\r\n }\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css(\"top\", top + offTop);\r\n }\r\n\r\n if(left >= freezenLeft){\r\n if(left + width < freezenLeft + offLeft){\r\n focuscell = false;\r\n }\r\n else if(left < freezenLeft + offLeft){ \r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": freezenLeft + offLeft,\r\n \"width\": width - (freezenLeft + offLeft - left)\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": left,\r\n \"width\": width\r\n });\r\n }\r\n }\r\n else if(left + width >= freezenLeft){\r\n if(left + width < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": left + offLeft,\r\n \"width\": freezenLeft - left\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": left + offLeft,\r\n \"width\": width - offLeft\r\n })\r\n }\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css(\"left\", left + offLeft);\r\n }\r\n\r\n if(!focuscell){\r\n $(\"#luckysheet-cell-selected-focus\").hide();\r\n }\r\n }\r\n }\r\n }\r\n else if (_this.freezenhorizontaldata != null) {\r\n let freezenTop = _this.freezenhorizontaldata[0];\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n let offTop = scrollTop - _this.freezenhorizontaldata[2];\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let obj = $.extend(true, {}, Store.luckysheet_select_save[s]);\r\n\r\n let r1 = obj.row[0], \r\n r2 = obj.row[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n\r\n let top_move = row_pre;\r\n let height_move = row - row_pre - 1;\r\n\r\n if(r1 >= freezen_rowindex){//原选区在冻结区外\r\n if(top_move + height_move < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).hide();\r\n }\r\n else if(top_move < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": freezenTop + offTop,\r\n \"height\": height_move - (freezenTop + offTop - top_move)\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": top_move,\r\n \"height\": height_move\r\n });\r\n }\r\n }\r\n else if(r2 >= freezen_rowindex){//原选区有一部分在冻结区内\r\n if(top_move + height_move < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": top_move + offTop,\r\n \"height\": freezenTop - top_move\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"top\": top_move + offTop,\r\n \"height\": height_move - offTop\r\n });\r\n }\r\n }\r\n else{//原选区在冻结区内\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css(\"top\", top_move + offTop);\r\n }\r\n\r\n if(s == Store.luckysheet_select_save.length - 1){\r\n let rf = obj.row_focus == null ? r1 : obj.row_focus;\r\n let cf = obj.column_focus == null ? obj.column[0] : obj.column_focus;\r\n \r\n let row_f = Store.visibledatarow[rf], \r\n row_pre_f = rf - 1 == -1 ? 0 : Store.visibledatarow[rf - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, rf, cf);\r\n if(!!margeset){\r\n row_f = margeset.row[1];\r\n row_pre_f = margeset.row[0];\r\n }\r\n\r\n let top = row_pre_f;\r\n let height = row_f - row_pre_f - 1;\r\n\r\n if(top >= freezenTop){\r\n if(top + height < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-focus\").hide();\r\n }\r\n else if(top < freezenTop + offTop){ \r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": freezenTop + offTop,\r\n \"height\": height - (freezenTop + offTop - top)\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": top,\r\n \"height\": height\r\n });\r\n }\r\n }\r\n else if(top + height >= freezenTop){\r\n if(top + height < freezenTop + offTop){\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": top + offTop,\r\n \"height\": freezenTop - top\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"top\": top + offTop,\r\n \"height\": height - offTop\r\n })\r\n }\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css(\"top\", top + offTop);\r\n }\r\n }\r\n }\r\n }\r\n else if (_this.freezenverticaldata != null) {\r\n let freezenLeft = _this.freezenverticaldata[0];\r\n let freezen_colindex = _this.freezenverticaldata[1];\r\n let offLeft = scrollLeft - _this.freezenverticaldata[2];\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let obj = $.extend(true, {}, Store.luckysheet_select_save[s]);\r\n\r\n let c1 = obj.column[0], \r\n c2 = obj.column[1];\r\n\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n let left_move = col_pre;\r\n let width_move = col - col_pre - 1;\r\n\r\n if(c1 >= freezen_colindex){//原选区在冻结区外\r\n if(left_move + width_move < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).hide();\r\n }\r\n else if(left_move < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": freezenLeft + offLeft,\r\n \"width\": width_move - (freezenLeft + offLeft - left_move)\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": left_move,\r\n \"width\": width_move\r\n });\r\n }\r\n }\r\n else if(c2 >= freezen_colindex){//原选区有一部分在冻结区内\r\n if(left_move + width_move < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": left_move + offLeft,\r\n \"width\": freezenLeft - left_move\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css({\r\n \"left\": left_move + offLeft,\r\n \"width\": width_move - offLeft\r\n });\r\n }\r\n }\r\n else{//原选区在冻结区内\r\n $(\"#luckysheet-cell-selected-boxs\").find(\".luckysheet-cell-selected\").eq(s).show().css(\"left\", left_move + offLeft);\r\n }\r\n\r\n if(s == Store.luckysheet_select_save.length - 1){\r\n let rf = obj.row_focus == null ? obj.row[0] : obj.row_focus;\r\n let cf = obj.column_focus == null ? c1 : obj.column_focus;\r\n \r\n let col_f = Store.visibledatacolumn[cf], \r\n col_pre_f = cf - 1 == -1 ? 0 : Store.visibledatacolumn[cf - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, rf, cf);\r\n if(!!margeset){\r\n col_f = margeset.column[1];\r\n col_pre_f = margeset.column[0];\r\n }\r\n\r\n let left = col_pre_f;\r\n let width = col_f - col_pre_f - 1;\r\n\r\n if(left >= freezenLeft){\r\n if(left + width < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-focus\").hide();\r\n }\r\n else if(left < freezenLeft + offLeft){ \r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": freezenLeft + offLeft,\r\n \"width\": width - (freezenLeft + offLeft - left)\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": left,\r\n \"width\": width\r\n });\r\n }\r\n }\r\n else if(left + width >= freezenLeft){\r\n if(left + width < freezenLeft + offLeft){\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": left + offLeft,\r\n \"width\": freezenLeft - left\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css({\r\n \"left\": left + offLeft,\r\n \"width\": width - offLeft\r\n })\r\n }\r\n }\r\n else{\r\n $(\"#luckysheet-cell-selected-focus\").show().css(\"left\", left + offLeft);\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n selectHightlightShow();\r\n }\r\n },\r\n scrollAdaptOfchart: function(){\r\n let _this = this;\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n\r\n if(_this.freezenhorizontaldata != null && _this.freezenverticaldata != null){\r\n let freezenTop = _this.freezenhorizontaldata[0] - _this.freezenhorizontaldata[2];\r\n let freezenLeft = _this.freezenverticaldata[0] - _this.freezenverticaldata[2];\r\n\r\n $(\"#luckysheet-cell-main .luckysheet-data-visualization-chart\").each(function(i, e){\r\n let x = $(e).position();\r\n let width = $(e).width();\r\n let height = $(e).height();\r\n\r\n let $canvas_width = $(e).find(\"canvas\").width();\r\n let $canvas_height = $(e).find(\"canvas\").height();\r\n\r\n let height_diff = $canvas_height - height;\r\n let width_diff = $canvas_width - width;\r\n\r\n if((x.top - height_diff) < freezenTop){\r\n let size = freezenTop - (x.top - height_diff);\r\n\r\n if(size > ($canvas_height + 40 + 2)){\r\n $(e).css(\"visibility\", \"hidden\");\r\n }\r\n else{\r\n $(e).css({\r\n \"top\": freezenTop + scrollTop,\r\n \"height\": $canvas_height - size,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"top\", - size);\r\n }\r\n }\r\n else{\r\n $(e).css({\r\n \"top\": x.top - height_diff + scrollTop,\r\n \"height\": $canvas_height,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"top\", 0);\r\n }\r\n\r\n if((x.left - width_diff) < freezenLeft){\r\n let size = freezenLeft - (x.left - width_diff);\r\n\r\n if(size > ($canvas_width + 20 + 2)){\r\n $(e).css(\"visibility\", \"hidden\");\r\n }\r\n else{\r\n $(e).css({\r\n \"left\": freezenLeft + scrollLeft,\r\n \"width\": $canvas_width - size,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"left\", - size);\r\n }\r\n }\r\n else{\r\n $(e).css({\r\n \"left\": x.left - width_diff + scrollLeft,\r\n \"width\": $canvas_width,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"left\", 0);\r\n }\r\n })\r\n }\r\n else if(_this.freezenhorizontaldata != null){\r\n let freezenTop = _this.freezenhorizontaldata[0] - _this.freezenhorizontaldata[2];\r\n\r\n $(\"#luckysheet-cell-main .luckysheet-data-visualization-chart\").each(function(i, e){\r\n let x = $(e).position();\r\n let height = $(e).height();\r\n \r\n let $canvas_height = $(e).find(\"canvas\").height();\r\n\r\n let height_diff = $canvas_height - height;\r\n\r\n if((x.top - height_diff) < freezenTop){\r\n let size = freezenTop - (x.top - height_diff);\r\n\r\n if(size > ($canvas_height + 40 + 2)){\r\n $(e).css(\"visibility\", \"hidden\");\r\n }\r\n else{\r\n $(e).css({\r\n \"top\": freezenTop + scrollTop,\r\n \"height\": $canvas_height - size,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"top\", - size);\r\n }\r\n }\r\n else{\r\n $(e).css({\r\n \"top\": x.top - height_diff + scrollTop,\r\n \"height\": $canvas_height,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"top\", 0);\r\n }\r\n })\r\n }\r\n else if(_this.freezenverticaldata != null){\r\n let freezenLeft = _this.freezenverticaldata[0] - _this.freezenverticaldata[2];\r\n\r\n $(\"#luckysheet-cell-main .luckysheet-data-visualization-chart\").each(function(i, e){\r\n let x = $(e).position();\r\n let width = $(e).width();\r\n\r\n let $canvas_width = $(e).find(\"canvas\").width();\r\n\r\n let width_diff = $canvas_width - width;\r\n\r\n if((x.left - width_diff) < freezenLeft){\r\n let size = freezenLeft - (x.left - width_diff);\r\n\r\n if(size > ($canvas_width + 20 + 2)){\r\n $(e).css(\"visibility\", \"hidden\");\r\n }\r\n else{\r\n $(e).css({\r\n \"left\": freezenLeft + scrollLeft,\r\n \"width\": $canvas_width - size,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"left\", - size);\r\n }\r\n }\r\n else{\r\n $(e).css({\r\n \"left\": x.left - width_diff + scrollLeft,\r\n \"width\": $canvas_width,\r\n \"visibility\": \"visible\"\r\n }); \r\n $(e).find(\"canvas\").css(\"left\", 0);\r\n }\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-cell-main .luckysheet-data-visualization-chart\").each(function(i, e){\r\n let x = $(e).position();\r\n let width = $(e).width();\r\n let height = $(e).height();\r\n\r\n let $canvas_width = $(e).find(\"canvas\").width();\r\n let $canvas_height = $(e).find(\"canvas\").height();\r\n\r\n let height_diff = $canvas_height - height;\r\n let width_diff = $canvas_width - width;\r\n\r\n $(e).css({\r\n \"top\": x.top - height_diff + scrollTop,\r\n \"height\": $canvas_height,\r\n \"left\": x.left - width_diff + scrollLeft,\r\n \"width\": $canvas_width,\r\n \"visibility\": \"visible\"\r\n }); \r\n\r\n $(e).find(\"canvas\").css({\r\n \"top\": 0,\r\n \"left\": 0\r\n });\r\n })\r\n }\r\n },\r\n scrollAdaptOfpostil: function(){\r\n let _this = this;\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n\r\n if(_this.freezenhorizontaldata != null && _this.freezenverticaldata != null){\r\n let freezenTop = _this.freezenhorizontaldata[0];\r\n let freezenLeft = _this.freezenverticaldata[0];\r\n\r\n let offTop = scrollTop - _this.freezenhorizontaldata[2];\r\n let offLeft = scrollLeft - _this.freezenverticaldata[2];\r\n\r\n $(\"#luckysheet-postil-showBoxs .luckysheet-postil-show\").each(function(i, e){\r\n let id = $(e).attr(\"id\");\r\n\r\n let r = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[0];\r\n let c = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[1];\r\n\r\n let postil = Store.flowdata[r][c].ps;\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let toX = col;\r\n let toY = row_pre;\r\n\r\n let postil_left = postil[\"left\"] == null ? toX + 18 : postil[\"left\"];\r\n let postil_top = postil[\"top\"] == null ? toY - 18 : postil[\"top\"];\r\n let postil_width = postil[\"width\"] == null ? luckysheetPostil.defaultWidth : postil[\"width\"];\r\n let postil_height = postil[\"height\"] == null ? luckysheetPostil.defaultHeight : postil[\"height\"];\r\n\r\n if(postil_top < 0){\r\n postil_top = 2;\r\n }\r\n\r\n let size = luckysheetPostil.getArrowCanvasSize(postil_left, postil_top, toX, toY);\r\n let show = true;\r\n let show2 = true;\r\n\r\n if(r >= _this.freezenhorizontaldata[1]){\r\n if(postil_top + postil_height < freezenTop){\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"top\", postil_top + offTop);\r\n $(e).show().find(\".arrowCanvas\").css(\"top\", size[1] + offTop);\r\n }\r\n else{\r\n if(postil_top < freezenTop + offTop){\r\n if(postil_top + postil_height <= freezenTop + offTop){\r\n show = false;\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css({ \"top\": freezenTop + offTop, \"height\": postil_height - (freezenTop + offTop - postil_top) });\r\n $(e).show().find(\".formulaInputFocus\").css(\"margin-top\", -(freezenTop + offTop - postil_top));\r\n $(e).show().find(\".arrowCanvas\").hide(); \r\n\r\n show2 = false;\r\n }\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css({\r\n \"top\": postil_top,\r\n \"height\": postil_height\r\n });\r\n $(e).show().find(\".formulaInputFocus\").css(\"margin-top\", 0);\r\n $(e).show().find(\".arrowCanvas\").css(\"top\", size[1]);\r\n // luckysheetPostil.buildPs(r, c, postil);\r\n }\r\n }\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"top\", postil_top + offTop);\r\n $(e).show().find(\".arrowCanvas\").css(\"top\", size[1] + offTop);\r\n }\r\n\r\n if(c >= _this.freezenverticaldata[1]){\r\n if(postil_left + postil_width < freezenLeft){\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"left\", postil_left + offLeft);\r\n $(e).show().find(\".arrowCanvas\").css(\"left\", size[0] + offLeft);\r\n }\r\n else{\r\n if(postil_left < freezenLeft + offLeft){\r\n if(postil_left + postil_width <= freezenLeft + offLeft){\r\n show = false;\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css({ \"left\": freezenLeft + offLeft, \"width\": postil_width - (freezenLeft + offLeft - postil_left) });\r\n $(e).show().find(\".formulaInputFocus\").css(\"margin-left\", -(freezenLeft + offLeft - postil_left));\r\n $(e).show().find(\".arrowCanvas\").hide(); \r\n\r\n show2 = false;\r\n }\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css({\r\n \"left\": postil_left,\r\n \"width\": postil_width \r\n });\r\n $(e).show().find(\".formulaInputFocus\").css(\"margin-left\", 0);\r\n $(e).show().find(\".arrowCanvas\").css(\"left\", size[0]);\r\n // luckysheetPostil.buildPs(r, c, postil);\r\n }\r\n }\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"left\", postil_left + offLeft);\r\n $(e).show().find(\".arrowCanvas\").css(\"left\", size[0] + offLeft);\r\n }\r\n\r\n if(!show){\r\n $(e).hide();\r\n }\r\n\r\n if(show && show2){\r\n $(e).show().find(\".arrowCanvas\").show();\r\n }\r\n })\r\n }\r\n else if(_this.freezenhorizontaldata != null){\r\n let freezenTop = _this.freezenhorizontaldata[0];\r\n let offTop = scrollTop - _this.freezenhorizontaldata[2];\r\n\r\n $(\"#luckysheet-postil-showBoxs .luckysheet-postil-show\").each(function(i, e){\r\n let id = $(e).attr(\"id\");\r\n\r\n let r = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[0];\r\n let c = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[1];\r\n\r\n let postil = Store.flowdata[r][c].ps;\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let toX = col;\r\n let toY = row_pre;\r\n\r\n let postil_left = postil[\"left\"] == null ? toX + 18 : postil[\"left\"];\r\n let postil_top = postil[\"top\"] == null ? toY - 18 : postil[\"top\"];\r\n let postil_width = postil[\"width\"] == null ? luckysheetPostil.defaultWidth : postil[\"width\"];\r\n let postil_height = postil[\"height\"] == null ? luckysheetPostil.defaultHeight : postil[\"height\"];\r\n\r\n if(postil_top < 0){\r\n postil_top = 2;\r\n }\r\n\r\n let size = luckysheetPostil.getArrowCanvasSize(postil_left, postil_top, toX, toY);\r\n\r\n if(r >= _this.freezenhorizontaldata[1]){\r\n if(postil_top + postil_height < freezenTop){\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"top\", postil_top + offTop);\r\n $(e).show().find(\".arrowCanvas\").css(\"top\", size[1] + offTop);\r\n }\r\n else{\r\n if(postil_top < freezenTop + offTop){\r\n if(postil_top + postil_height <= freezenTop + offTop){\r\n $(e).hide();\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css({ \"top\": freezenTop + offTop, \"height\": postil_height - (freezenTop + offTop - postil_top) });\r\n $(e).show().find(\".formulaInputFocus\").css(\"margin-top\", -(freezenTop + offTop - postil_top));\r\n $(e).show().find(\".arrowCanvas\").hide(); \r\n }\r\n }\r\n else{\r\n luckysheetPostil.buildPs(r, c, postil);\r\n }\r\n }\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"top\", postil_top + offTop);\r\n $(e).show().find(\".arrowCanvas\").css(\"top\", size[1] + offTop);\r\n }\r\n })\r\n }\r\n else if(_this.freezenverticaldata != null){\r\n let freezenLeft = _this.freezenverticaldata[0];\r\n let offLeft = scrollLeft - _this.freezenverticaldata[2];\r\n\r\n $(\"#luckysheet-postil-showBoxs .luckysheet-postil-show\").each(function(i, e){\r\n let id = $(e).attr(\"id\");\r\n\r\n let r = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[0];\r\n let c = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[1];\r\n\r\n let postil = Store.flowdata[r][c].ps;\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let toX = col;\r\n let toY = row_pre;\r\n\r\n let postil_left = postil[\"left\"] == null ? toX + 18 : postil[\"left\"];\r\n let postil_top = postil[\"top\"] == null ? toY - 18 : postil[\"top\"];\r\n let postil_width = postil[\"width\"] == null ? luckysheetPostil.defaultWidth : postil[\"width\"];\r\n let postil_height = postil[\"height\"] == null ? luckysheetPostil.defaultHeight : postil[\"height\"];\r\n\r\n if(postil_top < 0){\r\n postil_top = 2;\r\n }\r\n\r\n let size = luckysheetPostil.getArrowCanvasSize(postil_left, postil_top, toX, toY);\r\n\r\n if(c >= _this.freezenverticaldata[1]){\r\n if(postil_left + postil_width < freezenLeft){\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"left\", postil_left + offLeft);\r\n $(e).show().find(\".arrowCanvas\").css(\"left\", size[0] + offLeft);\r\n }\r\n else{\r\n if(postil_left < freezenLeft + offLeft){\r\n if(postil_left + postil_width <= freezenLeft + offLeft){\r\n $(e).hide();\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css({ \"left\": freezenLeft + offLeft, \"width\": postil_width - (freezenLeft + offLeft - postil_left) });\r\n $(e).show().find(\".formulaInputFocus\").css(\"margin-left\", -(freezenLeft + offLeft - postil_left));\r\n $(e).show().find(\".arrowCanvas\").hide(); \r\n }\r\n }\r\n else{\r\n luckysheetPostil.buildPs(r, c, postil);\r\n }\r\n }\r\n }\r\n else{\r\n $(e).show().find(\".luckysheet-postil-show-main\").css(\"left\", postil_left + offLeft);\r\n $(e).show().find(\".arrowCanvas\").css(\"left\", size[0] + offLeft);\r\n }\r\n })\r\n }\r\n else{\r\n $(\"#luckysheet-postil-showBoxs .luckysheet-postil-show\").each(function(i, e){\r\n let id = $(e).attr(\"id\");\r\n\r\n let r = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[0];\r\n let c = id.split(\"luckysheet-postil-show_\")[1].split(\"_\")[1];\r\n\r\n let postil = Store.flowdata[r][c].ps;\r\n\r\n luckysheetPostil.buildPs(r, c, postil);\r\n })\r\n }\r\n },\r\n scrollAdaptOfdpicon: function(){\r\n let _this = this;\r\n\r\n let copy_r = luckysheetDropCell.copyRange[\"row\"][1], \r\n copy_c = luckysheetDropCell.copyRange[\"column\"][1];\r\n \r\n let apply_r = luckysheetDropCell.applyRange[\"row\"][1], \r\n apply_c = luckysheetDropCell.applyRange[\"column\"][1];\r\n \r\n let row_index, col_index;\r\n if(apply_r >= copy_r && apply_c >= copy_c){\r\n row_index = apply_r;\r\n col_index = apply_c;\r\n }\r\n else{\r\n row_index = copy_r;\r\n col_index = copy_c; \r\n }\r\n\r\n if(_this.freezenhorizontaldata != null && _this.freezenverticaldata != null){\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n let offsetRow = luckysheet_searcharray(_this.freezenhorizontaldata[3], $(\"#luckysheet-cell-main\").scrollTop() - _this.freezenhorizontaldata[2]);\r\n let freezen_colindex = _this.freezenverticaldata[1];\r\n let offsetColumn = luckysheet_searcharray(_this.freezenverticaldata[3], $(\"#luckysheet-cell-main\").scrollLeft() - _this.freezenverticaldata[2]);\r\n\r\n if(row_index >= freezen_rowindex && col_index >= freezen_colindex){\r\n if(row_index < (freezen_rowindex + offsetRow - 1) || col_index < (freezen_colindex + offsetColumn - 1)){\r\n $(\"#luckysheet-dropCell-icon\").hide();\r\n }\r\n else{\r\n $(\"#luckysheet-dropCell-icon\").show();\r\n }\r\n }\r\n else if(row_index >= freezen_rowindex){\r\n if(row_index < (freezen_rowindex + offsetRow - 1)){\r\n $(\"#luckysheet-dropCell-icon\").hide();\r\n }\r\n else{\r\n let col = colLocationByIndex(col_index + offsetColumn)[1];\r\n\r\n $(\"#luckysheet-dropCell-icon\").show().css(\"left\", col);\r\n }\r\n }\r\n else if(col_index >= freezen_colindex){\r\n if(col_index < (freezen_colindex + offsetColumn - 1)){\r\n $(\"#luckysheet-dropCell-icon\").hide();\r\n }\r\n else{\r\n let row = rowLocationByIndex(row_index + offsetRow)[1];\r\n\r\n $(\"#luckysheet-dropCell-icon\").show().css(\"top\", row);\r\n }\r\n }\r\n else{\r\n let row = rowLocationByIndex(row_index + offsetRow)[1],\r\n col = colLocationByIndex(col_index + offsetColumn)[1];\r\n\r\n $(\"#luckysheet-dropCell-icon\").show().css({ \"left\": col, \"top\": row });\r\n }\r\n }\r\n else if(_this.freezenhorizontaldata != null){\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n let offsetRow = luckysheet_searcharray(_this.freezenhorizontaldata[3], $(\"#luckysheet-cell-main\").scrollTop() - _this.freezenhorizontaldata[2]);\r\n\r\n if(row_index >= freezen_rowindex){\r\n if(row_index < (freezen_rowindex + offsetRow - 1)){\r\n $(\"#luckysheet-dropCell-icon\").hide();\r\n }\r\n else{\r\n $(\"#luckysheet-dropCell-icon\").show();\r\n }\r\n }\r\n else{\r\n let row = rowLocationByIndex(row_index + offsetRow)[1];\r\n\r\n $(\"#luckysheet-dropCell-icon\").show().css(\"top\", row);\r\n }\r\n }\r\n else if(_this.freezenverticaldata != null){\r\n let freezen_colindex = _this.freezenverticaldata[1];\r\n let offsetColumn = luckysheet_searcharray(_this.freezenverticaldata[3], $(\"#luckysheet-cell-main\").scrollLeft() - _this.freezenverticaldata[2]);\r\n\r\n if(col_index >= freezen_colindex){\r\n if(col_index < (freezen_colindex + offsetColumn - 1)){\r\n $(\"#luckysheet-dropCell-icon\").hide();\r\n }\r\n else{\r\n $(\"#luckysheet-dropCell-icon\").show();\r\n }\r\n }\r\n else{\r\n let col = colLocationByIndex(col_index + offsetColumn)[1];\r\n\r\n $(\"#luckysheet-dropCell-icon\").show().css(\"left\", col);\r\n }\r\n }\r\n else{\r\n let row = rowLocationByIndex(row_index)[1],\r\n col = colLocationByIndex(col_index)[1];\r\n\r\n $(\"#luckysheet-dropCell-icon\").show().css({ \"left\": col, \"top\": row });\r\n }\r\n },\r\n scrollAdaptOffilteroptions: function(){\r\n let _this = this;\r\n\r\n if(_this.freezenhorizontaldata != null && _this.freezenverticaldata != null){\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n let freezen_top = _this.freezenhorizontaldata[0] + $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n let freezen_colindex = _this.freezenverticaldata[1];\r\n let offsetColumn = luckysheet_searcharray(_this.freezenverticaldata[3], $(\"#luckysheet-cell-main\").scrollLeft() - _this.freezenverticaldata[2]);\r\n\r\n $(\"#luckysheet-filter-options-sheet\"+ Store.currentSheetIndex +\" .luckysheet-filter-options\").each(function(i, e){\r\n let row_index = $(e).data(\"str\");\r\n let top = row_index - 1 == -1 ? 0 : Store.visibledatarow[row_index - 1];\r\n\r\n let col_index = $(e).data(\"cindex\");\r\n\r\n if(row_index >= freezen_rowindex && col_index >= freezen_colindex){\r\n if(top < freezen_top || col_index < (freezen_colindex + offsetColumn)){\r\n $(e).hide();\r\n }\r\n else{\r\n $(e).show();\r\n }\r\n }\r\n else if(row_index >= freezen_rowindex){\r\n if(top < freezen_top){\r\n $(e).hide();\r\n }\r\n else{\r\n let left = Store.visibledatacolumn[col_index + offsetColumn] - 20;\r\n\r\n $(e).show().css(\"left\", left);\r\n }\r\n }\r\n else if(col_index >= freezen_colindex){\r\n if(col_index < (freezen_colindex + offsetColumn)){\r\n $(e).hide();\r\n }\r\n else{\r\n $(e).show().css(\"top\", top + $(\"#luckysheet-cell-main\").scrollTop());\r\n }\r\n }\r\n else{\r\n let left = Store.visibledatacolumn[col_index + offsetColumn] - 20;\r\n\r\n $(e).show().css({ \"left\": left, \"top\": top + $(\"#luckysheet-cell-main\").scrollTop() });\r\n }\r\n });\r\n }\r\n else if(_this.freezenhorizontaldata != null){\r\n let freezen_rowindex = _this.freezenhorizontaldata[1];\r\n let freezen_top = _this.freezenhorizontaldata[0] + $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n $(\"#luckysheet-filter-options-sheet\"+ Store.currentSheetIndex +\" .luckysheet-filter-options\").each(function(i, e){\r\n let row_index = $(e).data(\"str\");\r\n let top = row_index - 1 == -1 ? 0 : Store.visibledatarow[row_index - 1];\r\n\r\n if(row_index >= freezen_rowindex){\r\n if(top < freezen_top){\r\n $(e).hide();\r\n }\r\n else{\r\n $(e).show();\r\n }\r\n }\r\n else{\r\n $(e).show().css(\"top\", top + $(\"#luckysheet-cell-main\").scrollTop());\r\n }\r\n });\r\n }\r\n else if(_this.freezenverticaldata != null){\r\n let freezen_colindex = _this.freezenverticaldata[1];\r\n let offsetColumn = luckysheet_searcharray(_this.freezenverticaldata[3], $(\"#luckysheet-cell-main\").scrollLeft() - _this.freezenverticaldata[2]);\r\n\r\n $(\"#luckysheet-filter-options-sheet\"+ Store.currentSheetIndex +\" .luckysheet-filter-options\").each(function(i, e){\r\n let col_index = $(e).data(\"cindex\");\r\n\r\n if(col_index >= freezen_colindex){\r\n if(col_index < (freezen_colindex + offsetColumn)){\r\n $(e).hide();\r\n }\r\n else{\r\n $(e).show();\r\n }\r\n }\r\n else{\r\n let left = Store.visibledatacolumn[col_index + offsetColumn] - 20;\r\n\r\n $(e).show().css(\"left\", left);\r\n }\r\n });\r\n }\r\n else{\r\n $(\"#luckysheet-filter-options-sheet\"+ Store.currentSheetIndex).empty();\r\n createFilterOptions(Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].filter_select);\r\n }\r\n },\r\n /**\r\n * \r\n * @param {string} operate \"freezenRow\"/ \"freezenColumn\"......\r\n * @param {Number | String} order 工作表索引;默认值为当前工作表索引\r\n * @param {Object} focus 冻结选区时的focus单元格行列值构成的对象;格式为{ row_focus:0, column_focus:0 }\r\n */\r\n saveFrozen: function(operate, order, focus = {}) {\r\n if (order == null) {\r\n order = getSheetIndex(Store.currentSheetIndex)\r\n }\r\n \r\n // New configuration attribute of sheet: frozen, which stores more semantic configuration for initialization and transmission to the backend. freezenhorizontaldata is still used as local data\r\n\r\n const select_save = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n\r\n const row_focus = select_save[\"row_focus\"] == null ? select_save[\"row\"][0] : select_save[\"row_focus\"];\r\n const column_focus = select_save[\"column_focus\"] == null ? select_save[\"column\"][0] : select_save[\"column_focus\"];\r\n\r\n const range = {\r\n row_focus: focus.row_focus || row_focus,\r\n column_focus: focus.column_focus || column_focus\r\n }\r\n\r\n const frozen = {\r\n \"freezenRow\": {\r\n type: 'row'\r\n },\r\n \"freezenColumn\": {\r\n type: 'column'\r\n },\r\n \"freezenRC\": {\r\n type: 'both'\r\n },\r\n \"freezenRowRange\": {\r\n type: 'rangeRow',\r\n range: range\r\n },\r\n \"freezenColumnRange\": {\r\n type: 'rangeColumn',\r\n range: range\r\n },\r\n \"freezenRCRange\": {\r\n type: 'rangeBoth',\r\n range: range\r\n },\r\n \"freezenCancel\": {\r\n type: 'cancel'\r\n }\r\n }\r\n\r\n // store frozen\r\n Store.luckysheetfile[order][\"frozen\"] = frozen[operate];\r\n },\r\n frozenTofreezen: function() {\r\n // get frozen type\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n const frozen = file[\"frozen\"];\r\n\r\n if(frozen == null){\r\n return;\r\n }\r\n\r\n let freezen = null;\r\n\r\n // transform to freezen\r\n if(frozen.type === 'row'){\r\n let scrollTop = 0;\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n \r\n freezen = {\r\n horizontal:{\r\n freezenhorizontaldata: freezenhorizontaldata,\r\n top: top\r\n }\r\n }\r\n \r\n }\r\n else if(frozen.type === 'column'){\r\n let scrollLeft = 0;\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n\r\n freezen = {\r\n vertical:{\r\n freezenverticaldata: freezenverticaldata,\r\n left: left\r\n }\r\n }\r\n }\r\n else if(frozen.type === 'both'){\r\n let scrollTop = 0;\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n \r\n let scrollLeft = 0;\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n\r\n freezen = {\r\n horizontal:{\r\n freezenhorizontaldata: freezenhorizontaldata,\r\n top: top\r\n },\r\n vertical:{\r\n freezenverticaldata: freezenverticaldata,\r\n left: left\r\n }\r\n }\r\n\r\n }\r\n else if(frozen.type === 'rangeRow'){\r\n let scrollTop = 0;\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n\r\n let row_focus = frozen.range[\"row_focus\"];\r\n\r\n if(row_focus > row_st){\r\n row_st = row_focus;\r\n }\r\n \r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n\r\n freezen = {\r\n horizontal:{\r\n freezenhorizontaldata: freezenhorizontaldata,\r\n top: top\r\n }\r\n }\r\n\r\n }\r\n else if(frozen.type === 'rangeColumn'){\r\n let scrollLeft = 0;\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n\r\n let column_focus = frozen.range[\"column_focus\"];\r\n\r\n if(column_focus > col_st){\r\n col_st = column_focus;\r\n }\r\n\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n\r\n freezen = {\r\n vertical:{\r\n freezenverticaldata: freezenverticaldata,\r\n left: left\r\n }\r\n }\r\n\r\n }\r\n else if(frozen.type === 'rangeBoth'){\r\n let scrollTop = 0;\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n\r\n let row_focus = frozen.range[\"row_focus\"];\r\n\r\n if(row_focus > row_st){\r\n row_st = row_focus;\r\n }\r\n \r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n\r\n let scrollLeft = 0;\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n\r\n let column_focus = frozen.range[\"column_focus\"];\r\n\r\n if(column_focus > col_st){\r\n col_st = column_focus;\r\n }\r\n\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n\r\n freezen = {\r\n horizontal:{\r\n freezenhorizontaldata: freezenhorizontaldata,\r\n top: top\r\n },\r\n vertical:{\r\n freezenverticaldata: freezenverticaldata,\r\n left: left\r\n }\r\n }\r\n }\r\n else if(frozen.type === 'cancel'){\r\n freezen = {\r\n horizontal: null,\r\n vertical: null\r\n }\r\n }\r\n\r\n file[\"freezen\"] = freezen;\r\n }\r\n}\r\n\r\nexport default luckysheetFreezen;","import luckysheetConfigsetting from './luckysheetConfigsetting';\r\nimport luckysheetFreezen from './freezen';\r\nimport { luckysheetrefreshgrid } from '../global/refresh';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport sheetmanage from './sheetmanage';\r\nimport tooltip from '../global/tooltip'\r\n\r\nlet gridW = 0, \r\n gridH = 0;\r\n\r\nexport default function luckysheetsizeauto(isRefreshCanvas=true) {\r\n if (!luckysheetConfigsetting.showinfobar) {\r\n Store.infobarHeight = 0;\r\n $(\"#luckysheet_info_detail\").hide();\r\n }\r\n else {\r\n $(\"#luckysheet_info_detail\").show();\r\n // Store.infobarHeight = 56;\r\n Store.infobarHeight = document.querySelector('#luckysheet_info_detail').offsetHeight;\r\n }\r\n\r\n if (!!Store.toobarObject && !!Store.toobarObject.toobarElements && Store.toobarObject.toobarElements.length === 0) {\r\n $(\"#\" + Store.container).find(\".luckysheet-wa-editor\").hide();\r\n Store.toolbarHeight = 0;\r\n }\r\n else {\r\n $(\"#\" + Store.container).find(\".luckysheet-wa-editor\").show();\r\n // Store.toolbarHeight = 72;\r\n Store.toolbarHeight = document.querySelector('#' + Store.container +' .luckysheet-wa-editor').offsetHeight;\r\n }\r\n\r\n // if (!luckysheetConfigsetting.showsheetbar) {\r\n // $(\"#\" + Store.container).find(\"#luckysheet-sheet-area\").hide();\r\n // Store.sheetBarHeight = 0;\r\n // }\r\n // else {\r\n // $(\"#\" + Store.container).find(\"#luckysheet-sheet-area\").show();\r\n // Store.sheetBarHeight = 31;\r\n // }\r\n\r\n \r\n customSheetbarConfig();\r\n\r\n // if (!luckysheetConfigsetting.showstatisticBar) {\r\n // $(\"#\" + Store.container).find(\".luckysheet-stat-area\").hide();\r\n // Store.statisticBarHeight = 0;\r\n // }\r\n // else {\r\n // $(\"#\" + Store.container).find(\".luckysheet-stat-area\").show();\r\n // Store.statisticBarHeight = 23;\r\n // }\r\n\r\n customStatisticBarConfig();\r\n\r\n // 公式栏\r\n const formulaEle = document.querySelector(\"#\" + Store.container + ' .luckysheet-wa-calculate');\r\n if (!luckysheetConfigsetting.sheetFormulaBar) {\r\n formulaEle.style.display = 'none';\r\n Store.calculatebarHeight = 0;\r\n }\r\n else {\r\n formulaEle.style.display = 'block';\r\n Store.calculatebarHeight = formulaEle.offsetHeight;\r\n }\r\n\r\n $(\"#\" + Store.container).find(\".luckysheet-grid-container\").css(\"top\", Store.toolbarHeight + Store.infobarHeight + Store.calculatebarHeight);\r\n\r\n gridW = $(\"#\" + Store.container).width();\r\n\r\n if(luckysheetConfigsetting.showConfigWindowResize){//数据透视表 图表 交替颜色 Protection\r\n if($(\"#luckysheet-modal-dialog-slider-pivot\").is(\":visible\")){\r\n gridW -= $(\"#luckysheet-modal-dialog-slider-pivot\").outerWidth();\r\n } \r\n else if($(\".chartSetting\").is(\":visible\")){\r\n gridW -= $(\".chartSetting\").outerWidth();\r\n }\r\n else if($(\"#luckysheet-modal-dialog-slider-alternateformat\").is(\":visible\")){\r\n gridW -= $(\"#luckysheet-modal-dialog-slider-alternateformat\").outerWidth();\r\n }\r\n if($(\"#luckysheet-modal-dialog-slider-protection\").is(\":visible\")){\r\n gridW -= $(\"#luckysheet-modal-dialog-slider-protection\").outerWidth();\r\n } \r\n }\r\n\r\n const _locale = locale();\r\n const locale_toolbar = _locale.toolbar;\r\n let ismore = false, \r\n toolbarW = 0,\r\n morebtn = `
\r\n
\r\n
\r\n\r\n
\r\n ${locale_toolbar.toolMore}\r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n
`,\r\n morediv = '
';\r\n \r\n if($(\"#luckysheet-icon-morebtn-div\").length == 0){\r\n $(\"body\").append(morediv);\r\n }\r\n\r\n $(\"#luckysheet-icon-morebtn-div\").hide();\r\n // $(\"#luckysheet-icon-morebtn-div > div\").appendTo($(\"#luckysheet-wa-editor\"));\r\n\r\n $(\"#luckysheet-icon-morebtn-div > div\").each(function(){\r\n const $t = $(this)[0];\r\n const $container = $(\"#luckysheet-wa-editor\")[0];\r\n \r\n $container.appendChild(document.createTextNode(\" \"));\r\n $container.appendChild($t);\r\n });\r\n\r\n $(\"#luckysheet-icon-morebtn\").remove();\r\n\r\n // 所有按钮宽度与元素定位\r\n const toobarWidths = Store.toobarObject.toobarWidths;\r\n const toobarElements = Store.toobarObject.toobarElements;\r\n let moreButtonIndex = 0;\r\n\r\n // When you resize the window during initialization, you will find that the dom has not been rendered yet\r\n if(toobarWidths == undefined){\r\n return;\r\n }\r\n // 找到应该隐藏的起始元素位置\r\n for (let index = toobarWidths.length - 1; index >= 0; index--) {\r\n\r\n // #luckysheet-icon-morebtn button width plus right is 83px\r\n if(toobarWidths[index] < gridW - 90){\r\n moreButtonIndex = index;\r\n if(moreButtonIndex < toobarWidths.length - 1){\r\n\r\n ismore = true;\r\n }\r\n break;\r\n }\r\n }\r\n // 从起始位置开始,后面的元素统一挪到下方隐藏DIV中\r\n for (let index = moreButtonIndex; index < toobarElements.length; index++) {\r\n const element = toobarElements[index];\r\n if(element instanceof Array){\r\n for(const ele of element){\r\n $(\"#luckysheet-icon-morebtn-div\").append($(`${ele}`));\r\n }\r\n }else{\r\n $(\"#luckysheet-icon-morebtn-div\").append($(`${element}`));\r\n }\r\n \r\n }\r\n\r\n if(ismore){\r\n \r\n $(\"#luckysheet-wa-editor\").append(morebtn);\r\n $(\"#luckysheet-icon-morebtn\").click(function(){\r\n let right = $(window).width() - $(\"#luckysheet-icon-morebtn\").offset().left - $(\"#luckysheet-icon-morebtn\").width()+ $(\"body\").scrollLeft();\r\n $(\"#luckysheet-icon-morebtn-div\").toggle().css(\"right\", right < 0 ? 0 : right);\r\n\r\n let $txt = $(this).find(\".luckysheet-toolbar-menu-button-caption\");\r\n if($txt.text().indexOf(locale_toolbar.toolMore) > -1){\r\n\r\n const toolCloseHTML = `\r\n
\r\n ${locale_toolbar.toolClose}\r\n
\r\n
\r\n
\r\n `\r\n $(this).find(\".luckysheet-toolbar-button-inner-box\").html(toolCloseHTML);\r\n }\r\n else{\r\n\r\n const toolMoreHTML = `\r\n
\r\n ${locale_toolbar.toolMore}\r\n
\r\n
\r\n
\r\n `\r\n\r\n $(this).find(\".luckysheet-toolbar-button-inner-box\").html(toolMoreHTML);\r\n }\r\n \r\n });\r\n //$(\"#luckysheet-wa-editor div\").trigger(\"create\");\r\n \r\n // $(\"#luckysheet-icon-morebtn-div .luckysheet-toolbar-menu-button\").css(\"margin-right\", -1);\r\n // $(\"#luckysheet-icon-morebtn-div .luckysheet-toolbar-button-split-left\").css(\"margin-right\", -3);\r\n\r\n // “更多”容器中,联动hover效果\r\n $(\"#luckysheet-icon-morebtn-div .luckysheet-toolbar-button-split-left\").off(\"hover\").hover(function(){\r\n $(this).next(\".luckysheet-toolbar-button-split-right\").addClass(\"luckysheet-toolbar-button-split-right-hover\");\r\n }, function(){\r\n $(this).next(\".luckysheet-toolbar-button-split-right\").removeClass(\"luckysheet-toolbar-button-split-right-hover\");\r\n });\r\n\r\n $(\"#luckysheet-icon-morebtn-div .luckysheet-toolbar-button-split-right\").off(\"hover\").hover(function(){\r\n $(this).prev(\".luckysheet-toolbar-button-split-left\").addClass(\"luckysheet-toolbar-button-hover\");\r\n }, function(){\r\n $(this).prev(\".luckysheet-toolbar-button-split-left\").removeClass(\"luckysheet-toolbar-button-hover\");\r\n });\r\n\r\n // tooltip\r\n tooltip.createHoverTip(\"#luckysheet-icon-morebtn-div\" ,\".luckysheet-toolbar-menu-button, .luckysheet-toolbar-button, .luckysheet-toolbar-combo-button\");\r\n }\r\n \r\n $(\"#\"+ Store.container + \" .luckysheet-wa-editor .luckysheet-toolbar-button-split-left\").off(\"hover\").hover(function(){\r\n $(this).next(\".luckysheet-toolbar-button-split-right\").addClass(\"luckysheet-toolbar-button-split-right-hover\");\r\n }, function(){\r\n $(this).next(\".luckysheet-toolbar-button-split-right\").removeClass(\"luckysheet-toolbar-button-split-right-hover\");\r\n });\r\n\r\n $(\"#\"+ Store.container + \" .luckysheet-wa-editor .luckysheet-toolbar-button-split-right\").off(\"hover\").hover(function(){\r\n $(this).prev(\".luckysheet-toolbar-button-split-left\").addClass(\"luckysheet-toolbar-button-hover\");\r\n }, function(){\r\n $(this).prev(\".luckysheet-toolbar-button-split-left\").removeClass(\"luckysheet-toolbar-button-hover\");\r\n });\r\n\r\n // When adding elements to the luckysheet-icon-morebtn-div element of the toolbar, it will affect the height of the entire workbook area, so the height is obtained here\r\n gridH = $(\"#\" + Store.container).height();\r\n\r\n $(\"#\" + Store.container).find(\".luckysheet\").height(gridH - 2).width(gridW - 2);\r\n\r\n changeSheetContainerSize(gridW, gridH)\r\n \r\n if(isRefreshCanvas){\r\n luckysheetrefreshgrid($(\"#luckysheet-cell-main\").scrollLeft(), $(\"#luckysheet-cell-main\").scrollTop());\r\n }\r\n\r\n sheetmanage.sheetArrowShowAndHide();\r\n sheetmanage.sheetBarShowAndHide();\r\n}\r\n\r\n\r\nexport function changeSheetContainerSize(gridW, gridH){\r\n if(gridW==null){\r\n gridW = $(\"#\" + Store.container).width();\r\n }\r\n\r\n if(gridH==null){\r\n gridH = $(\"#\" + Store.container).height();\r\n }\r\n Store.cellmainHeight = gridH - (Store.infobarHeight + Store.toolbarHeight + Store.calculatebarHeight + Store.columnHeaderHeight + Store.sheetBarHeight + Store.statisticBarHeight);\r\n Store.cellmainWidth = gridW - Store.rowHeaderWidth;\r\n \r\n $(\"#luckysheet-cols-h-c, #luckysheet-cell-main\").width(Store.cellmainWidth);\r\n $(\"#luckysheet-cell-main\").height(Store.cellmainHeight);\r\n $(\"#luckysheet-rows-h\").height(Store.cellmainHeight - Store.cellMainSrollBarSize);\r\n\r\n $(\"#luckysheet-scrollbar-y\").height(Store.cellmainHeight + Store.columnHeaderHeight - Store.cellMainSrollBarSize - 3);\r\n $(\"#luckysheet-scrollbar-x\").height(Store.cellMainSrollBarSize);\r\n $(\"#luckysheet-scrollbar-y\").width(Store.cellMainSrollBarSize);\r\n\r\n $(\"#luckysheet-scrollbar-x\").width(Store.cellmainWidth).css(\"left\", Store.rowHeaderWidth - 2);\r\n\r\n Store.luckysheetTableContentHW = [\r\n Store.cellmainWidth + Store.rowHeaderWidth - Store.cellMainSrollBarSize, \r\n Store.cellmainHeight + Store.columnHeaderHeight - Store.cellMainSrollBarSize\r\n ];\r\n\r\n $(\"#luckysheetTableContent, #luckysheetTableContentF\").attr({ \r\n width: Math.ceil(Store.luckysheetTableContentHW[0] * Store.devicePixelRatio), \r\n height: Math.ceil(Store.luckysheetTableContentHW[1] * Store.devicePixelRatio) \r\n })\r\n .css({ width: Store.luckysheetTableContentHW[0], height: Store.luckysheetTableContentHW[1] });\r\n\r\n $(\"#\" + Store.container).find(\"#luckysheet-grid-window-1\").css(\"bottom\", Store.sheetBarHeight);\r\n $(\"#\" + Store.container).find(\".luckysheet-grid-window\").css(\"bottom\", Store.statisticBarHeight);\r\n\r\n let gridwidth = $(\"#luckysheet-grid-window-1\").width();\r\n $(\"#luckysheet-freezebar-horizontal\").find(\".luckysheet-freezebar-horizontal-handle\")\r\n .css({ \"width\": gridwidth - 10 })\r\n .end()\r\n .find(\".luckysheet-freezebar-horizontal-drop\")\r\n .css({ \"width\": gridwidth - 10 });\r\n\r\n let gridheight = $(\"#luckysheet-grid-window-1\").height();\r\n $(\"#luckysheet-freezebar-vertical\")\r\n .find(\".luckysheet-freezebar-vertical-handle\")\r\n .css({ \"height\": gridheight - 10 })\r\n .end()\r\n .find(\".luckysheet-freezebar-vertical-drop\")\r\n .css({ \"height\": gridheight - 10 });\r\n \r\n luckysheetFreezen.createAssistCanvas();\r\n}\r\n\r\n/**\r\n * \r\n * \r\n * Toolbar judgment rules: First set the display and hide of all tool buttons according to showtoolbar, and then override the judgment of showtoolbar according to showtoolbarConfig rules\r\n * \r\n * The width value of each button in the statistics toolbar is used to calculate which needs to be placed in more buttons\r\n */\r\nexport function menuToolBarWidth() {\r\n const showtoolbar = luckysheetConfigsetting.showtoolbar;\r\n const showtoolbarConfig = luckysheetConfigsetting.showtoolbarConfig;\r\n\r\n const toobarWidths = Store.toobarObject.toobarWidths = [];\r\n const toobarElements = Store.toobarObject.toobarElements = [];\r\n const toobarConfig = Store.toobarObject.toobarConfig = {\r\n undo: {\r\n ele:'#luckysheet-icon-undo',\r\n index:0,\r\n }, //Undo redo\r\n redo: {\r\n ele:'#luckysheet-icon-redo',\r\n index:1,\r\n },\r\n paintFormat: {\r\n ele:['#luckysheet-icon-paintformat','#toolbar-separator-paint-format'],\r\n index:2,\r\n }, //Format brush\r\n currencyFormat: {\r\n ele:'#luckysheet-icon-currency',\r\n index:3,\r\n }, //currency format\r\n percentageFormat: {\r\n ele:'#luckysheet-icon-percent',\r\n index:4,\r\n }, //Percentage format\r\n numberDecrease: {\r\n ele:'#luckysheet-icon-fmt-decimal-decrease',\r\n index:5,\r\n }, //'Decrease the number of decimal places'\r\n numberIncrease: {\r\n ele:'#luckysheet-icon-fmt-decimal-increase',\r\n index:6,\r\n }, //'Increase the number of decimal places\r\n moreFormats: {\r\n ele:['#luckysheet-icon-fmt-other','#toolbar-separator-more-format'],\r\n index:7,\r\n }, //'More Formats'\r\n font: {\r\n ele:['#luckysheet-icon-font-family','#toolbar-separator-font-family'],\r\n index:8,\r\n }, //'font'\r\n fontSize: {\r\n ele:['#luckysheet-icon-font-size','#toolbar-separator-font-size'],\r\n index:9,\r\n }, //'Font size'\r\n bold: {\r\n ele:'#luckysheet-icon-bold',\r\n index:10,\r\n }, //'Bold (Ctrl+B)'\r\n italic: {\r\n ele:'#luckysheet-icon-italic',\r\n index:11,\r\n }, //'Italic (Ctrl+I)'\r\n strikethrough: {\r\n ele:'#luckysheet-icon-strikethrough',\r\n index:12,\r\n }, //'Strikethrough (Alt+Shift+5)'\r\n underline: {\r\n ele:'#luckysheet-icon-underline',\r\n index:13,\r\n }, //'Underline (Alt+Shift+6)'\r\n textColor: {\r\n ele:['#luckysheet-icon-text-color','#luckysheet-icon-text-color-menu','#toolbar-separator-text-color'],\r\n index:14,\r\n }, //'Text color'\r\n fillColor: {\r\n ele:['#luckysheet-icon-cell-color','#luckysheet-icon-cell-color-menu'],\r\n index:15,\r\n }, //'Cell color'\r\n border: {\r\n ele:['#luckysheet-icon-border-all','#luckysheet-icon-border-menu'],\r\n index:16,\r\n }, //'border'\r\n mergeCell: {\r\n ele:['#luckysheet-icon-merge-button','#luckysheet-icon-merge-menu','#toolbar-separator-merge-cell'],\r\n index:17,\r\n }, //'Merge cells'\r\n horizontalAlignMode: {\r\n ele:['#luckysheet-icon-align','#luckysheet-icon-align-menu'],\r\n index:18,\r\n }, //'Horizontal alignment'\r\n verticalAlignMode: {\r\n ele:['#luckysheet-icon-valign','#luckysheet-icon-valign-menu'],\r\n index:19,\r\n }, //'Vertical alignment'\r\n textWrapMode: {\r\n ele:['#luckysheet-icon-textwrap','#luckysheet-icon-textwrap-menu'],\r\n index:20,\r\n }, //'Wrap mode'\r\n textRotateMode: {\r\n ele:['#luckysheet-icon-rotation','#luckysheet-icon-rotation-menu','#toolbar-separator-text-rotate'],\r\n index:21,\r\n }, //'Text Rotation Mode'\r\n\t\timage:{\r\n ele:'#luckysheet-insertImg-btn-title',\r\n index:22,\r\n }, //'Insert link'\r\n\t\tlink:{\r\n ele:'#luckysheet-insertLink-btn-title',\r\n index:23,\r\n }, //'Insert picture'\r\n chart: {\r\n ele:'#luckysheet-chart-btn-title',\r\n index:24,\r\n }, //'chart' (the icon is hidden, but if the chart plugin is configured, you can still create a new chart by right click)\r\n postil: {\r\n ele:'#luckysheet-icon-postil',\r\n index:25,\r\n }, //'comment'\r\n pivotTable: {\r\n ele:['#luckysheet-pivot-btn-title','#toolbar-separator-pivot-table'],\r\n index:26,\r\n }, //'PivotTable'\r\n function: {\r\n ele:['#luckysheet-icon-function','#luckysheet-icon-function-menu'],\r\n index:27,\r\n }, //'formula'\r\n frozenMode: {\r\n ele:['#luckysheet-freezen-btn-horizontal','#luckysheet-icon-freezen-menu'],\r\n index:28,\r\n }, //'freeze mode'\r\n sortAndFilter: {\r\n ele:'#luckysheet-icon-autofilter',\r\n index:29,\r\n }, //'sort and filter'\r\n conditionalFormat: {\r\n ele:'#luckysheet-icon-conditionformat',\r\n index:30,\r\n }, //'Conditional Format'\r\n dataVerification: {\r\n ele:'#luckysheet-dataVerification-btn-title',\r\n index:31,\r\n }, // 'Data Verification'\r\n splitColumn: {\r\n ele:'#luckysheet-splitColumn-btn-title',\r\n index:32,\r\n }, //'Split column' \r\n screenshot: {\r\n ele:'#luckysheet-chart-btn-screenshot',\r\n index:33,\r\n }, //'screenshot'\r\n findAndReplace: {\r\n ele:'#luckysheet-icon-seachmore',\r\n index:34,\r\n }, //'Find and Replace'\r\n protection:{\r\n ele:'#luckysheet-icon-protection',\r\n index:35,\r\n }, // 'Worksheet protection'\r\n\t\tprint:{\r\n ele:'#luckysheet-icon-print',\r\n index:36,\r\n }, // 'print'\r\n };\r\n\r\n const config = {\r\n undo: true, //Undo\r\n redo: true, //Redo\r\n paintFormat: true, //Format brush\r\n currencyFormat: true, //currency format\r\n percentageFormat: true, //Percentage format\r\n numberDecrease: true, //'Decrease the number of decimal places'\r\n numberIncrease: true, //'Increase the number of decimal places\r\n moreFormats: true, //'More Formats'\r\n font: true, //'font'\r\n fontSize: true, //'Font size'\r\n bold: true, //'Bold (Ctrl+B)'\r\n italic: true, //'Italic (Ctrl+I)'\r\n strikethrough: true, //'Strikethrough (Alt+Shift+5)'\r\n underline: true, //'Underline (Alt+Shift+6)'\r\n textColor: true, //'Text color'\r\n fillColor: true, //'Cell color'\r\n border: true, //'border'\r\n mergeCell: true, //'Merge cells'\r\n horizontalAlignMode: true, //'Horizontal alignment'\r\n verticalAlignMode: true, //'Vertical alignment'\r\n textWrapMode: true, //'Wrap mode'\r\n textRotateMode: true, //'Text Rotation Mode'\r\n\t\timage:true, // 'Insert picture'\r\n\t\tlink: true, // 'Insert link'(TODO)\r\n\t\tchart: true, //'chart' (the icon is hidden, but if the chart plugin is configured, you can still create a new chart by right click)\r\n\t\tpostil:true, //'comment'\r\n\t\tpivotTable: true, //'PivotTable'\r\n\t\tfunction: true, //'formula'\r\n\t\tfrozenMode: true, //'freeze mode'\r\n\t\tsortAndFilter: true, //'Sort and filter'\r\n\t\tconditionalFormat: true, //'Conditional Format'\r\n\t\tdataVerification: true, // 'Data Verification'\r\n\t\tsplitColumn: true, //'Split column'\r\n\t\tscreenshot: true, //'screenshot'\r\n\t\tfindAndReplace: true, //'Find and Replace'\r\n\t\tprotection: true, // 'Worksheet protection'\r\n\t\tprint: true, // 'print'\r\n }\r\n\r\n // false means all false\r\n if(!showtoolbar){\r\n for(let s in config){\r\n config[s] = false;\r\n }\r\n }\r\n\r\n // showtoolbarConfig determines the final result\r\n if(JSON.stringify(showtoolbarConfig) !== '{}'){\r\n if(showtoolbarConfig.hasOwnProperty('undoRedo')){\r\n config.undo = config.redo = showtoolbarConfig.undoRedo;\r\n\r\n delete showtoolbarConfig.undoRedo;\r\n }\r\n Object.assign(config,showtoolbarConfig);\r\n } \r\n\r\n // 1. The button set to false, remove the dom\r\n // 2. Build toobarWidths and toobarElements\r\n for(let s in config){\r\n if(config[s]){\r\n toobarElements.push($.extend(true,{},toobarConfig[s]));\r\n\r\n }else{\r\n if(toobarConfig[s].ele instanceof Array){\r\n for(const item of toobarConfig[s].ele){\r\n $(item).remove();\r\n }\r\n }else{\r\n $(toobarConfig[s].ele).remove();\r\n }\r\n }\r\n }\r\n\r\n toobarElements.sort(sortToolbar);\r\n\r\n function sortToolbar(a,b) {\r\n if(a.index > b.index){\r\n return 1;\r\n }else{\r\n return -1;\r\n }\r\n }\r\n\r\n toobarElements.forEach((curr,index,arr)=>{\r\n arr[index] = curr.ele;\r\n\r\n if(index !== toobarElements.length - 1){\r\n if(curr.ele instanceof Array){\r\n toobarWidths.push($(curr.ele[0]).offset().left);\r\n }else{\r\n toobarWidths.push($(curr.ele).offset().left);\r\n }\r\n }else{\r\n if(curr.ele instanceof Array){\r\n toobarWidths.push($(curr.ele[0]).offset().left);\r\n toobarWidths.push($(curr.ele[0]).offset().left + $(curr.ele[0]).outerWidth() + 5);\r\n }else{\r\n toobarWidths.push($(curr.ele).offset().left);\r\n toobarWidths.push($(curr.ele).offset().left + $(curr.ele).outerWidth() + 5);\r\n }\r\n }\r\n\r\n });\r\n \r\n}\r\n\r\n/**\r\n *Custom configuration bottom sheet button\r\n */\r\nfunction customSheetbarConfig() {\r\n\r\n if(!luckysheetConfigsetting.initShowsheetbarConfig){\r\n\r\n luckysheetConfigsetting.initShowsheetbarConfig = true;\r\n\r\n const config = {\r\n add: true, //Add worksheet\r\n menu: true, //Worksheet management menu\r\n sheet: true //Worksheet display\r\n }\r\n \r\n if(!luckysheetConfigsetting.showsheetbar){\r\n for(let s in config){\r\n config[s] = false;\r\n }\r\n }\r\n \r\n // showsheetbarConfig determines the final result\r\n if(JSON.stringify(luckysheetConfigsetting.showsheetbarConfig) !== '{}'){\r\n Object.assign(config,luckysheetConfigsetting.showsheetbarConfig);\r\n }\r\n \r\n luckysheetConfigsetting.showsheetbarConfig = config;\r\n\r\n }\r\n\r\n const config = luckysheetConfigsetting.showsheetbarConfig;\r\n\r\n let isHide = 0;\r\n\r\n for (let s in config) {\r\n if(!config[s]){\r\n switch (s) {\r\n case 'add':\r\n $('#luckysheet-sheets-add').hide();\r\n isHide++;\r\n break;\r\n \r\n case 'menu':\r\n $('#luckysheet-sheets-m').hide();\r\n isHide++;\r\n break;\r\n \r\n case 'sheet':\r\n $('#luckysheet-sheet-container').hide();\r\n $('#luckysheet-sheets-leftscroll').hide();\r\n $('#luckysheet-sheets-rightscroll').hide();\r\n isHide++;\r\n break;\r\n \r\n default:\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (isHide === 3) {\r\n $(\"#\" + Store.container).find(\"#luckysheet-sheet-area\").hide();\r\n Store.sheetBarHeight = 0;\r\n }\r\n else {\r\n $(\"#\" + Store.container).find(\"#luckysheet-sheet-area\").show();\r\n Store.sheetBarHeight = 31;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * Customize the bottom count bar\r\n */\r\nfunction customStatisticBarConfig() {\r\n if(!luckysheetConfigsetting.initStatisticBarConfig){\r\n\r\n luckysheetConfigsetting.initStatisticBarConfig = true;\r\n\r\n const config = {\r\n count: true, // Count bar\r\n view: true, // print view\r\n zoom: true // Zoom\r\n }\r\n \r\n if(!luckysheetConfigsetting.showstatisticBar){\r\n for(let s in config){\r\n config[s] = false;\r\n }\r\n }\r\n \r\n // showstatisticBarConfig determines the final result\r\n if(JSON.stringify(luckysheetConfigsetting.showstatisticBarConfig) !== '{}'){\r\n Object.assign(config,luckysheetConfigsetting.showstatisticBarConfig);\r\n }\r\n \r\n luckysheetConfigsetting.showstatisticBarConfig = config;\r\n\r\n }\r\n\r\n const config = luckysheetConfigsetting.showstatisticBarConfig;\r\n\r\n let isHide = 0;\r\n\r\n for (let s in config) {\r\n if(!config[s]){\r\n switch (s) {\r\n case 'count':\r\n $('#luckysheet-sta-content').hide();\r\n isHide++;\r\n break;\r\n \r\n case 'view':\r\n $('.luckysheet-print-viewList').hide();\r\n isHide++;\r\n break;\r\n\r\n case 'zoom':\r\n $('#luckysheet-zoom-content').hide();\r\n isHide++;\r\n break;\r\n \r\n default:\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (isHide === 3) {\r\n $(\"#\" + Store.container).find(\".luckysheet-stat-area\").hide();\r\n Store.statisticBarHeight = 0;\r\n }\r\n else {\r\n $(\"#\" + Store.container).find(\".luckysheet-stat-area\").show();\r\n Store.statisticBarHeight = 23;\r\n }\r\n}","import Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport { modelHTML } from './constant';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { setluckysheet_scroll_status } from '../methods/set';\r\nimport sheetmanage from './sheetmanage';\r\nimport luckysheetsizeauto from './resize';\r\nimport dataVerificationCtrl from './dataVerificationCtrl';\r\nimport { replaceHtml,transformRangeToAbsolute,openSelfModel } from '../utils/util';\r\nimport { selectionCopyShow } from './select';\r\nimport tooltip from '../global/tooltip';\r\nimport cleargridelement from '../global/cleargridelement';\r\n\r\nlet isInitialProtection = false, isInitialProtectionAddRang = false, rangeItemListCache=[], isAddRangeItemState=true, updateRangeItemIndex = null, validationAuthority=null, updatingSheetFile=null, firstInputSheetProtectionPassword = true;\r\nlet sqrefMapCache = {}, inputRangeProtectionPassword = {}, initialRangePasswordHtml=false;\r\n\r\nconst authorityItemArr = [\r\n \"selectLockedCells\",\r\n \"selectunLockedCells\",\r\n \"formatCells\",\r\n \"formatColumns\",\r\n \"formatRows\",\r\n \"insertColumns\",\r\n \"insertRows\",\r\n \"insertHyperlinks\",\r\n \"deleteColumns\",\r\n \"deleteRows\",\r\n \"sort\",\r\n \"filter\",\r\n \"usePivotTablereports\",\r\n \"editObjects\",\r\n \"editScenarios\"\r\n]\r\n\r\nfunction addRangeItem(item){\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n const locale_button = _locale.button;\r\n\r\n let title = item.name, sqref = item.sqref, password = item.password;\r\n \r\n let passwordTxt = \"\";\r\n if(password!=null && password.length>0){\r\n passwordTxt = '';\r\n }\r\n\r\n let rangeItemTemplate = `\r\n
\r\n
\r\n \r\n
\r\n
\r\n ${title}${passwordTxt}\r\n
\r\n
\r\n ${sqref}\r\n
\r\n
\r\n \r\n
\r\n
\r\n `;\r\n\r\n $(\"#luckysheet-protection-rangeItem-container\").append(rangeItemTemplate);\r\n}\r\n\r\nfunction initialEvent(file){\r\n\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n const locale_button = _locale.button;\r\n\r\n //confirm protection\r\n $(\"#luckysheet-slider-protection-ok\").click(function(){\r\n let password = $(\"#protection-password\").val();\r\n let sheet = $(\"#protection-swichProtectionState\").is(\":checked\");\r\n let hint = $(\"#protection-hint\").val();\r\n\r\n let file = updatingSheetFile, aut = {};\r\n\r\n if(file!=null && file.config!=null && file.config.authority!=null){\r\n aut = file.config.authority;\r\n } \r\n \r\n let authorityData = {\r\n\r\n }\r\n\r\n let algorithmName = \"None\";\r\n if(password!=\"••••••••\"){\r\n authorityData.password = password;\r\n authorityData.algorithmName = \"None\";\r\n authorityData.saltValue = null;\r\n }\r\n else if(aut!=null){\r\n authorityData.algorithmName = aut.algorithmName;\r\n authorityData.saltValue = aut.saltValue;\r\n authorityData.password = aut.password;\r\n }\r\n else {\r\n authorityData.algorithmName = \"None\";\r\n authorityData.saltValue = null;\r\n authorityData.password = \"\";\r\n }\r\n\r\n authorityData.hintText = hint;\r\n\r\n authorityData.sheet = sheet==true?1:0;\r\n\r\n for(let i=0;i div.luckysheet-protection-rangeItem\").index($rangeItem);\r\n\r\n let item = rangeItemListCache[index];\r\n\r\n updateRangeItemIndex = index;\r\n\r\n $(\"#protection-allowRangeAdd-title\").val(item.name);\r\n $(\"#protection-allowRangeAdd-range input\").val(item.sqref);\r\n if(item.algorithmName==\"None\"){\r\n $(\"#protection-allowRangeAdd-password\").val(item.password);\r\n }\r\n else{\r\n $(\"#protection-allowRangeAdd-password\").val(\"••••••••\");\r\n }\r\n $(\"#protection-allowRangeAdd-hint\").val(item.hintText);\r\n });\r\n\r\n //delete allow edit range\r\n $(document).off(\"click.luckysheetProtection.rangeItemDelete\").on(\"click.luckysheetProtection.rangeItemDelete\",\"#luckysheet-protection-rangeItem-container .luckysheet-protection-rangeItem-del\", function(e){\r\n let $rangeItem = $(e.target).closest(\".luckysheet-protection-rangeItem\");\r\n\r\n let $rangeItemContainer = $(\"#luckysheet-protection-rangeItem-container\");\r\n\r\n let index = $rangeItemContainer.find(\"> div.luckysheet-protection-rangeItem\").index($rangeItem);\r\n\r\n let item = rangeItemListCache[index];\r\n\r\n rangeItemListCache.splice(index, 1);\r\n $rangeItem.remove();\r\n });\r\n\r\n //confirm allow edit range\r\n $(document).off(\"click.luckysheetProtection.rangeItemConfirm\").on(\"click.luckysheetProtection.rangeItemConfirm\",\"#luckysheet-protection-rangeItem-confirm\", function(){\r\n let name = $(\"#protection-allowRangeAdd-title\").val(),\r\n rangeText = $(\"#protection-allowRangeAdd-range input\").val(),\r\n password = $(\"#protection-allowRangeAdd-password\").val(),\r\n hint = $(\"#protection-allowRangeAdd-hint\").val();\r\n\r\n if(name.length==0){\r\n alert(local_protection.rangeItemErrorTitleNull);\r\n return;\r\n }\r\n\r\n let range = dataVerificationCtrl.getRangeByTxt(rangeText);\r\n\r\n if(rangeText.length==0){\r\n alert(local_protection.rangeItemErrorRangeNull);\r\n return;\r\n }\r\n\r\n if(range.length==0){\r\n alert(local_protection.rangeItemErrorRange);\r\n return;\r\n }\r\n\r\n rangeText = transformRangeToAbsolute(rangeText);\r\n\r\n\r\n if(isAddRangeItemState){\r\n let item = {\r\n name:name,\r\n password:password,\r\n hintText:hint,\r\n algorithmName:\"None\",//MD2,MD4,MD5,RIPEMD-128,RIPEMD-160,SHA-1,SHA-256,SHA-384,SHA-512,WHIRLPOOL\r\n saltValue:null,\r\n checkRangePasswordUrl:null,\r\n sqref:rangeText\r\n }\r\n\r\n addRangeItem(item);\r\n rangeItemListCache.push(item);\r\n }\r\n else{\r\n let index = updateRangeItemIndex;\r\n let item = rangeItemListCache[index];\r\n\r\n item.name = name;\r\n item.sqref = rangeText;\r\n item.hintText = hint;\r\n\r\n if(password!=\"••••••••\"){\r\n item.password = password;\r\n item.algorithmName = \"None\";\r\n }\r\n\r\n let $rangeItemContainer = $(\"#luckysheet-protection-rangeItem-container\");\r\n\r\n let $rangeitem = $rangeItemContainer.find(\"> div.luckysheet-protection-rangeItem\").eq(index);\r\n\r\n let $name = $rangeitem.find(\".luckysheet-protection-rangeItem-name\");\r\n\r\n let passwordTxt = \"\";\r\n if(password!=null && password.length>0){\r\n passwordTxt = '';\r\n }\r\n\r\n $name.html(name+passwordTxt).attr(\"title\",name);\r\n\r\n let $range = $rangeitem.find(\".luckysheet-protection-rangeItem-range\");\r\n\r\n $range.html(rangeText).attr(\"title\",rangeText);\r\n }\r\n\r\n\r\n\r\n $(\"#luckysheet-protection-rangeItem-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n\r\n });\r\n\r\n\r\n //sheet validation check passWord\r\n $(document).off(\"click.luckysheetProtection.validationConfirm\").on(\"click.luckysheetProtection.validationConfirm\",\"#luckysheet-protection-sheet-validation-confirm\", function(e){\r\n let $validation = $(\"#luckysheet-protection-sheet-validation\");\r\n let aut = validationAuthority;\r\n\r\n if(aut==null){\r\n restoreProtectionConfig(validationAuthority);\r\n $validation.hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-protection\").show();\r\n luckysheetsizeauto();\r\n return;\r\n }\r\n \r\n let $input = $validation.find(\"input\");\r\n let password = $input.val();\r\n\r\n\r\n if(password==null || password.length==0){\r\n alert(local_protection.checkPasswordNullalert);\r\n return;\r\n }\r\n\r\n if(aut.algorithmName!=null && aut.algorithmName!=\"None\"){\r\n if(aut.saltValue!=null && aut.saltValue.length>0){\r\n var hasher = CryptoApi.getHasher(aut.algorithmName);\r\n password =CryptoApi.hmac(aut.saltValue, password, hasher);\r\n }\r\n else{\r\n password = CryptoApi.hash(aut.algorithmName, password);\r\n }\r\n }\r\n\r\n if(password==aut.password){\r\n restoreProtectionConfig(validationAuthority);\r\n $validation.hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-protection\").show();\r\n luckysheetsizeauto();\r\n firstInputSheetProtectionPassword = false;\r\n }\r\n else{\r\n alert(local_protection.checkPasswordWrongalert);\r\n }\r\n \r\n });\r\n\r\n $(\"#luckysheet-protection-check-selectLockedCells\").change(function() { \r\n let $selectLockedCells = $(\"#luckysheet-protection-check-selectLockedCells\"), $selectunLockedCells = $(\"#luckysheet-protection-check-selectunLockedCells\");\r\n\r\n let selectLockedCellsChecked = $selectLockedCells.is(\":checked\"), selectunLockedCellsChecked = $selectunLockedCells.is(\":checked\");\r\n\r\n if(selectLockedCellsChecked){\r\n $selectunLockedCells.prop('checked', true);\r\n }\r\n });\r\n\r\n $(\"#luckysheet-protection-check-selectunLockedCells\").change(function() { \r\n let $selectLockedCells = $(\"#luckysheet-protection-check-selectLockedCells\"), $selectunLockedCells = $(\"#luckysheet-protection-check-selectunLockedCells\");\r\n\r\n let selectLockedCellsChecked = $selectLockedCells.is(\":checked\"), selectunLockedCellsChecked = $selectunLockedCells.is(\":checked\");\r\n\r\n if(!selectunLockedCellsChecked){\r\n $selectLockedCells.prop('checked', false);\r\n }\r\n });\r\n\r\n\r\n //Cell range select controll\r\n $(document).off(\"click.luckysheetProtection.dvRange\").on(\"click.luckysheetProtection.dvRange\", \"#protection-allowRangeAdd-range .fa-table\", function(e) {\r\n $(\"#luckysheet-protection-rangeItem-dialog\").hide();\r\n\r\n let dataSource = \"0\";\r\n let txt = $(this).siblings(\"input\").val().trim(); \r\n\r\n dataVerificationCtrl.rangeDialog(dataSource, txt);\r\n\r\n dataVerificationCtrl.selectRange = [];\r\n\r\n let range = dataVerificationCtrl.getRangeByTxt(txt);\r\n if(range.length > 0){\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n dataVerificationCtrl.selectRange.push({ \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1, \r\n \"left_move\": col_pre, \r\n \"width_move\": col - col_pre - 1, \r\n \"top_move\": row_pre, \r\n \"height_move\": row - row_pre - 1, \r\n \"row\": [r1, r2], \r\n \"column\": [c1, c2], \r\n \"row_focus\": r1, \r\n \"column_focus\": c1 \r\n });\r\n }\r\n }\r\n \r\n selectionCopyShow(dataVerificationCtrl.selectRange);\r\n }); \r\n $(document).off(\"click.luckysheetProtection.dvRange2\").on(\"click.luckysheetProtection.dvRange2\", \"#luckysheet-protection-rangeItem-dialog .show-box-item-dropdown .range .fa-table\", function(e) {\r\n $(\"#luckysheet-protection-rangeItem-dialog\").hide();\r\n\r\n let dataSource = \"1\";\r\n let txt = $(this).siblings(\"input\").val().trim(); \r\n\r\n dataVerificationCtrl.rangeDialog(dataSource, txt);\r\n\r\n dataVerificationCtrl.selectRange = [];\r\n\r\n let range = dataVerificationCtrl.getRangeByTxt(txt);\r\n if(range.length > 0){\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n dataVerificationCtrl.selectRange.push({ \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1, \r\n \"left_move\": col_pre, \r\n \"width_move\": col - col_pre - 1, \r\n \"top_move\": row_pre, \r\n \"height_move\": row - row_pre - 1, \r\n \"row\": [r1, r2], \r\n \"column\": [c1, c2], \r\n \"row_focus\": r1, \r\n \"column_focus\": c1 \r\n });\r\n }\r\n }\r\n \r\n selectionCopyShow(dataVerificationCtrl.selectRange);\r\n });\r\n $(document).off(\"click.luckysheetProtection.dvRangeConfirm\").on(\"click.luckysheetProtection.dvRangeConfirm\", \"#luckysheet-dataVerificationRange-dialog-confirm\", function(e) {\r\n let txt = $(this).parents(\"#luckysheet-dataVerificationRange-dialog\").find(\"input\").val();\r\n\r\n let $input = $(\"#protection-allowRangeAdd-range input\"), inputValue = $input.val();\r\n if(inputValue.substr(inputValue.length-1, 1)==\",\"){\r\n $input.val(inputValue + txt);\r\n }\r\n else{\r\n $input.val(txt);\r\n }\r\n $(\"#luckysheet-dataVerificationRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-protection-rangeItem-dialog\").show();\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n $(document).off(\"click.luckysheetProtection.dvRangeClose\").on(\"click.dvRangeClose\", \"#luckysheet-dataVerificationRange-dialog-close\", function(e) {\r\n $(\"#luckysheet-dataVerificationRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-protection-rangeItem-dialog\").show();\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n $(document).on(\"click.luckysheetProtection.luckysheetProtection\", \"#luckysheet-dataVerificationRange-dialog .luckysheet-modal-dialog-title-close\", function(e) {\r\n $(\"#luckysheet-dataVerificationRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-protection-rangeItem-dialog\").show();\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n}\r\n\r\n//protect range config\r\nfunction initialProtectionRangeModal(file){\r\n if(isInitialProtectionAddRang){\r\n return;\r\n }\r\n isInitialProtectionAddRang = true;\r\n let _locale = locale();\r\n let local_protection = _locale.protection;\r\n const locale_button = _locale.button;\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-protection-rangeItem-dialog\", \r\n \"addclass\": \"luckysheet-protection-rangeItem-dialog\", \r\n \"title\": local_protection.allowRangeTitle, \r\n \"content\": `\r\n
\r\n
\r\n
\r\n ${local_protection.allowRangeAddTitle}\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n ${local_protection.allowRangeAddSqrf}\r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${local_protection.allowRangeAddTitlePassword}\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n ${local_protection.allowRangeAddTitleHint}\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n `, \r\n \"botton\": `\r\n `, \r\n \"style\": \"z-index:100003\" \r\n }));\r\n}\r\n\r\n\r\n//Protect sheet initial\r\nfunction initialProtectionRIghtBar(file){\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n const locale_button = _locale.button;\r\n\r\n let authorityItemHtml = \"\";\r\n for(let i=0;i\r\n
\r\n \r\n
\r\n \r\n `;\r\n }\r\n\r\n const protectionModalHtml = `\r\n
\r\n
${local_protection.protectiontTitle}
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${local_protection.authorityTitle}\r\n
\r\n ${authorityItemHtml}\r\n
\r\n
\r\n
\r\n
\r\n ${local_protection.allowRangeTitle}\r\n
\r\n
\r\n
\r\n ${local_protection.allowRangeAdd}\r\n
\r\n
\r\n
\r\n\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n ${locale_button.confirm}\r\n
\r\n
\r\n
\r\n
\r\n ${locale_button.cancel}\r\n
\r\n
\r\n
\r\n
\r\n
\r\n `;\r\n\r\n $(\"body\").append(protectionModalHtml);\r\n\r\n\r\n //Password input initial for sheet Protection\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-protection-sheet-validation\", \r\n \"addclass\": \"luckysheet-protection-sheet-validation\", \r\n \"title\": local_protection.validationTitle, \r\n \"content\": `\r\n
\r\n
\r\n ${local_protection.validationTips}\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n `, \r\n \"botton\": `\r\n `, \r\n \"style\": \"z-index:100003\" \r\n }));\r\n\r\n}\r\n\r\n\r\nfunction restoreProtectionConfig(aut){\r\n if(aut==null){\r\n aut = {};\r\n }\r\n for(let i=0;i0){\r\n if(aut.algorithmName==\"None\" || aut.algorithmName==null){\r\n $(\"#protection-password\").val(aut.password);\r\n }\r\n else{\r\n $(\"#protection-password\").val(\"••••••••\");\r\n }\r\n }\r\n else{\r\n $(\"#protection-password\").val(\"\");\r\n }\r\n\r\n let sheet = aut.sheet;\r\n if(aut.sheet==null){\r\n sheet = 0;\r\n }\r\n $(\"#protection-swichProtectionState\").prop('checked',sheet==1?true:false);\r\n\r\n let hintText = aut.hintText;\r\n if(hintText==null){\r\n hintText = \"\";\r\n }\r\n $(\"#protection-hint\").val(hintText);\r\n\r\n\r\n rangeItemListCache = [];\r\n $(\"#luckysheet-protection-rangeItem-container\").empty();\r\n let allowRangeList = aut.allowRangeList;\r\n if(allowRangeList!=null && allowRangeList.length>0){\r\n for(let i=0;i0){\r\n validationAuthority = aut;\r\n $(\"#luckysheet-protection-sheet-validation input\").val(\"\");\r\n openSelfModel(\"luckysheet-protection-sheet-validation\");\r\n return;\r\n }\r\n else{//retore protection config\r\n restoreProtectionConfig(aut);\r\n }\r\n }\r\n else{//protection initial config\r\n $(\"#luckysheet-protection-check-selectLockedCells\").prop('checked',true);\r\n $(\"#luckysheet-protection-check-selectunLockedCells\").prop('checked',true);\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-slider-protection\").show();\r\n luckysheetsizeauto();\r\n\r\n}\r\n\r\nexport function closeProtectionModal(){\r\n $(\"#luckysheet-protection-rangeItem-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-protection\").hide();\r\n luckysheetsizeauto();\r\n}\r\n\r\n\r\n\r\n\r\nfunction checkProtectionLockedSqref(r, c, aut, local_protection, isOpenAlert=true){\r\n let isPass = false;\r\n let rangeAut = aut.allowRangeList;\r\n if(rangeAut!=null && rangeAut.length>0){\r\n let isExists = false;\r\n for(let i=0;i 0){\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n if(r>=r1 && r<=r2 && c>=c1 && c<=c2){\r\n isExists = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(isExists){\r\n\r\n let password = ra.password;\r\n if(password!=null && password.length>0 && !(sqref in inputRangeProtectionPassword)){\r\n if(isOpenAlert){\r\n openRangePasswordModal(ra);\r\n $(\"#luckysheet-selection-copy .luckysheet-selection-copy\").hide();\r\n }\r\n return false;\r\n }\r\n else{\r\n isPass = true;\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(!isPass && isOpenAlert){\r\n let ht;\r\n if(aut.hintText != null && aut.hintText.length>0){\r\n ht = aut.hintText;\r\n }\r\n else{\r\n ht = local_protection.defaultSheetHintText;\r\n }\r\n tooltip.info(\"\", ht);\r\n $(\"#luckysheet-selection-copy .luckysheet-selection-copy\").hide();\r\n }\r\n \r\n return isPass;\r\n}\r\n\r\n\r\nfunction openRangePasswordModal(rangeAut) {\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n const locale_button = _locale.button;\r\n \r\n if(!initialRangePasswordHtml){\r\n //Password input initial for range\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-protection-range-validation\", \r\n \"addclass\": \"luckysheet-protection-sheet-validation\", \r\n \"title\": local_protection.validationTitle, \r\n \"content\": `\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n `, \r\n \"botton\": `\r\n `, \r\n \"style\": \"z-index:100003\" \r\n }));\r\n }\r\n\r\n initialRangePasswordHtml = true;\r\n\r\n\r\n \r\n openSelfModel(\"luckysheet-protection-range-validation\");\r\n\r\n let $hint = $(\"#luckysheet-protection-range-validation-hint\");\r\n if(rangeAut.hintText != null && rangeAut.hintText.length>0){\r\n $hint.html(rangeAut.hintText);\r\n }\r\n else{\r\n $hint.html(local_protection.defaultRangeHintText);\r\n }\r\n let $rangeV = $(\"#luckysheet-protection-range-validation\");\r\n let $input = $rangeV.find(\"input\");\r\n $input.val(\"\");\r\n\r\n $(\"#luckysheet-protection-range-validation-confirm\").off(\"click\").on(\"click\", function(){\r\n let password = $input.val();\r\n\r\n if(password==null || password.length==0){\r\n alert(local_protection.checkPasswordNullalert);\r\n return;\r\n }\r\n\r\n if(rangeAut.algorithmName!=null && rangeAut.algorithmName!=\"None\"){\r\n // password = CryptoApi.hash(rangeAut.algorithmName, password);\r\n if(rangeAut.saltValue!=null && rangeAut.saltValue.length>0){\r\n var hasher = CryptoApi.getHasher(rangeAut.algorithmName);\r\n password =CryptoApi.hmac(rangeAut.saltValue, password, hasher);\r\n }\r\n else{\r\n password = CryptoApi.hash(rangeAut.algorithmName, password);\r\n }\r\n }\r\n\r\n if(password==rangeAut.password){\r\n inputRangeProtectionPassword[rangeAut.sqref] = 1;\r\n $rangeV.hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n alert(local_protection.checkPasswordSucceedalert);\r\n }\r\n else{\r\n alert(local_protection.checkPasswordWrongalert);\r\n }\r\n\r\n });\r\n \r\n}\r\n\r\n//protection state\r\nexport function checkProtectionNotEnable(sheetIndex){\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(sheetFile==null){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n\r\n let ht;\r\n if(aut.hintText != null && aut.hintText.length>0){\r\n ht = aut.hintText;\r\n }\r\n else{\r\n ht = local_protection.defaultSheetHintText;\r\n }\r\n tooltip.info(\"\", ht);\r\n\r\n return false;\r\n}\r\n\r\n//cell locked state\r\nexport function checkProtectionLocked(r, c, sheetIndex){\r\n\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(sheetFile==null){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let data=sheetFile.data, cell=data[r][c], aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n if(cell && !cell.lo){\r\n return true;\r\n }\r\n\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n\r\n return checkProtectionLockedSqref(r, c , aut, local_protection);\r\n}\r\n\r\n//cell hidden state\r\nexport function checkProtectionCellHidden(r, c, sheetIndex){\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(!sheetFile || !sheetFile.data[r] || !sheetFile.data[r][c]){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let data=sheetFile.data, cell=data[r][c], aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n if(cell==null || cell.hi==null || cell.hi==0){\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n//cell range locked state\r\nexport function checkProtectionLockedRangeList(rangeList, sheetIndex){\r\n //EPM-BUDGET-START\r\n if (rangeList[0].column[0] !== rangeList[0].column[1]) return true\r\n //EPM-BUDGET-END\r\n\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(sheetFile==null){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n if(rangeList==null || rangeList.length==0){\r\n return true;\r\n }\r\n\r\n //EPM-BUDGET-START\r\n let cell = sheetFile.data[rangeList[0].row[0]][rangeList[0].column[0]]\r\n if(cell&& !cell.lo){\r\n return true;\r\n }\r\n //EPM-BUDGET-END\r\n\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n\r\n for(let s = 0; s < rangeList.length; s++){\r\n let r1 = rangeList[s].row[0], r2 = rangeList[s].row[1];\r\n let c1 = rangeList[s].column[0], c2 = rangeList[s].column[1];\r\n\r\n for(let r=r1;r<=r2;r++){\r\n for(let c=c1;c<=c2;c++){\r\n let isPass = checkProtectionLockedSqref(r, c , aut, local_protection);\r\n if(isPass==false){\r\n return false;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n//selectLockedCells , selectunLockedCells and cell state\r\nexport function checkProtectionSelectLockedOrUnLockedCells(r, c, sheetIndex){\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(sheetFile==null){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let data=sheetFile.data, cell=data[r][c], aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n if(cell && !cell.lo){//unlocked\r\n if(aut.selectunLockedCells==1 || aut.selectunLockedCells==null){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n else{//locked??\r\n let isAllEdit = checkProtectionLockedSqref(r, c , aut, local_protection, false);//dont alert password model\r\n if(isAllEdit){//unlocked\r\n if(aut.selectunLockedCells==1 || aut.selectunLockedCells==null){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n else{//locked\r\n if(aut.selectLockedCells==1 || aut.selectLockedCells==null){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n \r\n}\r\n\r\n\r\n\r\n//selectLockedCells or selectunLockedCells authority, highlight cell \r\nexport function checkProtectionAllSelected(sheetIndex){\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(sheetFile==null){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n let selectunLockedCells = false;\r\n if(aut.selectunLockedCells==1 || aut.selectunLockedCells==null){\r\n selectunLockedCells = true;\r\n }\r\n\r\n let selectLockedCells = false;\r\n if(aut.selectLockedCells==1 || aut.selectLockedCells==null){\r\n selectLockedCells = true;\r\n }\r\n\r\n if(selectunLockedCells && selectLockedCells){\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n//formatCells authority, bl cl fc fz ff ct border etc.\r\nexport function checkProtectionFormatCells(sheetIndex){\r\n\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(sheetFile==null){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n if(aut.formatCells==1 || aut.formatCells==null){\r\n return true;\r\n }\r\n\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n\r\n let ht;\r\n if(aut.hintText != null && aut.hintText.length>0){\r\n ht = aut.hintText;\r\n }\r\n else{\r\n ht = local_protection.defaultSheetHintText;\r\n }\r\n tooltip.info(\"\", ht);\r\n\r\n return false;\r\n}\r\n\r\n//formatColumns authority: controll column hidden and width\r\n//formatRows authority: controll row hidden and height\r\n//insertColumns authority\r\n//insertRows authority\r\n//insertHyperlinks authority:Hyperlinks is not incomplete\r\n//deleteColumns authority\r\n//deleteRows authority\r\n//sort authority\r\n//filter authority\r\n//usePivotTablereports authority\r\n//editObjects authority: insert,delete,update for image, chart, comment,shape etc. \r\n//editScenarios authority: Scenarios features is uncompleted\r\n\r\nexport function checkProtectionAuthorityNormal(sheetIndex, type=\"formatColumns\", isAlert=true){\r\n\r\n let sheetFile = sheetmanage.getSheetByIndex(sheetIndex);\r\n if(sheetFile==null){\r\n return true;\r\n }\r\n\r\n if(sheetFile.config==null || sheetFile.config.authority==null){\r\n return true;\r\n }\r\n\r\n let aut = sheetFile.config.authority;\r\n\r\n if(aut==null || aut.sheet==null || aut.sheet==0 ){\r\n return true;\r\n }\r\n\r\n if(aut[type]==1 || aut[type]==null){\r\n return true;\r\n }\r\n\r\n if(isAlert){\r\n const _locale = locale();\r\n const local_protection = _locale.protection;\r\n \r\n let ht;\r\n if(aut.hintText != null && aut.hintText.length>0){\r\n ht = aut.hintText;\r\n }\r\n else{\r\n ht = local_protection.defaultSheetHintText;\r\n }\r\n tooltip.info(\"\", ht);\r\n }\r\n\r\n return false;\r\n}","import { columeHeader_word, columeHeader_word_index, luckysheetdefaultFont } from '../controllers/constant';\r\nimport menuButton from '../controllers/menuButton';\r\nimport { isdatatype, isdatatypemulti } from '../global/datecontroll';\r\nimport { hasChinaword,isRealNum } from '../global/validate';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport numeral from 'numeral';\r\n// import method from '../global/method';\r\n\r\n/**\r\n * Common tool methods\r\n */\r\n\r\n/**\r\n * Determine whether a string is in standard JSON format\r\n * @param {String} str \r\n */\r\nfunction isJsonString(str) {\r\n try {\r\n if (typeof JSON.parse(str) == \"object\") {\r\n return true;\r\n }\r\n }\r\n catch (e) { }\r\n return false;\r\n}\r\n\r\n\r\n/**\r\n * extend two objects\r\n * @param {Object } jsonbject1\r\n * @param {Object } jsonbject2 \r\n */\r\nfunction common_extend(jsonbject1, jsonbject2) {\r\n let resultJsonObject = {};\r\n\r\n for (let attr in jsonbject1) {\r\n resultJsonObject[attr] = jsonbject1[attr];\r\n }\r\n\r\n for (let attr in jsonbject2) {\r\n // undefined is equivalent to no setting\r\n if(jsonbject2[attr] == undefined){\r\n continue;\r\n }\r\n resultJsonObject[attr] = jsonbject2[attr];\r\n }\r\n\r\n return resultJsonObject;\r\n};\r\n\r\n// 替换temp中的${xxx}为指定内容 ,temp:字符串,这里指html代码,dataarry:一个对象{\"xxx\":\"替换的内容\"}\r\n// 例:luckysheet.replaceHtml(\"${image}\",{\"image\":\"abc\",\"jskdjslf\":\"abc\"}) ==> abc\r\nfunction replaceHtml(temp, dataarry) {\r\n return temp.replace(/\\$\\{([\\w]+)\\}/g, function (s1, s2) { let s = dataarry[s2]; if (typeof (s) != \"undefined\") { return s; } else { return s1; } });\r\n};\r\n\r\n//获取数据类型\r\nfunction getObjType(obj) {\r\n let toString = Object.prototype.toString;\r\n\r\n let map = {\r\n '[object Boolean]': 'boolean',\r\n '[object Number]': 'number',\r\n '[object String]': 'string',\r\n '[object Function]': 'function',\r\n '[object Array]': 'array',\r\n '[object Date]': 'date',\r\n '[object RegExp]': 'regExp',\r\n '[object Undefined]': 'undefined',\r\n '[object Null]': 'null',\r\n '[object Object]': 'object'\r\n }\r\n\r\n // if(obj instanceof Element){\r\n // return 'element';\r\n // }\r\n\r\n return map[toString.call(obj)];\r\n}\r\n\r\n//获取当前日期时间\r\nfunction getNowDateTime(format) {\r\n let now = new Date();\r\n let year = now.getFullYear(); //得到年份\r\n let month = now.getMonth(); //得到月份\r\n let date = now.getDate(); //得到日期\r\n let day = now.getDay(); //得到周几\r\n let hour = now.getHours(); //得到小时\r\n let minu = now.getMinutes(); //得到分钟\r\n let sec = now.getSeconds(); //得到秒\r\n\r\n month = month + 1;\r\n if (month < 10) month = \"0\" + month;\r\n if (date < 10) date = \"0\" + date;\r\n if (hour < 10) hour = \"0\" + hour;\r\n if (minu < 10) minu = \"0\" + minu;\r\n if (sec < 10) sec = \"0\" + sec;\r\n\r\n let time = '';\r\n\r\n //日期\r\n if(format == 1) {\r\n time = year + \"-\" + month + \"-\" + date;\r\n }\r\n //日期时间\r\n else if(format == 2) {\r\n time = year + \"-\" + month + \"-\" + date+ \" \" + hour + \":\" + minu + \":\" + sec;\r\n }\r\n\r\n return time;\r\n}\r\n\r\n//颜色 16进制转rgb\r\nfunction hexToRgb(hex) {\r\n let color = [], rgb = [];\r\n hex = hex.replace(/#/, \"\");\r\n\r\n if (hex.length == 3) { // 处理 \"#abc\" 成 \"#aabbcc\"\r\n let tmp = [];\r\n\r\n for (let i = 0; i < 3; i++) {\r\n tmp.push(hex.charAt(i) + hex.charAt(i));\r\n }\r\n\r\n hex = tmp.join(\"\");\r\n }\r\n\r\n for (let i = 0; i < 3; i++) {\r\n color[i] = \"0x\" + hex.substr(i + 2, 2);\r\n rgb.push(parseInt(Number(color[i])));\r\n }\r\n\r\n return 'rgb(' + rgb.join(\",\") + ')';\r\n};\r\n\r\n//颜色 rgb转16进制\r\nfunction rgbTohex(color) {\r\n let rgb;\r\n\r\n if (color.indexOf(\"rgba\") > -1) {\r\n rgb = color.replace(\"rgba(\", \"\").replace(\")\", \"\").split(',');\r\n }\r\n else {\r\n rgb = color.replace(\"rgb(\", \"\").replace(\")\", \"\").split(',');\r\n }\r\n\r\n let r = parseInt(rgb[0]);\r\n let g = parseInt(rgb[1]);\r\n let b = parseInt(rgb[2]);\r\n\r\n let hex = \"#\" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);\r\n\r\n return hex;\r\n};\r\n\r\n//列下标 字母转数字\r\nfunction ABCatNum(a) {\r\n // abc = abc.toUpperCase();\r\n\r\n // let abc_len = abc.length;\r\n // if (abc_len == 0) {\r\n // return NaN;\r\n // }\r\n\r\n // let abc_array = abc.split(\"\");\r\n // let wordlen = columeHeader_word.length;\r\n // let ret = 0;\r\n\r\n // for (let i = abc_len - 1; i >= 0; i--) {\r\n // if (i == abc_len - 1) {\r\n // ret += columeHeader_word_index[abc_array[i]];\r\n // }\r\n // else {\r\n // ret += Math.pow(wordlen, abc_len - i - 1) * (columeHeader_word_index[abc_array[i]] + 1);\r\n // }\r\n // }\r\n\r\n // return ret;\r\n if(a==null || a.length==0){\r\n return NaN;\r\n }\r\n var str=a.toLowerCase().split(\"\");\r\n var num=0;\r\n var al = str.length;\r\n var getCharNumber = function(charx){\r\n return charx.charCodeAt() -96;\r\n };\r\n var numout = 0;\r\n var charnum = 0;\r\n for(var i = 0; i < al; i++){\r\n charnum = getCharNumber(str[i]);\r\n numout += charnum * Math.pow(26, al-i-1);\r\n };\r\n // console.log(a, numout-1);\r\n if(numout==0){\r\n return NaN;\r\n }\r\n return numout-1;\r\n};\r\n\r\n//列下标 数字转字母\r\nfunction chatatABC(n) {\r\n // let wordlen = columeHeader_word.length;\r\n\r\n // if (index < wordlen) {\r\n // return columeHeader_word[index];\r\n // }\r\n // else {\r\n // let last = 0, pre = 0, ret = \"\";\r\n // let i = 1, n = 0;\r\n\r\n // while (index >= (wordlen / (wordlen - 1)) * (Math.pow(wordlen, i++) - 1)) {\r\n // n = i;\r\n // }\r\n\r\n // let index_ab = index - (wordlen / (wordlen - 1)) * (Math.pow(wordlen, n - 1) - 1);//970\r\n // last = index_ab + 1;\r\n\r\n // for (let x = n; x > 0; x--) {\r\n // let last1 = last, x1 = x;//-702=268, 3\r\n\r\n // if (x == 1) {\r\n // last1 = last1 % wordlen;\r\n\r\n // if (last1 == 0) {\r\n // last1 = 26;\r\n // }\r\n\r\n // return ret + columeHeader_word[last1 - 1];\r\n // }\r\n\r\n // last1 = Math.ceil(last1 / Math.pow(wordlen, x - 1));\r\n // //last1 = last1 % wordlen;\r\n // ret += columeHeader_word[last1 - 1];\r\n\r\n // if (x > 1) {\r\n // last = last - (last1 - 1) * wordlen;\r\n // }\r\n // }\r\n // }\r\n\r\n var orda = 'a'.charCodeAt(0); \r\n \r\n var ordz = 'z'.charCodeAt(0); \r\n \r\n var len = ordz - orda + 1; \r\n \r\n var s = \"\"; \r\n \r\n while( n >= 0 ) { \r\n \r\n s = String.fromCharCode(n % len + orda) + s; \r\n \r\n n = Math.floor(n / len) - 1; \r\n \r\n } \r\n \r\n return s.toUpperCase(); \r\n};\r\n\r\nfunction ceateABC(index) {\r\n let wordlen = columeHeader_word.length;\r\n\r\n if (index < wordlen) {\r\n return columeHeader_word;\r\n }\r\n else {\r\n let relist = [];\r\n let i = 2, n = 0;\r\n\r\n while (index < (wordlen / (wordlen - 1)) * (Math.pow(wordlen, i) - 1)) {\r\n n = i;\r\n i++;\r\n }\r\n\r\n for (let x = 0; x < n; x++) {\r\n\r\n if (x == 0) {\r\n relist = relist.concat(columeHeader_word);\r\n }\r\n else {\r\n relist = relist.concat(createABCdim(x), index);\r\n }\r\n }\r\n }\r\n};\r\n\r\nfunction createABCdim(x, count) {\r\n let chwl = columeHeader_word.length;\r\n\r\n if (x == 1) {\r\n let ret = [];\r\n let c = 0, con = true;\r\n\r\n for (let i = 0; i < chwl; i++) {\r\n let b = columeHeader_word[i];\r\n\r\n for (let n = 0; n < chwl; n++) {\r\n let bq = b + columeHeader_word[n];\r\n ret.push(bq);\r\n c++;\r\n\r\n if (c > index) {\r\n return ret;\r\n }\r\n }\r\n }\r\n }\r\n else if (x == 2) {\r\n let ret = [];\r\n let c = 0, con = true;\r\n\r\n for (let i = 0; i < chwl; i++) {\r\n let bb = columeHeader_word[i];\r\n\r\n for (let w = 0; w < chwl; w++) {\r\n let aa = columeHeader_word[w];\r\n\r\n for (let n = 0; n < chwl; n++) {\r\n let bqa = bb + aa + columeHeader_word[n];\r\n ret.push(bqa);\r\n c++;\r\n\r\n if (c > index) {\r\n return ret;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n};\r\n\r\n/**\r\n * 计算字符串字节长度\r\n * @param {*} val 字符串\r\n * @param {*} subLen 要截取的字符串长度\r\n */\r\nfunction getByteLen(val,subLen) {\r\n if(subLen === 0){\r\n return \"\";\r\n }\r\n\r\n if (val == null) {\r\n return 0;\r\n }\r\n\r\n let len = 0;\r\n for (let i = 0; i < val.length; i++) {\r\n let a = val.charAt(i);\r\n\r\n if (a.match(/[^\\x00-\\xff]/ig) != null) {\r\n len += 2;\r\n }\r\n else {\r\n len += 1;\r\n }\r\n\r\n if(isRealNum(subLen) && len === ~~subLen){\r\n return val.substring(0,i)\r\n }\r\n\r\n }\r\n\r\n return len;\r\n};\r\n\r\n//数组去重\r\nfunction ArrayUnique(dataArr) {\r\n let result = [];\r\n let obj = {};\r\n if (dataArr.length > 0) {\r\n for (let i = 0; i < dataArr.length; i++) {\r\n let item = dataArr[i];\r\n if (!obj[item]) {\r\n result.push(item);\r\n obj[item] = 1;\r\n }\r\n }\r\n }\r\n return result\r\n}\r\n\r\n//获取字体配置\r\nfunction luckysheetfontformat(format) {\r\n let fontarray = locale().fontarray;\r\n if (getObjType(format) == \"object\") {\r\n let font = \"\";\r\n\r\n //font-style\r\n if (format.it == \"0\" || format.it == null) {\r\n font += \"normal \";\r\n }\r\n else {\r\n font += \"italic \";\r\n }\r\n\r\n //font-variant\r\n font += \"normal \";\r\n\r\n //font-weight\r\n if (format.bl == \"0\" || format.bl == null) {\r\n font += \"normal \";\r\n }\r\n else {\r\n font += \"bold \";\r\n }\r\n\r\n //font-size/line-height\r\n if (!format.fs) {\r\n font += Store.defaultFontSize + \"pt \";\r\n }\r\n else {\r\n font += Math.ceil(format.fs) + \"pt \";\r\n }\r\n\r\n if (!format.ff) {\r\n \r\n font += fontarray[0] + ', \"Helvetica Neue\", Helvetica, Arial, \"PingFang SC\", \"Hiragino Sans GB\", \"Heiti SC\", \"Microsoft YaHei\", \"WenQuanYi Micro Hei\", sans-serif';\r\n }\r\n else {\r\n let fontfamily = null;\r\n let fontjson = locale().fontjson;\r\n if (isdatatypemulti(format.ff)[\"num\"]) {\r\n fontfamily = fontarray[parseInt(format.ff)];\r\n }\r\n else {\r\n\r\n // fontfamily = fontarray[fontjson[format.ff]];\r\n fontfamily = format.ff;\r\n\r\n fontfamily = fontfamily.replace(/\"/g, \"\").replace(/'/g, \"\");\r\n\r\n if(fontfamily.indexOf(\" \")>-1){\r\n fontfamily = '\"' + fontfamily + '\"';\r\n }\r\n\r\n if(fontfamily!=null && document.fonts && !document.fonts.check(\"12px \"+fontfamily)){\r\n menuButton.addFontTolist(fontfamily);\r\n }\r\n }\r\n\r\n if (fontfamily == null) {\r\n fontfamily = fontarray[0];\r\n }\r\n\r\n font += fontfamily + ', \"Helvetica Neue\", Helvetica, Arial, \"PingFang SC\", \"Hiragino Sans GB\", \"Heiti SC\", \"Microsoft YaHei\", \"WenQuanYi Micro Hei\", sans-serif';\r\n }\r\n\r\n return font;\r\n }\r\n else {\r\n return luckysheetdefaultFont();\r\n }\r\n}\r\n\r\n//右键菜单\r\nfunction showrightclickmenu($menu, x, y) {\r\n let winH = $(window).height(), winW = $(window).width();\r\n let menuW = $menu.width(), menuH = $menu.height();\r\n let top = y, left = x;\r\n\r\n if (x + menuW > winW) {\r\n left = x - menuW;\r\n }\r\n\r\n if (y + menuH > winH) {\r\n top = y - menuH;\r\n }\r\n\r\n if (top < 0) {\r\n top = 0;\r\n }\r\n\r\n $menu.css({ \"top\": top, \"left\": left }).show();\r\n}\r\n\r\n//单元格编辑聚焦\r\nfunction luckysheetactiveCell() {\r\n if (!!Store.fullscreenmode) {\r\n setTimeout(function () {\r\n $(\"#luckysheet-rich-text-editor\").focus().select();\r\n }, 50);\r\n }\r\n}\r\n\r\n//单元格编辑聚焦\r\nfunction luckysheetContainerFocus() {\r\n // $(\"#\" + Store.container).focus({ \r\n // preventScroll: true \r\n // });\r\n \r\n // fix jquery error: Uncaught TypeError: ((n.event.special[g.origType] || {}).handle || g.handler).apply is not a function\r\n\r\n $(\"#\" + Store.container).attr(\"tabindex\", 0).focus();\r\n}\r\n\r\n//数字格式\r\nfunction numFormat(num, type) {\r\n if (num == null || isNaN(parseFloat(num)) || hasChinaword(num) || num == -Infinity || num == Infinity) {\r\n return null;\r\n }\r\n\r\n let floatlen = 6, ismustfloat = false;\r\n if (type == null || type == \"auto\") {\r\n if (num < 1) {\r\n floatlen = 6;\r\n }\r\n else {\r\n floatlen = 1;\r\n }\r\n }\r\n else {\r\n if (isdatatype(type) == \"num\") {\r\n floatlen = parseInt(type);\r\n ismustfloat = true;\r\n }\r\n else {\r\n floatlen = 6;\r\n }\r\n }\r\n\r\n let format = \"\", value = null;\r\n for (let i = 0; i < floatlen; i++) {\r\n format += \"0\";\r\n }\r\n\r\n if (!ismustfloat) {\r\n format = \"[\" + format + \"]\";\r\n }\r\n\r\n if (num >= 1e+21) {\r\n value = parseFloat(numeral(num).value());\r\n }\r\n else {\r\n value = parseFloat(numeral(num).format(\"0.\" + format));\r\n }\r\n\r\n return value;\r\n}\r\n\r\nfunction numfloatlen(n) {\r\n if (n != null && !isNaN(parseFloat(n)) && !hasChinaword(n)) {\r\n let value = numeral(n).value();\r\n let lens = value.toString().split(\".\");\r\n\r\n if (lens.length == 1) {\r\n lens = 0;\r\n }\r\n else {\r\n lens = lens[1].length;\r\n }\r\n\r\n return lens;\r\n }\r\n else {\r\n return null;\r\n }\r\n}\r\n\r\n//二级菜单显示位置\r\nfunction mouseclickposition($menu, x, y, p) {\r\n let winH = $(window).height(), winW = $(window).width();\r\n let menuW = $menu.width(), menuH = $menu.height();\r\n let top = y, left = x;\r\n\r\n if (p == null) {\r\n p = \"lefttop\";\r\n }\r\n\r\n if (p == \"lefttop\") {\r\n $menu.css({ \"top\": y, \"left\": x }).show();\r\n }\r\n else if (p == \"righttop\") {\r\n $menu.css({ \"top\": y, \"left\": x - menuW }).show();\r\n }\r\n else if (p == \"leftbottom\") {\r\n $menu.css({ \"bottom\": winH - y - 12, \"left\": x }).show();\r\n }\r\n else if (p == \"rightbottom\") {\r\n $menu.css({ \"bottom\": winH - y - 12, \"left\": x - menuW }).show();\r\n }\r\n}\r\n\r\n/**\r\n * 元素选择器\r\n * @param {String} selector css选择器\r\n * @param {String} context 指定父级DOM\r\n */\r\nfunction $$(selector, context) {\r\n context = context || document\r\n var elements = context.querySelectorAll(selector)\r\n return elements.length == 1\r\n ? Array.prototype.slice.call(elements)[0]\r\n : Array.prototype.slice.call(elements)\r\n}\r\n\r\n/** \r\n * 串行加载指定的脚本\r\n * 串行加载[异步]逐个加载,每个加载完成后加载下一个\r\n * 全部加载完成后执行回调\r\n * @param {Array|String} scripts 指定要加载的脚本\r\n * @param {Object} options 属性设置\r\n * @param {Function} callback 成功后回调的函数\r\n * @return {Array} 所有生成的脚本元素对象数组\r\n */\r\n\r\nfunction seriesLoadScripts(scripts, options, callback) {\r\n if (typeof (scripts) !== 'object') {\r\n var scripts = [scripts];\r\n }\r\n var HEAD = document.getElementsByTagName('head')[0] || document.documentElement;\r\n var s = [];\r\n var last = scripts.length - 1;\r\n //递归\r\n var recursiveLoad = function (i) {\r\n s[i] = document.createElement('script');\r\n s[i].setAttribute('type', 'text/javascript');\r\n // Attach handlers for all browsers\r\n // 异步\r\n s[i].onload = s[i].onreadystatechange = function () {\r\n if (!/*@cc_on!@*/0 || this.readyState === 'loaded' || this.readyState === 'complete') {\r\n this.onload = this.onreadystatechange = null;\r\n this.parentNode.removeChild(this);\r\n if (i !== last) {\r\n recursiveLoad(i + 1);\r\n } else if (typeof (callback) === 'function') {\r\n callback()\r\n };\r\n }\r\n }\r\n // 同步\r\n s[i].setAttribute('src', scripts[i]);\r\n\r\n // 设置属性\r\n if (typeof options === 'object') {\r\n for (var attr in options) {\r\n s[i].setAttribute(attr, options[attr]);\r\n }\r\n }\r\n\r\n HEAD.appendChild(s[i]);\r\n };\r\n recursiveLoad(0);\r\n}\r\n\r\n\r\n/**\r\n * 并行加载指定的脚本\r\n * 并行加载[同步]同时加载,不管上个是否加载完成,直接加载全部\r\n * 全部加载完成后执行回调\r\n * @param {Array|String} scripts 指定要加载的脚本\r\n * @param {Object} options 属性设置\r\n * @param {Function} callback 成功后回调的函数\r\n * @return {Array} 所有生成的脚本元素对象数组\r\n */\r\n\r\nfunction parallelLoadScripts(scripts, options, callback) {\r\n if (typeof (scripts) !== 'object') {\r\n var scripts = [scripts];\r\n }\r\n var HEAD = document.getElementsByTagName('head')[0] || document.documentElement;\r\n var s = [];\r\n var loaded = 0;\r\n for (var i = 0; i < scripts.length; i++) {\r\n s[i] = document.createElement('script');\r\n s[i].setAttribute('type', 'text/javascript');\r\n // Attach handlers for all browsers\r\n // 异步\r\n s[i].onload = s[i].onreadystatechange = function () {\r\n if (!/*@cc_on!@*/0 || this.readyState === 'loaded' || this.readyState === 'complete') {\r\n loaded++;\r\n this.onload = this.onreadystatechange = null;\r\n this.parentNode.removeChild(this);\r\n if (loaded === scripts.length && typeof (callback) === 'function') callback();\r\n }\r\n };\r\n // 同步\r\n s[i].setAttribute('src', scripts[i]);\r\n\r\n // 设置属性\r\n if (typeof options === 'object') {\r\n for (var attr in options) {\r\n s[i].setAttribute(attr, options[attr]);\r\n }\r\n }\r\n\r\n HEAD.appendChild(s[i]);\r\n }\r\n}\r\n\r\n/**\r\n* 动态添加css\r\n* @param {String} url 指定要加载的css地址\r\n*/\r\nfunction loadLink(url) {\r\n var doc = document;\r\n var link = doc.createElement(\"link\");\r\n link.setAttribute(\"rel\", \"stylesheet\");\r\n link.setAttribute(\"type\", \"text/css\");\r\n link.setAttribute(\"href\", url);\r\n\r\n var heads = doc.getElementsByTagName(\"head\");\r\n if (heads.length) {\r\n heads[0].appendChild(link);\r\n }\r\n else {\r\n doc.documentElement.appendChild(link);\r\n }\r\n}\r\n\r\n/**\r\n* 动态添加一组css\r\n* @param {String} url 指定要加载的css地址\r\n*/\r\nfunction loadLinks(urls) {\r\n if (typeof (urls) !== 'object') {\r\n urls = [urls];\r\n }\r\n if (urls.length) {\r\n urls.forEach(url => {\r\n loadLink(url);\r\n });\r\n }\r\n}\r\n\r\nfunction transformRangeToAbsolute(txt1){\r\n if(txt1 ==null ||txt1.length==0){\r\n return null;\r\n }\r\n\r\n let txtArray = txt1.split(\",\");\r\n let ret = \"\";\r\n for(let i=0;i1){\r\n sheetName = txtSplit[0];\r\n rangeTxt = txtSplit[1];\r\n }\r\n else{\r\n rangeTxt = txtSplit[0];\r\n }\r\n\r\n let rangeTxtArray = rangeTxt.split(\":\");\r\n\r\n let rangeRet = \"\";\r\n for(let a=0;a {\r\n// if (typeof data === 'object' && data.toString() === '[object Object]') {\r\n// for (let k in data) {\r\n// if(list.includes(k)){\r\n// if (typeof data[k] === 'object') {\r\n// defineObjectReactive(data, k, data[k])\r\n// } else {\r\n// defineBasicReactive(data, k, data[k])\r\n// }\r\n// }\r\n// }\r\n// }\r\n// }\r\n\r\nconst createProxy = (data, k, callback) => {\r\n if(!data.hasOwnProperty(k)){ \r\n console.info('No %s in data',k);\r\n return; \r\n };\r\n\r\n if (getObjType(data) === 'object') {\r\n if (getObjType(data[k]) === 'object' || getObjType(data[k]) === 'array') {\r\n defineObjectReactive(data, k, data[k], callback)\r\n } else {\r\n defineBasicReactive(data, k, data[k], callback)\r\n }\r\n }\r\n}\r\n \r\nfunction defineObjectReactive(obj, key, value, callback) {\r\n // 递归\r\n obj[key] = new Proxy(value, {\r\n set(target, property, val, receiver) {\r\n \r\n setTimeout(() => {\r\n callback(target, property, val, receiver);\r\n }, 0);\r\n\r\n return Reflect.set(target, property, val, receiver)\r\n }\r\n })\r\n}\r\n \r\nfunction defineBasicReactive(obj, key, value, callback) {\r\n Object.defineProperty(obj, key, {\r\n enumerable: true,\r\n configurable: false,\r\n get() {\r\n return value\r\n },\r\n set(newValue) {\r\n if (value === newValue) return\r\n console.log(`发现 ${key} 属性 ${value} -> ${newValue}`)\r\n\r\n setTimeout(() => {\r\n callback(value,newValue);\r\n }, 0);\r\n\r\n value = newValue\r\n\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * Remove an item in the specified array\r\n * @param {array} array Target array \r\n * @param {string} item What needs to be removed\r\n */\r\nfunction arrayRemoveItem(array, item) {\r\n array.some((curr, index, arr)=>{\r\n if(curr === item){\r\n arr.splice(index, 1);\r\n return curr === item;\r\n }\r\n })\r\n}\r\n\r\n \r\nexport {\r\n isJsonString,\r\n common_extend,\r\n replaceHtml,\r\n getObjType,\r\n getNowDateTime,\r\n hexToRgb,\r\n rgbTohex,\r\n ABCatNum,\r\n chatatABC,\r\n ceateABC,\r\n createABCdim,\r\n getByteLen,\r\n ArrayUnique,\r\n luckysheetfontformat,\r\n showrightclickmenu,\r\n luckysheetactiveCell,\r\n numFormat,\r\n numfloatlen,\r\n mouseclickposition,\r\n $$,\r\n seriesLoadScripts,\r\n parallelLoadScripts,\r\n loadLinks,\r\n luckysheetContainerFocus,\r\n transformRangeToAbsolute,\r\n openSelfModel,\r\n createProxy,\r\n arrayRemoveItem\r\n}","import { getObjType } from '../utils/util';\r\nimport { isRealNull, isRealNum, isEditMode } from './validate';\r\nimport { isdatetime, diff } from './datecontroll';\r\nimport tooltip from './tooltip';\r\nimport editor from './editor';\r\nimport { rowlenByRange } from './getRowlen';\r\nimport { jfrefreshgrid } from './refresh';\r\nimport {checkProtectionAuthorityNormal} from '../controllers/protection';\r\nimport Store from '../store';\r\nimport numeral from 'numeral';\r\n\r\n//数据排序方法\r\nfunction orderbydata(data, index, isAsc) {\r\n if (isAsc == null) {\r\n isAsc = true;\r\n }\r\n\r\n let a = function (x, y) {\r\n let x1 = x[index] , y1 = y[index];\r\n\r\n if(getObjType(x[index]) == \"object\"){\r\n x1 = x[index].v;\r\n }\r\n\r\n if(getObjType(y[index]) == \"object\"){\r\n y1 = y[index].v;\r\n }\r\n\r\n if(isRealNull(x1)){\r\n return 1;\r\n }\r\n\r\n if(isRealNull(y1)){\r\n return -1;\r\n }\r\n\r\n if (isdatetime(x1) && isdatetime(y1)) {\r\n return diff(x1, y1);\r\n }\r\n else if (isRealNum(x1) && isRealNum(y1)) {\r\n return numeral(x1).value() - numeral(y1).value();\r\n }\r\n else if (!isRealNum(x1) && !isRealNum(y1)) {\r\n return x1.localeCompare(y1, \"zh\");\r\n }\r\n else if (!isRealNum(x1)) {\r\n return 1;\r\n }\r\n else if (!isRealNum(y1)) {\r\n return -1;\r\n }\r\n }\r\n\r\n let d = function (x, y) {\r\n let x1 = x[index] , y1 = y[index];\r\n\r\n if(getObjType(x[index]) == \"object\"){\r\n x1 = x[index].v;\r\n }\r\n\r\n if(getObjType(y[index]) == \"object\"){\r\n y1 = y[index].v;\r\n }\r\n\r\n if(isRealNull(x1)){\r\n return 1;\r\n }\r\n\r\n if(isRealNull(y1)){\r\n return -1;\r\n }\r\n\r\n if (isdatetime(x1) && isdatetime(y1)) {\r\n return diff(y1, x1);\r\n }\r\n else if (isRealNum(x1) && isRealNum(y1)) {\r\n return numeral(y1).value() - numeral(x1).value();\r\n }\r\n else if (!isRealNum(x1) && !isRealNum(y1)) {\r\n return y1.localeCompare(x1, \"zh\");\r\n }\r\n else if (!isRealNum(x1)) {\r\n return -1;\r\n }\r\n else if (!isRealNum(y1)) {\r\n return 1;\r\n }\r\n }\r\n\r\n if (isAsc) {\r\n return data.sort(a);\r\n }\r\n else {\r\n return data.sort(d);\r\n }\r\n}\r\n\r\nfunction orderbydata1D(data, isAsc) {\r\n if (isAsc == null) {\r\n isAsc = true;\r\n }\r\n\r\n let a = function (x, y) {\r\n let x1 = x, y1 = y;\r\n\r\n if(getObjType(x) == \"object\"){\r\n x1 = x.v;\r\n }\r\n\r\n if(getObjType(y) == \"object\"){\r\n y1 = y.v;\r\n }\r\n\r\n if(x1 == null){\r\n x1 = \"\";\r\n }\r\n\r\n if(y1 == null){\r\n y1 = \"\";\r\n }\r\n\r\n if (isdatetime(x1) && isdatetime(y1)) {\r\n return diff(x1, y1);\r\n }\r\n else if (isRealNum(x1) && isRealNum(y1)) {\r\n return numeral(x1).value() - numeral(y1).value();\r\n }\r\n else if (!isRealNum(x1) && !isRealNum(y1)) {\r\n return x1.localeCompare(y1, \"zh\");\r\n }\r\n else if (!isRealNum(x1)) {\r\n return 1;\r\n }\r\n else if (!isRealNum(y1)) {\r\n return -1;\r\n }\r\n }\r\n\r\n let d = function (x, y) {\r\n let x1 = x, y1 = y;\r\n\r\n if(getObjType(x) == \"object\"){\r\n x1 = x.v;\r\n }\r\n\r\n if(getObjType(y) == \"object\"){\r\n y1 = y.v;\r\n }\r\n\r\n if(x1 == null){\r\n x1 = \"\";\r\n }\r\n\r\n if(y1 == null){\r\n y1 = \"\";\r\n }\r\n\r\n if (isdatetime(x1) && isdatetime(y1)) {\r\n return diff(y1, x1);\r\n }\r\n else if (isRealNum(x1) && isRealNum(y1)) {\r\n return numeral(y1).value() - numeral(x1).value();\r\n }\r\n else if (!isRealNum(x1) && !isRealNum(y1)) {\r\n return y1.localeCompare(x1, \"zh\");\r\n }\r\n else if (!isRealNum(x1)) {\r\n return -1;\r\n }\r\n else if (!isRealNum(y1)) {\r\n return 1;\r\n }\r\n }\r\n\r\n if (isAsc) {\r\n return data.sort(a);\r\n }\r\n else {\r\n return data.sort(d);\r\n }\r\n}\r\n\r\n//排序选区数据\r\nfunction sortSelection(isAsc) {\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"sort\")){\r\n return;\r\n }\r\n if(Store.luckysheet_select_save.length > 1){\r\n if(isEditMode()){\r\n alert(\"不能对多重选择区域执行此操作,请选择单个区域,然后再试\");\r\n }\r\n else{\r\n tooltip.info(\"不能对多重选择区域执行此操作,请选择单个区域,然后再试\", \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n if(isAsc == null){\r\n isAsc = true;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let r1 = Store.luckysheet_select_save[0].row[0], \r\n r2 = Store.luckysheet_select_save[0].row[1];\r\n let c1 = Store.luckysheet_select_save[0].column[0], \r\n c2 = Store.luckysheet_select_save[0].column[1];\r\n\r\n let str, edr;\r\n\r\n for(let r = r1; r <= r2; r++){\r\n if(d[r] != null && d[r][c1] != null){\r\n let cell = d[r][c1];\r\n\r\n if(cell.mc != null || isRealNull(cell.v)){\r\n continue;\r\n }\r\n\r\n if(str == null && /[\\u4e00-\\u9fa5]+/g.test(cell.v)){\r\n str = r + 1;\r\n edr = r + 1;\r\n continue;\r\n }\r\n \r\n if(str == null){\r\n str = r; \r\n }\r\n\r\n edr = r;\r\n }\r\n }\r\n\r\n if(str == null || str > r2){\r\n return;\r\n }\r\n\r\n let hasMc = false; //排序选区是否有合并单元格\r\n let data = [];\r\n\r\n for(let r = str; r <= edr; r++){\r\n let data_row = [];\r\n\r\n for(let c = c1; c <= c2; c++){\r\n if(d[r][c] != null && d[r][c].mc != null){\r\n hasMc = true;\r\n break;\r\n }\r\n\r\n data_row.push(d[r][c]);\r\n }\r\n\r\n data.push(data_row);\r\n }\r\n\r\n if(hasMc){\r\n if(isEditMode()){\r\n alert(\"选区有合并单元格,无法执行此操作!\");\r\n }\r\n else{\r\n tooltip.info(\"选区有合并单元格,无法执行此操作!\", \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n data = orderbydata(data, 0, isAsc);\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = c1; c <= c2; c++){\r\n d[r][c] = data[r - str][c - c1];\r\n }\r\n }\r\n\r\n let allParam = {};\r\n if(Store.config[\"rowlen\"] != null){\r\n let cfg = $.extend(true, {}, Store.config);\r\n cfg = rowlenByRange(d, str, edr, cfg);\r\n\r\n allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true\r\n }\r\n }\r\n\r\n jfrefreshgrid(d, [{ \"row\": [str, edr], \"column\": [c1, c2] }], allParam);\r\n}\r\n\r\n//排序一列数据\r\nfunction sortColumnSeletion(colIndex, isAsc) {\r\n if(!checkProtectionAuthorityNormal(Store.currentSheetIndex, \"sort\")){\r\n return;\r\n }\r\n if(isAsc == null){\r\n isAsc = true;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let r1 = 0, r2 = d.length - 1;\r\n let c1 = 0, c2 = d[0].length - 1;\r\n\r\n let str, edr;\r\n\r\n for(let r = r1; r <= r2; r++){\r\n if(d[r][colIndex] != null && d[r][colIndex].mc != null){\r\n continue;\r\n }\r\n\r\n if(d[r][colIndex] != null && !isRealNull(d[r][colIndex].v) && /[\\u4e00-\\u9fa5]+/g.test(d[r][colIndex].v) && str == null){\r\n str = r + 1;\r\n edr = r + 1;\r\n continue;\r\n }\r\n\r\n if(str == null){\r\n str = r; \r\n }\r\n\r\n if(d[r][colIndex] != null && !isRealNull(d[r][colIndex].v)){\r\n edr = r;\r\n }\r\n }\r\n\r\n if(str == null || str > r2){\r\n return;\r\n }\r\n\r\n let hasMc = false; //排序选区是否有合并单元格\r\n let data = [];\r\n\r\n for(let r = str; r <= edr; r++){\r\n let data_row = [];\r\n\r\n for(let c = c1; c <= c2; c++){\r\n if(d[r][c] != null && d[r][c].mc != null){\r\n hasMc = true;\r\n break;\r\n }\r\n\r\n data_row.push(d[r][c]);\r\n }\r\n\r\n data.push(data_row);\r\n }\r\n\r\n if(hasMc){\r\n if(isEditMode()){\r\n alert(\"列排序会扩展至整个表格选区,选区有合并单元格,无法执行此操作,请选择功能栏排序功能!\");\r\n }\r\n else{\r\n tooltip.info(\"列排序会扩展至整个表格选区,选区有合并单元格,无法执行此操作,请选择功能栏排序功能!\", \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n data = orderbydata(data, colIndex, isAsc);\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = c1; c <= c2; c++){\r\n d[r][c] = data[r - str][c - c1];\r\n }\r\n }\r\n\r\n let allParam = {};\r\n if(Store.config[\"rowlen\"] != null){\r\n let cfg = $.extend(true, {}, Store.config);\r\n cfg = rowlenByRange(d, str, edr, cfg);\r\n\r\n allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true\r\n }\r\n }\r\n\r\n jfrefreshgrid(d, [{ \"row\": [str, edr], \"column\": [c1, c2] }], allParam);\r\n}\r\n\r\nexport {\r\n orderbydata,\r\n orderbydata1D,\r\n sortSelection,\r\n sortColumnSeletion,\r\n}","import { getcellvalue } from './getdata';\r\n\r\nconst luckysheetArray = {\r\n transpose: function (getdata, useGetcellValue=true) {\r\n let arr = [];\r\n if (getdata.length == 0) {\r\n return [];\r\n }\r\n\r\n if (getdata[0].length == 0) {\r\n return [];\r\n }\r\n\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n let a = [];\r\n for (let r = 0; r < getdata.length; r++) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n if(useGetcellValue){\r\n value = getcellvalue(r, c, getdata);\r\n }\r\n else{\r\n value = getdata[r][c];\r\n }\r\n }\r\n a.push(value);\r\n }\r\n arr.push(a);\r\n }\r\n\r\n return arr;\r\n },\r\n minusClear: function(p, m){\r\n if(m.row[0] > p.row[1] || m.row[1] < p.row[0] || m.column[0] > p.column[1] || m.column[1] < p.column[0]){\r\n return null;\r\n }\r\n\r\n if(m.row[0] == p.row[0] && m.row[1] < p.row[1] && m.column[0] > p.column[0] && m.column[1] < p.column[1]){\r\n return [];\r\n }\r\n\r\n let ret = [], range = {row:[], column:[]};\r\n\r\n let row1 = null, column1 = [p.column[0], p.column[1]];\r\n if(m.row[1] > p.row[0] && m.row[1] < p.row[1]){\r\n row1 = [m.row[1] + 1, p.row[1]];\r\n }\r\n else if(m.row[0] > p.row[0] && m.row[0] < p.row[1]){\r\n row1 = [p.row[0], m.row[0] - 1];\r\n }\r\n\r\n if(row1 != null){\r\n ret.push({\"row\": row1, \"column\": column1});\r\n }\r\n\r\n let row2 = [p.row[0], p.row[1]], column2 = null;\r\n if(m.column[1] > p.column[0] && m.column[1] < p.column[1]){\r\n column2 = [m.column[1] + 1, p.column[1]];\r\n }\r\n else if(m.column[0] > p.column[0] && m.column[0] < p.column[1]){\r\n column2 = [p.column[0], m.column[0] - 1];\r\n }\r\n\r\n if(column2 != null){\r\n ret.push({\"row\": row2, \"column\": column2});\r\n }\r\n\r\n return ret;\r\n }\r\n}\r\n\r\nexport default luckysheetArray;","import { numFormat } from '../utils/util';\r\n\r\nconst analysis = {\r\n \"STDEVP\": function (mean, array1d) {\r\n let cov = 0;\r\n for (let i = 0; i < array1d.length; i++) {\r\n let xi = array1d[i];\r\n cov += Math.pow(xi - mean, 2);\r\n }\r\n return numFormat(Math.sqrt(cov / array1d.length));\r\n },\r\n \"STDEV\": function (mean, array1d) {\r\n let cov = 0;\r\n for (let i = 0; i < array1d.length; i++) {\r\n let xi = array1d[i];\r\n cov += Math.pow(xi - mean, 2);\r\n }\r\n return numFormat(Math.sqrt(cov / (array1d.length - 1)));\r\n },\r\n \"VARP\": function (mean, array1d) {\r\n let cov = 0;\r\n for (let i = 0; i < array1d.length; i++) {\r\n let xi = array1d[i];\r\n cov += Math.pow(xi - mean, 2);\r\n }\r\n return numFormat(cov / array1d.length);\r\n },\r\n \"let\": function (mean, array1d) {\r\n let cov = 0;\r\n for (let i = 0; i < array1d.length; i++) {\r\n let xi = array1d[i];\r\n cov += Math.pow(xi - mean, 2);\r\n }\r\n return numFormat(cov / (array1d.length - 1));\r\n },\r\n};\r\n\r\nexport default analysis;","import { getSheetIndex, getRangetxt } from '../methods/get';\r\nimport { \r\n replaceHtml, \r\n getObjType, \r\n ABCatNum, \r\n numFormat,\r\n numfloatlen,\r\n showrightclickmenu, \r\n mouseclickposition \r\n} from '../utils/util';\r\nimport { getdatabyselectionD, getcellvalue, datagridgrowth } from '../global/getdata';\r\nimport { isdatetime, diff, isdatatypemulti, isdatatype } from '../global/datecontroll';\r\nimport { genarate, update } from '../global/format';\r\nimport { isRealNull, isEditMode } from '../global/validate';\r\nimport { orderbydata1D } from '../global/sort';\r\nimport { jfrefreshgrid, jfrefreshgridall } from '../global/refresh';\r\nimport tooltip from '../global/tooltip';\r\nimport editor from '../global/editor';\r\nimport cleargridelement from '../global/cleargridelement';\r\nimport luckysheetArray from '../global/array';\r\nimport analysis from '../global/analysis';\r\nimport { selectHightlightShow } from './select';\r\nimport { luckysheet_searcharray } from './sheetSearch';\r\nimport { \r\n modelHTML, \r\n filtermenuHTML, \r\n filtersubmenuHTML, \r\n pivottableconfigHTML,\r\n pivottablesumHTML,\r\n luckysheetPivotTableHTML \r\n} from './constant';\r\nimport sheetmanage from './sheetmanage';\r\nimport luckysheetsizeauto from './resize';\r\nimport server from './server';\r\nimport {checkProtectionAuthorityNormal} from './protection';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport numeral from 'numeral';\r\n\r\nconst pivotTable = {\r\n pivotDatas: null,\r\n pivotSheetIndex: 0,\r\n pivotDataSheetIndex: 0,\r\n celldata: null,\r\n origindata: null,\r\n getCellData: function (cursheetindex, datasheetindex, data_select_save) {\r\n let _this = this;\r\n\r\n let sheetIndex;\r\n if (cursheetindex != null) {\r\n sheetIndex = cursheetindex;\r\n }\r\n else {\r\n sheetIndex = Store.currentSheetIndex;\r\n }\r\n\r\n let realIndex = getSheetIndex(sheetIndex);\r\n\r\n if (getObjType(Store.luckysheetfile[realIndex].pivotTable) != \"object\"){\r\n Store.luckysheetfile[realIndex].pivotTable = new Function(\"return \" + Store.luckysheetfile[realIndex].pivotTable )();\r\n }\r\n\r\n if (Store.luckysheetfile[realIndex].pivotTable != null) {\r\n _this.column = Store.luckysheetfile[realIndex].pivotTable.column;\r\n _this.row = Store.luckysheetfile[realIndex].pivotTable.row;\r\n _this.values = Store.luckysheetfile[realIndex].pivotTable.values;\r\n _this.filter = Store.luckysheetfile[realIndex].pivotTable.filter;\r\n _this.showType = Store.luckysheetfile[realIndex].pivotTable.showType;\r\n\r\n _this.filterparm = Store.luckysheetfile[realIndex].pivotTable.filterparm;\r\n\r\n if (Store.luckysheetfile[realIndex].pivotTable.drawPivotTable != null) {\r\n _this.drawPivotTable = Store.luckysheetfile[realIndex].pivotTable.drawPivotTable;\r\n }\r\n else {\r\n _this.drawPivotTable = true;\r\n }\r\n\r\n if (Store.luckysheetfile[realIndex].pivotTable.pivotTableBoundary != null) {\r\n _this.pivotTableBoundary = Store.luckysheetfile[realIndex].pivotTable.pivotTableBoundary;\r\n }\r\n else {\r\n _this.pivotTableBoundary = [12, 6];\r\n }\r\n\r\n if (data_select_save != null) {\r\n _this.pivot_select_save = data_select_save;\r\n }\r\n else {\r\n _this.pivot_select_save = Store.luckysheetfile[realIndex].pivotTable.pivot_select_save;\r\n }\r\n\r\n if (datasheetindex != null) {\r\n _this.pivotDataSheetIndex = datasheetindex;\r\n }\r\n else {\r\n _this.pivotDataSheetIndex = Store.luckysheetfile[realIndex].pivotTable.pivotDataSheetIndex;\r\n }\r\n }\r\n else {\r\n _this.column = null;\r\n _this.row = null;\r\n _this.values = null;\r\n _this.filter = null;\r\n _this.showType = null;\r\n\r\n _this.filterparm = null;\r\n\r\n _this.drawPivotTable = true;\r\n _this.pivotTableBoundary = [12, 6];\r\n\r\n if (data_select_save != null) {\r\n _this.pivot_select_save = data_select_save;\r\n }\r\n else {\r\n _this.pivot_select_save = Store.luckysheet_select_save;\r\n }\r\n\r\n if (datasheetindex != null) {\r\n _this.pivotDataSheetIndex = datasheetindex;\r\n }\r\n else {\r\n _this.pivotDataSheetIndex = sheetIndex;\r\n }\r\n }\r\n\r\n let pivotrealIndex = getSheetIndex(_this.pivotDataSheetIndex);\r\n\r\n let otherfile = Store.luckysheetfile[pivotrealIndex];\r\n if(otherfile[\"data\"] == null){\r\n otherfile[\"data\"] = sheetmanage.buildGridData(otherfile);\r\n }\r\n _this.origindata = getdatabyselectionD(otherfile.data, _this.pivot_select_save);\r\n\r\n let rowhidden = {};\r\n if (_this.filterparm != null) {\r\n for (let f in _this.filterparm) {\r\n // 目的是取出rowhidden\r\n for (let h in _this.filterparm[f]) {\r\n if (h === 'rowhidden' && _this.filterparm[f][h] != null) {\r\n rowhidden = $.extend(true, rowhidden, _this.filterparm[f][h]);\r\n }\r\n }\r\n }\r\n }\r\n _this.rowhidden = rowhidden;\r\n\r\n _this.pivotSheetIndex = sheetIndex;\r\n\r\n let newdata = [];\r\n for (let i = 0; i < _this.origindata.length; i++) {\r\n if (_this.rowhidden != null && _this.rowhidden[i] != null) {\r\n continue;\r\n }\r\n newdata.push([].concat(_this.origindata[i]));\r\n }\r\n _this.celldata = newdata;\r\n\r\n _this.pivot_data_type = {};\r\n for (let c = 0; c < _this.celldata[1].length; c++) {\r\n let type = isdatatype(_this.celldata[1][c]);\r\n _this.pivot_data_type[c.toString()] = type;\r\n }\r\n },\r\n pivot_data_type: {},\r\n pivot_select_save: null,\r\n column: null,\r\n row: null,\r\n values: null,\r\n filter: null,\r\n showType: null,\r\n rowhidden: null,\r\n selected: null,\r\n caljs: null,\r\n initial: true,\r\n filterparm: null,\r\n luckysheet_pivotTable_select_state: false,\r\n jgridCurrentPivotInput: null,\r\n movestate: false,\r\n moveitemposition: [],\r\n movesave: {},\r\n showvaluecolrow: function () {\r\n let _this = this;\r\n\r\n if ($(\"#luckysheet-modal-dialog-config-value .luckysheet-modal-dialog-slider-config-item\").length >= 2) {\r\n $(\"#luckysheetpivottablevaluecolrowshow\").show();\r\n\r\n if (_this.showType == \"column\") {\r\n $(\"#luckysheetpivottablevaluecolrow\").prop(\"checked\", true);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow']\").addClass(\"ui-state-active\");\r\n\r\n $(\"#luckysheetpivottablevaluecolrow1\").prop(\"checked\", false);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow1']\").removeClass(\"ui-state-active\");\r\n }\r\n else {\r\n $(\"#luckysheetpivottablevaluecolrow1\").prop(\"checked\", true);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow1']\").addClass(\"ui-state-active\");\r\n\r\n $(\"#luckysheetpivottablevaluecolrow\").prop(\"checked\", false);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow']\").removeClass(\"ui-state-active\");\r\n }\r\n }\r\n else {\r\n $(\"#luckysheetpivottablevaluecolrowshow\").hide();\r\n }\r\n },\r\n resetOrderby: function (obj) {\r\n let orderby = $(\"#luckysheet-modal-dialog-config-value .luckysheet-modal-dialog-slider-config-item\").index(obj);\r\n $(\"#luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column\").find(\".luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n if ($(this).data(\"orderby\") == orderby) {\r\n $(this).data(\"orderby\", \"self\");\r\n }\r\n });\r\n },\r\n luckysheetsliderlistclearfilter: function ($filter) {\r\n let _this = this;\r\n\r\n let $t = $filter.parent();\r\n let cindex = $t.data(\"index\");\r\n\r\n let rowhidden = {}, \r\n selected = {}, \r\n d = _this.origindata, \r\n filterdata = {};\r\n\r\n $t.data(\"rowhidden\", \"\").find(\".luckysheet-slider-list-item-filtered\").hide();\r\n _this.setDatatojsfile(\"selected\", {}, cindex);\r\n _this.setDatatojsfile(\"rowhidden\", null, cindex);\r\n\r\n let newdata = [];\r\n for (let i = 0; i < d.length; i++) {\r\n if (rowhidden[i] != null) {\r\n continue;\r\n }\r\n newdata.push([].concat(d[i]));\r\n }\r\n\r\n _this.celldata = newdata;\r\n _this.refreshPivotTable();\r\n $(\"#luckysheet-pivotTableFilter-menu, #luckysheet-pivotTableFilter-submenu\").hide();\r\n },\r\n luckysheetsliderlistitemfilter: function ($filter) {\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_filter = _locale.filter;\r\n\r\n let $t = $filter.parent(), \r\n toffset = $t.offset(), \r\n $menu = $(\"#luckysheet-pivotTableFilter-menu\"), \r\n winH = $(window).height(), \r\n winW = $(window).width();\r\n\r\n let cindex = $t.data(\"index\");\r\n\r\n let rowhidden = $t.data(\"rowhidden\");\r\n if(rowhidden == null || rowhidden == \"\"){\r\n rowhidden = {};\r\n }\r\n else if(getObjType(rowhidden) == \"string\"){\r\n rowhidden = JSON.parse(rowhidden);\r\n }\r\n\r\n $(\"body .luckysheet-cols-menu\").hide();\r\n $(\"#luckysheet-pivotTableFilter-menu, #luckysheet-pivotTableFilter-submenu\").hide();\r\n $(\"#luckysheet-pivotTableFilter-byvalue-input\").val(\"\");\r\n $(\"#luckysheet-pivotTableFilter-bycondition\").next().hide();\r\n $(\"#luckysheet-pivotTableFilter-byvalue\").next().show();\r\n\r\n $menu.data(\"index\", cindex);\r\n\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input\").hide().find(\"input\").val();\r\n $(\"#luckysheet-pivotTableFilter-selected span\").data(\"type\", \"0\").data(\"type\", null).text(locale_filter.filiterInputNone);\r\n\r\n let byconditiontype = $t.data(\"byconditiontype\");\r\n $(\"#luckysheet-pivotTableFilter-selected span\").data(\"value\", $t.data(\"byconditionvalue\")).data(\"type\", byconditiontype).text($t.data(\"byconditiontext\"));\r\n\r\n if (byconditiontype == \"2\") {\r\n let $input = $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input2\").show().find(\"input\");\r\n $input.eq(0).val($t.data(\"byconditionvalue1\"));\r\n $input.eq(1).val($t.data(\"byconditionvalue2\"));\r\n }\r\n else if (byconditiontype == \"1\") {\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input\").eq(0).show().find(\"input\").val($t.data(\"byconditionvalue1\"));\r\n }\r\n\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select\").empty().html('
'+locale_filter.filiterMoreDataTip+'
');\r\n \r\n let rowhiddenother = {}; //其它筛选列的隐藏行\r\n $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").not($t.get(0)).each(function () {\r\n let $t = $(this), rh = $t.data(\"rowhidden\");\r\n\r\n if (rh == null || rh == \"\") {\r\n return true;\r\n }\r\n\r\n if(getObjType(rh) == \"string\"){\r\n rh = JSON.parse(rh);\r\n }\r\n \r\n for (let r in rh) {\r\n rowhiddenother[r] = 0;\r\n }\r\n });\r\n\r\n let data = _this.origindata;\r\n\r\n setTimeout(function () {\r\n //日期值\r\n let dvmap = {}; \r\n let dvmap_uncheck = {};\r\n\r\n //除日期以外的值\r\n let vmap = {}; \r\n let vmap_uncheck = {}; \r\n\r\n for (let r = 1; r < data.length; r++) {\r\n if(r in rowhiddenother){\r\n continue;\r\n }\r\n\r\n if(data[r] == null){\r\n continue;\r\n }\r\n\r\n let cell = data[r][cindex];\r\n\r\n if(cell != null && cell.ct != null && cell.ct.t == \"d\"){ //单元格是日期\r\n let v = update(\"YYYY-MM-DD\", cell.v);\r\n\r\n let y = v.split(\"-\")[0];\r\n let m = v.split(\"-\")[1];\r\n let d = v.split(\"-\")[2];\r\n\r\n if(!(y in dvmap)){\r\n dvmap[y] = {};\r\n }\r\n\r\n if(!(m in dvmap[y])){\r\n dvmap[y][m] = {};\r\n }\r\n\r\n if(!(d in dvmap[y][m])){\r\n dvmap[y][m][d] = 0;\r\n }\r\n \r\n dvmap[y][m][d]++;\r\n\r\n if(r in rowhidden){\r\n dvmap_uncheck[y] = 0;\r\n dvmap_uncheck[m] = 0;\r\n dvmap_uncheck[d] = 0;\r\n }\r\n }\r\n else{\r\n let v, m;\r\n if(cell == null || isRealNull(cell.v)){\r\n v = null;\r\n m = null;\r\n }\r\n else{\r\n v = cell.v;\r\n m = cell.m;\r\n }\r\n\r\n if(!(v in vmap)){\r\n vmap[v] = {};\r\n }\r\n\r\n if(!(m in vmap[v])){\r\n vmap[v][m] = 0; \r\n }\r\n\r\n vmap[v][m]++;\r\n\r\n if(r in rowhidden){\r\n vmap_uncheck[v + \"#$$$#\" + m] = 0;\r\n }\r\n }\r\n }\r\n\r\n //遍历数据加到页面\r\n let item = [];\r\n\r\n if(JSON.stringify(dvmap).length > 2){\r\n for(let y in dvmap){\r\n let ysum = 0;\r\n let monthHtml = '';\r\n\r\n for(let m in dvmap[y]){\r\n let msum = 0;\r\n let dayHtml = '';\r\n\r\n for(let d in dvmap[y][m]){\r\n let dayL = dvmap[y][m][d];\r\n msum += dayL;\r\n\r\n //月 小于 10\r\n let mT;\r\n if(Number(m) < 10){\r\n mT = \"0\" + Number(m);\r\n }\r\n else{\r\n mT = m; \r\n }\r\n\r\n //日 小于 10\r\n let dT;\r\n if(Number(d) < 10){\r\n dT = \"0\" + Number(d);\r\n }\r\n else{\r\n dT = d; \r\n }\r\n\r\n //日是否选中状态\r\n if((y in dvmap_uncheck) && (m in dvmap_uncheck) && (d in dvmap_uncheck)){\r\n dayHtml += '
' +\r\n '' +\r\n '' +\r\n '( ' + dayL + ' )' +\r\n '
';\r\n }\r\n else{\r\n dayHtml += '
' +\r\n '' +\r\n '' +\r\n '( ' + dayL + ' )' +\r\n '
';\r\n }\r\n }\r\n\r\n ysum += msum;\r\n \r\n //月 小于 10\r\n let mT2;\r\n if(Number(m) < 10){\r\n mT2 = \"0\" + Number(m);\r\n }\r\n else{\r\n mT2 = m; \r\n }\r\n\r\n //月是否选中状态\r\n if((y in dvmap_uncheck) && (m in dvmap_uncheck)){\r\n monthHtml += '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + msum + ' )' +\r\n '
' +\r\n '
' + dayHtml + '
' +\r\n '
';\r\n }\r\n else{\r\n monthHtml += '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + msum + ' )' +\r\n '
' +\r\n '
' + dayHtml + '
' +\r\n '
';\r\n }\r\n }\r\n\r\n //年是否选中状态\r\n let yearHtml;\r\n if(y in dvmap_uncheck){\r\n yearHtml = '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + ysum + ' )' +\r\n '
' +\r\n '
' + monthHtml + '
' +\r\n '
';\r\n }\r\n else{\r\n yearHtml = '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '( ' + ysum + ' )' +\r\n '
' +\r\n '
' + monthHtml + '
' +\r\n '
';\r\n }\r\n\r\n item.unshift(yearHtml);\r\n }\r\n }\r\n\r\n if(JSON.stringify(vmap).length > 2){\r\n let vmapKeys = Object.keys(vmap);\r\n vmapKeys = orderbydata1D(vmapKeys, true);\r\n\r\n for(let i = 0; i < vmapKeys.length; i++){\r\n let v = vmapKeys[i];\r\n\r\n for(let x in vmap[v]){\r\n let text;\r\n if((v + \"#$$$#\" + x) == \"null#$$$#null\"){\r\n text = locale_filter.valueBlank;\r\n }\r\n else{\r\n text = x;\r\n }\r\n\r\n //是否选中状态\r\n let dataHtml;\r\n if((v + \"#$$$#\" + x) in vmap_uncheck){\r\n dataHtml = '
' +\r\n '' +\r\n '' +\r\n '( ' + vmap[v][x] + ' )' +\r\n '
';\r\n }\r\n else{\r\n dataHtml = '
' +\r\n '' +\r\n '' +\r\n '( ' + vmap[v][x] + ' )' +\r\n '
';\r\n }\r\n\r\n item.push(dataHtml);\r\n }\r\n }\r\n }\r\n\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select\").html(\"
\" + item.join(\"\") + \"
\");\r\n }, 1);\r\n\r\n showrightclickmenu($menu, toffset.left - 250, toffset.top);\r\n },\r\n getSumTypeName: function (type) {\r\n let name = \"\";\r\n\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n\r\n if (type == \"SUM\") {\r\n name = locale_pivotTable.valueStatisticsSUM;\r\n }\r\n else if (type == \"COUNT\") {\r\n name = locale_pivotTable.valueStatisticsCOUNT;\r\n }\r\n else if (type == \"COUNTA\") {\r\n name = locale_pivotTable.valueStatisticsCOUNTA;\r\n }\r\n else if (type == \"COUNTUNIQUE\") {\r\n name = locale_pivotTable.valueStatisticsCOUNTUNIQUE;\r\n }\r\n else if (type == \"AVERAGE\") {\r\n name = locale_pivotTable.valueStatisticsAVERAGE;\r\n }\r\n else if (type == \"MAX\") {\r\n name = locale_pivotTable.valueStatisticsMAX;\r\n }\r\n else if (type == \"MIN\") {\r\n name = locale_pivotTable.valueStatisticsMIN;\r\n }\r\n else if (type == \"MEDIAN\") {\r\n name = locale_pivotTable.valueStatisticsMEDIAN;\r\n }\r\n else if (type == \"PRODUCT\") {\r\n name = locale_pivotTable.valueStatisticsPRODUCT;\r\n }\r\n else if (type == \"STDEV\") {\r\n name = locale_pivotTable.valueStatisticsSTDEV;\r\n }\r\n else if (type == \"STDEVP\") {\r\n name = locale_pivotTable.valueStatisticsSTDEVP;\r\n }\r\n else if (type == \"let\") {\r\n name = locale_pivotTable.valueStatisticslet;\r\n }\r\n else if (type == \"VARP\") {\r\n name = locale_pivotTable.valueStatisticsVARP;\r\n }\r\n\r\n return name;\r\n },\r\n setDatatojsfile: function (attr, value, cindex) {\r\n let _this = this;\r\n\r\n let index = getSheetIndex(_this.pivotSheetIndex);\r\n if (Store.luckysheetfile[index][\"pivotTable\"] == null) {\r\n Store.luckysheetfile[index][\"pivotTable\"] = {};\r\n }\r\n\r\n if (cindex == null) {\r\n Store.luckysheetfile[index][\"pivotTable\"][attr] = value;\r\n _this[attr] = value;\r\n }\r\n else {\r\n if (Store.luckysheetfile[index][\"pivotTable\"][\"filterparm\"] == null) {\r\n Store.luckysheetfile[index][\"pivotTable\"][\"filterparm\"] = {};\r\n }\r\n\r\n if (Store.luckysheetfile[index][\"pivotTable\"][\"filterparm\"][cindex.toString()] == null) {\r\n Store.luckysheetfile[index][\"pivotTable\"][\"filterparm\"][cindex.toString()] = {};\r\n }\r\n Store.luckysheetfile[index][\"pivotTable\"][\"filterparm\"][cindex.toString()][attr] = value;\r\n\r\n if (_this[\"filterparm\"] == null) {\r\n _this[\"filterparm\"] = {};\r\n }\r\n\r\n if (_this[\"filterparm\"][cindex.toString()] == null) {\r\n _this[\"filterparm\"][cindex.toString()] = {};\r\n }\r\n\r\n _this[\"filterparm\"][cindex.toString()][attr] = value;\r\n }\r\n },\r\n createPivotTable: function (e) {\r\n\r\n if(isEditMode() || Store.allowEdit===false){\r\n return;\r\n }\r\n let _this = this;\r\n\r\n let datasheetindex = Store.currentSheetIndex;\r\n\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n\r\n if(isEditMode()){\r\n alert(locale_pivotTable.errorNotAllowEdit);\r\n return;\r\n }\r\n\r\n if(Store.luckysheet_select_save.length > 1){\r\n tooltip.info(\"\", locale_pivotTable.errorNotAllowMulti);\r\n return\r\n }\r\n\r\n if (Store.luckysheet_select_save.length == 0 || Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] || Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1]) {\r\n tooltip.info(\"\", locale_pivotTable.errorSelectRange);\r\n return;\r\n }\r\n\r\n let select_save = $.extend(true, {}, Store.luckysheet_select_save[0]);\r\n sheetmanage.addNewSheet(e, true);\r\n\r\n _this.getCellData(Store.currentSheetIndex, datasheetindex, select_save);\r\n\r\n _this.setDatatojsfile(\"pivot_select_save\", select_save);\r\n _this.setDatatojsfile(\"pivotDataSheetIndex\", datasheetindex);\r\n\r\n _this.initialPivotManage();\r\n },\r\n changePivotTable: function (index) {\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n\r\n let pivotDataSheetIndex = Store.luckysheetfile[getSheetIndex(index)].pivotTable.pivotDataSheetIndex;\r\n let real_pivotDataSheetIndex = getSheetIndex(pivotDataSheetIndex);\r\n\r\n if(real_pivotDataSheetIndex == null){\r\n tooltip.info(locale_pivotTable.errorIsDamage, \"\");\r\n return;\r\n }\r\n\r\n _this.getCellData(index);\r\n _this.initialPivotManage(true);\r\n _this.refreshPivotTable(); //初始化在一个普通sheet页,从此普通sheet页切换到数据透视表页时,需要刷新下数据,否则还是旧数据\r\n },\r\n refreshPivotTable: function (isRefreshCanvas=true) {\r\n let _this = this;\r\n\r\n let redo = {};\r\n redo[\"pivotTable\"] = pivotTable; \r\n redo[\"data\"] = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n\r\n _this.storePivotTableParam();\r\n let ret = _this.dataHandler(_this.column, _this.row, _this.values, _this.showType, _this.celldata);\r\n _this.setDatatojsfile(\"pivotDatas\", ret);\r\n\r\n let d = $.extend(true, [], sheetmanage.nulldata);\r\n let data = d;\r\n\r\n let addr = 0, addc = 0;\r\n\r\n if (ret.length == 0) {\r\n _this.setDatatojsfile(\"drawPivotTable\", true);\r\n _this.setDatatojsfile(\"pivotTableBoundary\", [12, 6]);\r\n }\r\n else {\r\n _this.setDatatojsfile(\"drawPivotTable\", false);\r\n _this.setDatatojsfile(\"pivotTableBoundary\", [ret.length, ret[0].length]);\r\n\r\n let rlen = ret.length, \r\n clen = ret[0].length;\r\n\r\n addr = rlen - d.length; \r\n addc = clen - d[0].length;\r\n\r\n data = datagridgrowth(d, addr + 20, addc + 10, true);\r\n\r\n for (let r = 0; r < rlen; r++) {\r\n let x = [].concat(data[r]);\r\n for (let c = 0; c < clen; c++) {\r\n let value = \"\";\r\n if (ret[r] != null && ret[r][c] != null) {\r\n value = getcellvalue(r, c, ret);\r\n }\r\n x[c] = value;\r\n }\r\n data[r] = x;\r\n }\r\n }\r\n\r\n redo[\"type\"] = \"pivotTable_change\";\r\n redo[\"curdata\"] = $.extend(true, [], data);\r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n\r\n let pivotTable = _this.getPivotTableData();\r\n redo[\"pivotTablecur\"] = pivotTable; \r\n\r\n if(Store.clearjfundo){\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n }\r\n \r\n cleargridelement();\r\n Store.clearjfundo = false;\r\n \r\n if (addr > 0 || addc > 0) {\r\n jfrefreshgridall(data[0].length, data.length, data, null, Store.luckysheet_select_save, \"datachangeAll\", undefined, undefined,isRefreshCanvas);\r\n }\r\n else {\r\n jfrefreshgrid(data, Store.luckysheet_select_save, {}, null, isRefreshCanvas);\r\n selectHightlightShow();\r\n }\r\n\r\n Store.clearjfundo = true;\r\n },\r\n drawPivotTable: true,\r\n pivotTableBoundary: [12, 6],\r\n pivotclick: function (row_index, col_index, index) {\r\n if(index == null){\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n\r\n\r\n let file = Store.luckysheetfile[getSheetIndex(index)];\r\n\r\n if(!file.isPivotTable){\r\n return;\r\n }\r\n\r\n let pivotDataSheetIndex = file.pivotTable.pivotDataSheetIndex;\r\n let real_pivotDataSheetIndex = getSheetIndex(pivotDataSheetIndex);\r\n\r\n if(real_pivotDataSheetIndex == null){\r\n return;\r\n }\r\n\r\n let slider = $(\"#luckysheet-modal-dialog-slider-pivot\"); \r\n\r\n let isRangeClick = this.isPivotRange(row_index, col_index);\r\n if (isRangeClick && slider.is(\":hidden\")) {\r\n if(!checkProtectionAuthorityNormal(index, \"usePivotTablereports\",false)){\r\n // Store.luckysheet_select_status = false;\r\n return;\r\n }\r\n slider.show();\r\n luckysheetsizeauto();\r\n $(\"#luckysheet-sta-content\").css(\"padding-right\", 260);\r\n }\r\n else if(!isRangeClick && slider.is(\":visible\")) {\r\n slider.hide();\r\n luckysheetsizeauto();\r\n $(\"#luckysheet-sta-content\").css(\"padding-right\", 10);\r\n }\r\n },\r\n isPivotRange: function (row_index, col_index) {\r\n let _this = this;\r\n\r\n if (!!Store.luckysheetcurrentisPivotTable) {\r\n if (row_index < _this.pivotTableBoundary[0] && col_index < _this.pivotTableBoundary[1]) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n },\r\n storePivotTableParam: function () {\r\n let _this = this;\r\n let columnarr = [], rowarr = [], filterarr = [], valuesarr = [];\r\n\r\n $(\"#luckysheet-modal-dialog-config-filter .luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n let item = {};\r\n item[\"index\"] = $(this).data(\"index\");\r\n item[\"name\"] = $(this).data(\"name\");\r\n item[\"fullname\"] = $(this).find(\".luckysheet-modal-dialog-slider-config-item-txt\").text();\r\n filterarr.push(item);\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-config-row .luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n let item = {};\r\n item[\"index\"] = $(this).data(\"index\");\r\n item[\"name\"] = $(this).data(\"name\");\r\n item[\"fullname\"] = $(this).find(\".luckysheet-modal-dialog-slider-config-item-txt\").text();\r\n item[\"order\"] = $(this).data(\"order\");\r\n item[\"orderby\"] = $(this).data(\"orderby\");\r\n item[\"stastic\"] = $(this).data(\"stastic\");\r\n rowarr.push(item);\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-config-column .luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n let item = {};\r\n item[\"index\"] = $(this).data(\"index\");\r\n item[\"name\"] = $(this).data(\"name\");\r\n item[\"fullname\"] = $(this).find(\".luckysheet-modal-dialog-slider-config-item-txt\").text();\r\n item[\"order\"] = $(this).data(\"order\");\r\n item[\"orderby\"] = $(this).data(\"orderby\");\r\n item[\"stastic\"] = $(this).data(\"stastic\");\r\n columnarr.push(item);\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-config-value .luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n let item = {};\r\n item[\"index\"] = $(this).data(\"index\");\r\n item[\"name\"] = $(this).data(\"name\");\r\n item[\"fullname\"] = $(this).find(\".luckysheet-modal-dialog-slider-config-item-txt\").text();\r\n item[\"sumtype\"] = $(this).data(\"sumtype\");\r\n item[\"nameindex\"] = $(this).data(\"nameindex\");\r\n valuesarr.push(item);\r\n });\r\n\r\n _this.setDatatojsfile(\"column\", columnarr);\r\n _this.setDatatojsfile(\"row\", rowarr);\r\n _this.setDatatojsfile(\"filter\", filterarr);\r\n _this.setDatatojsfile(\"values\", valuesarr);\r\n let showtype = $(\"#luckysheetpivottablevaluecolrow:checked, #luckysheetpivottablevaluecolrow1:checked\").val();\r\n _this.setDatatojsfile(\"showType\", showtype == \"0\" ? \"row\" : \"column\");\r\n\r\n let pivotTable = _this.getPivotTableData();\r\n delete pivotTable.pivotDatas;\r\n server.saveParam(\"all\", _this.pivotSheetIndex, pivotTable, { \"k\": \"pivotTable\" });\r\n },\r\n getPivotTableData: function(dataindex){\r\n if(dataindex == null){\r\n dataindex = this.pivotSheetIndex;\r\n }\r\n\r\n let index = getSheetIndex(dataindex);\r\n let pivotTable = Store.luckysheetfile[index][\"pivotTable\"];\r\n\r\n if(getObjType(pivotTable) == \"object\"){\r\n pivotTable = $.extend(true, {}, Store.luckysheetfile[index][\"pivotTable\"]);\r\n }\r\n else{\r\n pivotTable = new Function(\"return \" + pivotTable )();\r\n }\r\n\r\n return pivotTable\r\n },\r\n addValuesToTitle: function (titles, values) {\r\n let rowLen = titles.length * values.length, \r\n colLen = titles[0].length + 1;\r\n \r\n let retdata = [];\r\n if (titles.length == 0 && values.length > 0) {\r\n for (let v = 0; v < values.length; v++) {\r\n retdata.push(values[v].fullname);\r\n }\r\n\r\n return retdata;\r\n }\r\n\r\n if (values.length == 0 && titles.length > 0) {\r\n return titles;\r\n }\r\n\r\n for (let r = 0; r < rowLen; r++) {\r\n retdata[r] = new Array(colLen);\r\n\r\n for (let c = 0; c < colLen - 1; c++) {\r\n retdata[r][c] = titles[Math.floor(r / values.length)][c];\r\n }\r\n\r\n retdata[r][colLen - 1] = values[r % values.length].fullname;\r\n }\r\n\r\n return retdata;\r\n },\r\n initialPivotManage: function (restore) {\r\n let _this = this;\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n const locale_button = _locale.button;\r\n const locale_filter = _locale.filter;\r\n\r\n if (_this.initial) {\r\n _this.initial = false;\r\n\r\n\r\n\r\n $(\"body\").append(luckysheetPivotTableHTML());\r\n $(\"#luckysheet-modal-dialog-slider-close\").click(function () {\r\n $(\"#luckysheet-modal-dialog-slider-pivot\").hide();\r\n luckysheetsizeauto();\r\n });\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \"id\": \"luckysheet-data-pivotTable-selection\", \"addclass\": \"luckysheet-data-pivotTable-selection\", \"title\": locale_pivotTable.titleSelectionDataRange, \"content\": '', \"botton\": '' }));\r\n\r\n $(\"body\").append(replaceHtml(filtermenuHTML(), { \"menuid\": \"pivotTableFilter\" }));\r\n $(\"body\").append(replaceHtml(filtersubmenuHTML(), { \"menuid\": \"pivotTableFilter\" }));\r\n $(\"body\").append(pivottableconfigHTML());\r\n $(\"body\").append(pivottablesumHTML());\r\n\r\n $(\"#luckysheet-pivotTableFilter-orderby-asc\").remove();\r\n $(\"#luckysheet-pivotTableFilter-orderby-desc\").next().remove();\r\n $(\"#luckysheet-pivotTableFilter-orderby-desc\").remove();\r\n $(\"#luckysheet-pivotTableFilter-orderby-color\").next().remove();\r\n $(\"#luckysheet-pivotTableFilter-orderby-color\").remove();\r\n\r\n $(\"#luckysheetpivottablevaluecolrow, #luckysheetpivottablevaluecolrow1\").checkboxradio({\r\n icon: false\r\n }).change(function () {\r\n _this.refreshPivotTable();\r\n });\r\n\r\n let hidefilersubmenu = null;\r\n $(\"#luckysheet-pivotTableFilter-menu\").mouseover(function () {\r\n clearTimeout(hidefilersubmenu);\r\n hidefilersubmenu = setTimeout(function () {\r\n $(\"#luckysheet-pivotTableFilter-submenu\").hide();\r\n }, 500);\r\n });\r\n\r\n //点击复选框\r\n $(document).off(\"click.ptFilterCheckbox1\").on(\"click.ptFilterCheckbox1\", \"#luckysheet-pivotTableFilter-byvalue-select .textBox\",function(){\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n })\r\n $(document).off(\"click.ptFilterCheckbox2\").on(\"click.ptFilterCheckbox2\", \"#luckysheet-pivotTableFilter-byvalue-select .year\",function(){\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".month\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".day\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".month\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".day\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n })\r\n $(document).off(\"click.ptFilterCheckbox3\").on(\"click.ptFilterCheckbox3\", \"#luckysheet-pivotTableFilter-byvalue-select .month\",function(){\r\n //月份 对应的 天\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).parents(\".monthBox\").find(\".day\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".monthBox\").find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).parents(\".monthBox\").find(\".day\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".monthBox\").find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n //月份 对应的 年份\r\n let yearDayAllCheck = true;\r\n let $yearDay = $(this).parents(\".yearBox\").find(\".day\");\r\n $yearDay.each(function(i,e){\r\n if($(e).attr(\"data-check\") == \"true\"){\r\n \r\n }\r\n else{\r\n yearDayAllCheck = false;\r\n }\r\n });\r\n if(yearDayAllCheck){\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n else{\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n })\r\n $(document).off(\"click.ptFilterCheckbox4\").on(\"click.ptFilterCheckbox4\", \"#luckysheet-pivotTableFilter-byvalue-select .day\",function(){\r\n if($(this).attr(\"data-check\") == \"true\"){\r\n $(this).attr(\"data-check\", \"false\");\r\n $(this).find(\"input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n else{\r\n $(this).attr(\"data-check\", \"true\");\r\n $(this).find(\"input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n //天 对应的 月份\r\n let monthDayAllCheck = true;\r\n let $monthDay = $(this).parents(\".monthBox\").find(\".day\");\r\n $monthDay.each(function(i,e){\r\n if($(e).attr(\"data-check\") == \"true\"){\r\n \r\n }\r\n else{\r\n monthDayAllCheck = false;\r\n }\r\n });\r\n if(monthDayAllCheck){\r\n $(this).parents(\".monthBox\").find(\".month\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".monthBox\").find(\".month input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n else{\r\n $(this).parents(\".monthBox\").find(\".month\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".monthBox\").find(\".month input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n //天 对应的 年份\r\n let yearDayAllCheck = true;\r\n let $yearDay = $(this).parents(\".yearBox\").find(\".day\");\r\n $yearDay.each(function(i,e){\r\n if($(e).attr(\"data-check\") == \"true\"){\r\n \r\n }\r\n else{\r\n yearDayAllCheck = false;\r\n }\r\n });\r\n if(yearDayAllCheck){\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"true\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").prop(\"checked\", true);\r\n }\r\n else{\r\n $(this).parents(\".yearBox\").find(\".year\").attr(\"data-check\", \"false\");\r\n $(this).parents(\".yearBox\").find(\".year input[type='checkbox']\").removeAttr(\"checked\");\r\n }\r\n })\r\n\r\n //日期 三级下拉显示\r\n $(document).off(\"click.ptFilterYearDropdown\").on(\"click.ptFilterYearDropdown\", \"#luckysheet-pivotTableFilter-byvalue-select .yearBox .fa-caret-right\",function(){\r\n let $p = $(this).parents(\".luckysheet-mousedown-cancel\");\r\n if($p.hasClass(\"year\")){\r\n $(this).parents(\".yearBox\").find(\".monthList\").slideToggle();\r\n }\r\n if($p.hasClass(\"month\")){\r\n $(this).parents(\".monthBox\").find(\".dayList\").slideToggle();\r\n }\r\n });\r\n\r\n //全选\r\n $(\"#luckysheet-pivotTableFilter-byvalue-btn-all\").click(function () {\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']\").prop(\"checked\", true);\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']\").parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"true\");\r\n });\r\n\r\n //反选\r\n $(\"#luckysheet-pivotTableFilter-byvalue-btn-contra\").click(function () {\r\n let $input = $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']\");\r\n $input.each(function(i, e){\r\n if($(e).is(\":checked\")){\r\n $(e).removeAttr(\"checked\");\r\n $(e).parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"false\");\r\n }\r\n else{\r\n $(e).prop(\"checked\", true);\r\n $(e).parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"true\");\r\n }\r\n });\r\n //天 对应的 月份\r\n let $month = $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox .monthBox\");\r\n $month.each(function(index, event){\r\n let monthDayAllCheck = true;\r\n let $monthDay = $(event).find(\".day input[type='checkbox']\");\r\n $monthDay.each(function(i,e){\r\n if($(e).is(\":checked\")){\r\n \r\n }\r\n else{\r\n monthDayAllCheck = false;\r\n }\r\n });\r\n if(monthDayAllCheck){\r\n $(event).find(\".month input[type='checkbox']\").prop(\"checked\", true);\r\n $(event).attr(\"data-check\", \"true\");\r\n }\r\n else{\r\n $(event).find(\".month input[type='checkbox']\").removeAttr(\"checked\");\r\n $(event).attr(\"data-check\", \"false\");\r\n }\r\n });\r\n //天 对应的 年份\r\n let $year = $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox .yearBox\");\r\n $year.each(function(index, event){\r\n let yearDayAllCheck = true;\r\n let $yearDay = $(event).find(\".day input[type='checkbox']\");\r\n $yearDay.each(function(i,e){\r\n if($(e).is(\":checked\")){\r\n \r\n }\r\n else{\r\n yearDayAllCheck = false;\r\n }\r\n });\r\n if(yearDayAllCheck){\r\n $(event).find(\".year input[type='checkbox']\").prop(\"checked\", true);\r\n $(event).attr(\"data-check\", \"true\");\r\n }\r\n else{\r\n $(event).find(\".year input[type='checkbox']\").removeAttr(\"checked\");\r\n $(event).attr(\"data-check\", \"false\");\r\n }\r\n });\r\n });\r\n\r\n //清除\r\n $(\"#luckysheet-pivotTableFilter-byvalue-btn-clear\").click(function () {\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']\").removeAttr(\"checked\");\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']\").parents(\".luckysheet-mousedown-cancel\").attr(\"data-check\", \"false\");\r\n });\r\n\r\n //按照值进行筛选\r\n $(\"#luckysheet-pivotTableFilter-byvalue-input\").on('input propertychange', function () {\r\n let v = $(this).val().toString();\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox .luckysheet-mousedown-cancel\").show();\r\n if(v != \"\"){\r\n let $check = $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']\");\r\n $check.each(function(i, e){\r\n let $p = $(e).parents(\".luckysheet-mousedown-cancel\");\r\n if($p.hasClass(\"day\")){ //日期\r\n let day = $(e).siblings(\"label\").text().toString();\r\n let month = $(e).parents(\".monthBox\").find(\".month label\").text().toString();\r\n let year = $(e).parents(\".yearBox\").find(\".year label\").text().toString();\r\n let itemV = year + \"-\" + month + \"-\" + day;\r\n \r\n if(itemV.indexOf(v) == -1){\r\n $(e).parents(\".day\").hide();\r\n //天 对应的 月份\r\n let $monthDay = $(e).parents(\".dayList\").find(\".day:visible\");\r\n if($monthDay.length == 0){\r\n $(e).parents(\".monthBox\").find(\".month\").hide();\r\n }\r\n //天 对应的 年份\r\n let $yearDay = $(e).parents(\".monthList\").find(\".day:visible\");\r\n if($yearDay.length == 0){\r\n $(e).parents(\".yearBox\").find(\".year\").hide();\r\n }\r\n }\r\n }\r\n if($p.hasClass(\"textBox\")){ //其它\r\n let itemV = $(e).siblings(\"label\").text().toString();\r\n \r\n if(itemV.indexOf(v) == -1){\r\n $(e).parents(\".textBox\").hide();\r\n }\r\n }\r\n });\r\n }\r\n });\r\n\r\n $(\"#luckysheet-pivotTableFilter-bycondition, #luckysheet-pivotTableFilter-byvalue\").click(function () {\r\n let $t = $(this);\r\n $t.next().slideToggle(200);\r\n setTimeout(function () {\r\n if ($t.attr(\"id\") == \"luckysheet-pivotTableFilter-bycondition\" && $(\"#luckysheet-pivotTableFilter-bycondition\").next().is(\":visible\")) {\r\n if ($(\"#luckysheet-pivotTableFilter-selected span\").text() != locale_filter.filiterInputNone) {\r\n $(\"#luckysheet-pivotTableFilter-byvalue\").next().slideUp(200);\r\n }\r\n }\r\n\r\n if ($t.is($(\"#luckysheet-pivotTableFilter-bycondition\"))) {\r\n if ($(\"#luckysheet-pivotTableFilter-bycondition\").next().is(\":hidden\") && $(\"#luckysheet-pivotTableFilter-byvalue\").next().is(\":hidden\")) {\r\n $(\"#luckysheet-pivotTableFilter-byvalue\").next().slideDown(200);\r\n }\r\n }\r\n }, 300);\r\n\r\n });\r\n\r\n //取消按钮\r\n $(\"#luckysheet-pivotTableFilter-cancel\").click(function () {\r\n $(\"#luckysheet-pivotTableFilter-menu, #luckysheet-pivotTableFilter-submenu\").hide();\r\n });\r\n\r\n $(\"#luckysheet-pivotTableFilter-selected\").click(function () {\r\n let $t = $(this), toffset = $t.offset(), $menu = $(\"#luckysheet-pivotTableFilter-submenu\");\r\n $menu.hide();\r\n let winH = $(window).height(), winW = $(window).width();\r\n let menuW = $menu.width(), menuH = $menu.height();\r\n let top = toffset.top, left = toffset.left, mheight = winH - toffset.top - 20;\r\n if (toffset.left + menuW > winW) {\r\n left = toffset.left - menuW;\r\n }\r\n\r\n if (toffset.top > winH / 2) {\r\n top = winH - toffset.top;\r\n if (top < 0) {\r\n top = 0;\r\n }\r\n\r\n mheight = toffset.top - 20;\r\n }\r\n\r\n $menu.css({ \"top\": top, \"left\": left, \"height\": mheight }).show();\r\n clearTimeout(hidefilersubmenu);\r\n });\r\n\r\n //按条件过滤\r\n $(\"#luckysheet-pivotTableFilter-submenu\").mouseover(function () {\r\n clearTimeout(hidefilersubmenu);\r\n }).find(\".luckysheet-cols-menuitem\").click(function (e) {\r\n $(\"#luckysheet-pivotTableFilter-selected span\").html($(this).find(\".luckysheet-cols-menuitem-content\").text()).data(\"value\", $(this).data(\"value\"));\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input\").hide();\r\n if ($(this).data(\"type\") == \"2\") {\r\n $(\"#luckysheet-pivotTableFilter-selected span\").data(\"type\", \"2\");\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input2\").show();\r\n }\r\n else if ($(this).data(\"type\") == \"0\") {\r\n $(\"#luckysheet-pivotTableFilter-selected span\").data(\"type\", \"0\");\r\n }\r\n else {\r\n $(\"#luckysheet-pivotTableFilter-selected span\").data(\"type\", \"1\");\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input\").eq(0).show();\r\n //若是日期 改变input type类型为date\r\n if($(this).attr(\"data-value\") == \"dateequal\" || $(this).attr(\"data-value\") == \"datelessthan\" || $(this).attr(\"data-value\") == \"datemorethan\"){\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input input\").prop(\"type\", \"date\");\r\n }\r\n else{\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input input\").prop(\"type\", \"text\");\r\n }\r\n }\r\n $(\"#luckysheet-pivotTableFilter-byvalue\").next().slideUp();\r\n $(\"#luckysheet-pivotTableFilter-submenu\").hide();\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-pivotTable-list\").on(\"click\", \" .luckysheet-slider-list-item-filter\", function (e) {\r\n _this.luckysheetsliderlistitemfilter($(this));\r\n e.stopPropagation();\r\n return false;\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-pivotTable-list\").on(\"click\", \" .luckysheet-slider-list-item-filtered\", function (e) {\r\n _this.luckysheetsliderlistclearfilter($(this).next());\r\n e.stopPropagation();\r\n return false;\r\n });\r\n\r\n $(\"#luckysheet-dialog-pivotTable-range-seleted\").click(function () {\r\n $(\"#luckysheet-modal-dialog-slider-pivot\").hide();\r\n luckysheetsizeauto();\r\n let $t = $(\"#luckysheet-data-pivotTable-selection\"), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n\r\n $(\"#luckysheet-data-pivotTable-selection\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 4 }).show();\r\n\r\n _this.jgridCurrentPivotInput = $(\"#luckysheet-dialog-pivotTable-range\").html();\r\n $(\"#luckysheet-pivotTable-range-selection-input\").val(_this.jgridCurrentPivotInput);\r\n _this.luckysheet_pivotTable_select_state = true;\r\n });\r\n\r\n //清除筛选按钮\r\n $(\"#luckysheet-pivotTableFilter-initial\").click(function () {\r\n $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-slider-list-item-filtered\").hide();\r\n $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").data(\"rowhidden\", \"\");\r\n $(\"#luckysheet-pivotTableFilter-menu, #luckysheet-pivotTableFilter-submenu\").hide();\r\n $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input\").hide().find(\"input\").val();\r\n $(\"#luckysheet-pivotTableFilter-selected span\").data(\"type\", \"0\").data(\"type\", null).text(locale_filter.filiterInputNone);\r\n\r\n _this.setDatatojsfile(\"filterparm\", null);\r\n _this.celldata = _this.origindata;\r\n\r\n _this.refreshPivotTable();\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column\").on(\"click\", \".luckysheet-modal-dialog-slider-config-item-icon\", function (e) {\r\n let $t = $(e.target), \r\n $item = $t.closest(\".luckysheet-modal-dialog-slider-config-item\"), \r\n cindex = $item.data(\"index\"), \r\n toffset = $item.offset();\r\n let order = $item.data(\"order\"), \r\n orderby = $item.data(\"orderby\"), \r\n stastic = $item.data(\"stastic\");\r\n \r\n if (order == null) {\r\n order = \"default\";\r\n }\r\n\r\n let option = '';\r\n\r\n $(\"#luckysheet-modal-dialog-config-value .luckysheet-modal-dialog-slider-config-item\").each(function (i) {\r\n option += '';\r\n });\r\n $(\"#luckysheet-pivotTable-config-option-orderby\").empty().html(option);\r\n \r\n if (orderby == null) {\r\n orderby = \"self\";\r\n }\r\n\r\n if (stastic == null) {\r\n stastic = \"1\";\r\n }\r\n\r\n $(\"#luckysheet-pivotTable-config-option-order\").val(order).data(\"index\", cindex);\r\n $(\"#luckysheet-pivotTable-config-option-orderby\").val(orderby).data(\"index\", cindex);\r\n $(\"#luckysheet-pivotTable-config-option-stastic\").val(stastic).data(\"index\", cindex);\r\n\r\n mouseclickposition($(\"#luckysheet-pivotTable-config-option\"), toffset.left + $item.outerWidth(), toffset.top - 13, \"rightbottom\");\r\n e.stopPropagation();\r\n return false;\r\n });\r\n\r\n $(\"#luckysheet-pivotTable-config-option-order,#luckysheet-pivotTable-config-option-orderby,#luckysheet-pivotTable-config-option-stastic\").change(function () {\r\n let $t = $(this), cindex = $t.data(\"index\");\r\n \r\n $(\"#luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column\").find(\".luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n if ($(this).data(\"index\") == cindex) {\r\n $(this).data($t.attr(\"id\").replace(\"luckysheet-pivotTable-config-option-\", \"\"), $t.val());\r\n }\r\n });\r\n\r\n _this.refreshPivotTable();\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-config-value\").on(\"click\", \".luckysheet-modal-dialog-slider-config-item-icon\", function (e) {\r\n let $t = $(e.target), \r\n $item = $t.closest(\".luckysheet-modal-dialog-slider-config-item\"), \r\n cindex = $item.data(\"index\"), \r\n toffset = $item.offset(), \r\n sumtype = $item.data(\"sumtype\");\r\n \r\n let type = _this.pivot_data_type[cindex.toString()];\r\n if (sumtype == null) {\r\n if (type == \"num\") {\r\n sumtype = \"SUM\";\r\n }\r\n else {\r\n sumtype = \"COUNTA\";\r\n }\r\n }\r\n\r\n let $menu = $(\"#luckysheet-pivotTable-config-option-sumtype\");\r\n $menu.find(\".luckysheet-submenu-arrow\").hide();\r\n $menu.find(\".luckysheet-cols-menuitem[sumtype='\" + sumtype + \"'] .luckysheet-submenu-arrow\").css(\"display\", \"inline\");\r\n $menu.data(\"item\", $item);\r\n\r\n mouseclickposition($menu, toffset.left + $item.outerWidth(), toffset.top - 13, \"rightbottom\");\r\n e.stopPropagation();\r\n return false;\r\n });\r\n\r\n $(\"#luckysheet-pivotTable-config-option-sumtype .luckysheet-cols-menuitem\").click(function () {\r\n let $item = $(\"#luckysheet-pivotTable-config-option-sumtype\").data(\"item\");\r\n let sumtype = $(this).attr(\"sumtype\");\r\n $item.data(\"sumtype\", $(this).attr(\"sumtype\"));\r\n let name = _this.getSumTypeName(sumtype) + \":\" + $item.data(\"name\");\r\n $item.attr(\"title\", name).find(\".luckysheet-modal-dialog-slider-config-item-txt\").html(name);\r\n $(\"#luckysheet-pivotTable-config-option-sumtype\").hide();\r\n _this.refreshPivotTable();\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-config-filter\").on(\"click\", \".luckysheet-modal-dialog-slider-config-item-icon\", function (e) {\r\n let $t = $(e.target), \r\n cindex = $t.closest(\".luckysheet-modal-dialog-slider-config-item\").data(\"index\");\r\n _this.luckysheetsliderlistitemfilter($(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").eq(cindex).find(\".luckysheet-slider-list-item-filter\"));\r\n e.stopPropagation();\r\n return false;\r\n });\r\n\r\n //确认按钮\r\n $(\"#luckysheet-pivotTableFilter-confirm\").click(function () {\r\n let $menu = $(\"#luckysheet-pivotTableFilter-menu\");\r\n let cindex = $menu.data(\"index\");\r\n\r\n let rowhiddenother = {}; //其它筛选列的隐藏行\r\n $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").each(function () {\r\n let $t = $(this), rh = $t.data(\"rowhidden\");\r\n\r\n if($t.data(\"index\") != cindex){\r\n if (rh == null || rh == \"\") {\r\n return true;\r\n }\r\n\r\n if(getObjType(rh) == \"string\"){\r\n rh = JSON.parse(rh);\r\n }\r\n \r\n for (let r in rh) {\r\n rowhiddenother[r] = 0;\r\n }\r\n }\r\n });\r\n\r\n let d = _this.origindata;\r\n\r\n let filterdata = {};\r\n let rowhidden = {};\r\n let caljs = {};\r\n\r\n if ($(\"#luckysheet-pivotTableFilter-bycondition\").next().is(\":visible\") && $(\"#luckysheet-pivotTableFilter-byvalue\").next().is(\":hidden\") && $(\"#luckysheet-pivotTableFilter-selected span\").data(\"value\") != \"null\") {\r\n let $t = $(\"#luckysheet-pivotTableFilter-selected span\");\r\n let type = $t.data(\"type\"), value = $t.data(\"value\");\r\n\r\n caljs[\"value\"] = value;\r\n caljs[\"text\"] = $t.text();\r\n\r\n if (type == \"0\") {\r\n caljs[\"type\"] = \"0\";\r\n }\r\n else if (type == \"2\") {\r\n let $input = $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input2 input\");\r\n caljs[\"type\"] = \"2\";\r\n caljs[\"value1\"] = $input.eq(0).val();\r\n caljs[\"value2\"] = $input.eq(1).val();\r\n }\r\n else {\r\n caljs[\"type\"] = \"1\";\r\n caljs[\"value1\"] = $(\"#luckysheet-pivotTableFilter-menu .luckysheet-pivotTableFilter-selected-input\").eq(0).find(\"input\").val();\r\n }\r\n\r\n for (let r = 1; r < d.length; r++) {\r\n if(r in rowhiddenother){\r\n continue;\r\n }\r\n\r\n if(d[r] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][cindex];\r\n \r\n if (value == \"cellnull\") { //单元格为空\r\n if(cell != null && !isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"cellnonull\") { //单元格有数据\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"textinclude\") { //文本包含 \r\n let value1 = caljs[\"value1\"];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(cell.m.indexOf(value1) == -1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textnotinclude\") { //文本不包含\r\n let value1 = caljs[\"value1\"];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n\r\n }\r\n else{\r\n if(cell.m.indexOf(value1) > -1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textstart\") { //文本开头为\r\n let value1 = caljs[\"value1\"], valuelen = value1.length;\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(cell.m.substr(0, valuelen) != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textend\") { //文本结尾为\r\n let value1 = caljs[\"value1\"], valuelen = value1.length;\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(valuelen > cell.m.length || cell.m.substr(cell.m.length - valuelen, valuelen) != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"textequal\") { //文本等于\r\n let value1 = caljs[\"value1\"];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else{\r\n if(cell.m != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n else if (value == \"dateequal\") { //日期等于\r\n let value1 = genarate(caljs[\"value1\"])[2];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n if(parseInt(cell.v) != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"datelessthan\") { //日期早于\r\n let value1 = genarate(caljs[\"value1\"])[2];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n if(parseInt(cell.v) >= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"datemorethan\") { //日期晚于\r\n let value1 = genarate(caljs[\"value1\"])[2];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n if(parseInt(cell.v) <= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"morethan\") { //大于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v <= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"moreequalthan\") { //大于等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v < value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"lessthan\") { //小于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v >= value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"lessequalthan\") { //小于等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v > value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"equal\") { //等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v != value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"noequal\") { //不等于\r\n let value1 = parseFloat(caljs[\"value1\"]);\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v == value1){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"include\") { //介于\r\n let value1 = parseFloat(caljs[\"value1\"]), value2 = parseFloat(caljs[\"value2\"]);\r\n\r\n let min, max;\r\n if(value1 < value2){\r\n min = value1;\r\n max = value2;\r\n }\r\n else{\r\n max = value1;\r\n min = value2; \r\n }\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v < min || cell.v > max){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else if (value == \"noinclude\") { //不在其中\r\n let value1 = parseFloat(caljs[\"value1\"]), value2 = parseFloat(caljs[\"value2\"]);\r\n\r\n let min, max;\r\n if(value1 < value2){\r\n min = value1;\r\n max = value2;\r\n }\r\n else{\r\n max = value1;\r\n min = value2; \r\n }\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n rowhidden[r] = 0;\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"n\"){\r\n if(cell.v >= min && cell.v <= max){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n else{\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']\").each(function(i, e){\r\n if($(e).is(\":visible\") && $(e).is(\":checked\")){\r\n return true;\r\n }\r\n\r\n if($(e).closest(\".day\").length > 0){\r\n let day = $(e).siblings(\"label\").text();\r\n if(Number(day) < 10){\r\n day = \"0\" + day;\r\n }\r\n\r\n let month = $(e).closest(\".monthBox\").find(\".month label\").text().replace(locale_filter.filiterMonthText, \"\");\r\n if(Number(month) < 10){\r\n month = \"0\" + month;\r\n }\r\n\r\n let year = $(e).closest(\".yearBox\").find(\".year label\").text().replace(locale_filter.filiterYearText, \"\");\r\n\r\n let itemV = locale_filter.filterDateFormatTip+\"#$$$#\" + year + \"-\" + month + \"-\" + day;\r\n\r\n filterdata[itemV] = \"1\";\r\n }\r\n\r\n if($(e).closest(\".textBox\").length > 0){\r\n let itemV = $(e).closest(\".textBox\").data(\"filter\");\r\n\r\n filterdata[itemV] = \"1\";\r\n }\r\n })\r\n\r\n for (let r = 1; r < d.length; r++) {\r\n if(r in rowhiddenother){\r\n continue;\r\n }\r\n\r\n if(d[r] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][cindex];\r\n\r\n let value;\r\n if(cell == null || isRealNull(cell.v)){\r\n value = \"null#$$$#null\";\r\n }\r\n else if(cell.ct != null && cell.ct.t == \"d\"){\r\n let fmt = update(\"YYYY-MM-DD\", cell.v);\r\n value = locale_filter.filterDateFormatTip+\"#$$$#\" + fmt;\r\n }\r\n else{\r\n value = cell.v + \"#$$$#\" + cell.m;\r\n }\r\n\r\n if(value in filterdata){\r\n rowhidden[r] = 0;\r\n }\r\n }\r\n }\r\n\r\n let $top = $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").eq(cindex);\r\n if ($(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']:visible:checked\").length < $(\"#luckysheet-pivotTableFilter-byvalue-select .ListBox input[type='checkbox']:visible\").length || $(\"#luckysheet-pivotTableFilter-byvalue-input\").val().length > 0 || ($(\"#luckysheet-pivotTableFilter-bycondition\").next().is(\":visible\") && $(\"#luckysheet-pivotTableFilter-byvalue\").next().is(\":hidden\") && $(\"#luckysheet-pivotTableFilter-selected span\").data(\"value\") != \"null\")) {\r\n $top.data(\"rowhidden\", JSON.stringify(rowhidden)).find(\".luckysheet-slider-list-item-filtered\").show();\r\n _this.setDatatojsfile(\"rowhidden\", rowhidden, cindex);\r\n\r\n if (caljs != null) {\r\n $top.data(\"byconditionvalue\", caljs[\"value\"]).data(\"byconditiontype\", caljs[\"type\"]).data(\"byconditiontext\", caljs[\"text\"]);\r\n \r\n if (caljs[\"value1\"] != null) {\r\n $top.data(\"byconditionvalue1\", caljs[\"value1\"]);\r\n }\r\n\r\n if (caljs[\"value2\"] != null) {\r\n $top.data(\"byconditionvalue2\", caljs[\"value2\"]);\r\n }\r\n\r\n _this.setDatatojsfile(\"caljs\", caljs, cindex);\r\n }\r\n }\r\n else {\r\n $top.data(\"rowhidden\", \"\").find(\".luckysheet-slider-list-item-filtered\").hide();\r\n _this.setDatatojsfile(\"rowhidden\", null, cindex);\r\n }\r\n\r\n let newdata = [];\r\n for (let i = 0; i < d.length; i++) {\r\n if(i in rowhidden || i in rowhiddenother){\r\n continue;\r\n }\r\n\r\n newdata.push([].concat(d[i]));\r\n }\r\n\r\n _this.celldata = newdata;\r\n _this.refreshPivotTable();\r\n $(\"#luckysheet-pivotTableFilter-menu, #luckysheet-pivotTableFilter-submenu\").hide();\r\n\r\n cleargridelement();\r\n });\r\n\r\n $(\"#luckysheet-data-pivotTable-selection .luckysheet-model-close-btn, #luckysheet-data-pivotTable-selection .luckysheet-modal-dialog-title-close\").click(function () {\r\n $(\"#luckysheet-modal-dialog-slider-pivot\").show();\r\n luckysheetsizeauto();\r\n $(\"#luckysheet-cell-main .luckysheet-pivotTable-selection-set div\").show();\r\n\r\n $(\"#luckysheet-data-pivotTable-selection\").hide();\r\n\r\n sheetmanage.changeSheetExec(_this.pivotSheetIndex);\r\n\r\n _this.luckysheet_pivotTable_select_state = false;\r\n\r\n cleargridelement();\r\n });\r\n\r\n $(\"#luckysheet-pivotTable-selection-confirm\").click(function () {\r\n let $input = $(\"#luckysheet-pivotTable-range-selection-input\"), val = $input.val();\r\n\r\n if ($.trim(val).length == 0 || $.trim(val).toUpperCase() == _this.jgridCurrentPivotInput.toUpperCase()) {\r\n $input.val(_this.jgridCurrentPivotInput);\r\n $(\"#luckysheet-data-pivotTable-selection .luckysheet-model-close-btn\").click();\r\n return;\r\n }\r\n else {\r\n let val1 = val.split(\"!\");\r\n let sheettxt = \"\", rangetxt = \"\", sheetIndex = -1;\r\n\r\n if (val1.length > 1) {\r\n sheettxt = val1[0];\r\n rangetxt = val1[1];\r\n\r\n for (let i in Store.luckysheetfile) {\r\n if (sheettxt == Store.luckysheetfile[i].name) {\r\n sheetIndex = Store.luckysheetfile[i].index;\r\n break;\r\n }\r\n }\r\n\r\n if (sheetIndex == -1) {\r\n sheetIndex = 0;\r\n }\r\n }\r\n else {\r\n let index = getSheetIndex(Store.currentSheetIndex);\r\n sheettxt = Store.luckysheetfile[index].name;\r\n sheetIndex = Store.luckysheetfile[index].index;\r\n rangetxt = val1[0];\r\n }\r\n\r\n if(Store.luckysheetfile[getSheetIndex(sheetIndex)].isPivotTable){\r\n if(isEditMode()){\r\n alert(locale_pivotTable.errorNotAllowPivotData);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_pivotTable.errorNotAllowPivotData); \r\n }\r\n $input.val(_this.jgridCurrentPivotInput);\r\n return;\r\n }\r\n\r\n if (rangetxt.indexOf(\":\") == -1) {\r\n if(isEditMode()){\r\n alert(locale_pivotTable.errorSelectionRange);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_pivotTable.errorSelectionRange); \r\n }\r\n $input.val(_this.jgridCurrentPivotInput);\r\n return;\r\n }\r\n\r\n rangetxt = rangetxt.split(\":\");\r\n let row = [], col = [];\r\n \r\n row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, \"\")) - 1;\r\n row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, \"\")) - 1;\r\n\r\n if (row[0] > row[1]) {\r\n if(isEditMode()){\r\n alert(locale_pivotTable.errorSelectionRange);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_pivotTable.errorSelectionRange); \r\n }\r\n $input.val(_this.jgridCurrentPivotInput);\r\n return;\r\n }\r\n\r\n col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, \"\"));\r\n col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, \"\"));\r\n\r\n if (col[0] > col[1]) {\r\n if(isEditMode()){\r\n alert(locale_pivotTable.errorSelectionRange);\r\n }\r\n else{\r\n tooltip.info(locale_pivotTable.errorSelectionRange); \r\n }\r\n $input.val(_this.jgridCurrentPivotInput);\r\n return;\r\n }\r\n sheetmanage.changeSheetExec(_this.pivotSheetIndex);\r\n\r\n _this.setDatatojsfile(\"pivot_select_save\", { \"row\": row, \"column\": col });\r\n _this.setDatatojsfile(\"pivotDataSheetIndex\", sheetIndex);\r\n\r\n _this.getCellData(_this.pivotSheetIndex, sheetIndex, { \"row\": row, \"column\": col });\r\n\r\n _this.initialPivotManage();\r\n\r\n $(\"#luckysheet-dialog-pivotTable-range\").html(val);\r\n\r\n $(\"#luckysheet-modal-dialog-slider-pivot\").show();\r\n\r\n $(\"#luckysheet-data-pivotTable-selection\").hide();\r\n\r\n _this.luckysheet_pivotTable_select_state = false;\r\n\r\n _this.refreshPivotTable();\r\n\r\n luckysheetsizeauto();\r\n\r\n cleargridelement();\r\n }\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-slider-pivot\").on(\"mousedown\", \".luckysheet-slider-list-item-name, .luckysheet-modal-dialog-slider-config-item-txt\", function (e) {\r\n let $cur = $(e.target);\r\n _this.movestate = true;\r\n _this.movesave.obj = $cur.parent();\r\n _this.movesave.name = $cur.data(\"name\");\r\n _this.movesave.containerid = $cur.parent().parent().attr(\"id\");\r\n _this.movesave.index = $cur.data(\"index\");\r\n \r\n if ($(\"#luckysheet-modal-dialog-slider-pivot-move\").length == 0) {\r\n $(\"body\").append('
' + _this.movesave.name + '
');\r\n }\r\n\r\n _this.movesave.width = $(\"#luckysheet-modal-dialog-slider-pivot-move\").outerWidth();\r\n _this.movesave.height = $(\"#luckysheet-modal-dialog-slider-pivot-move\").outerHeight();\r\n\r\n $(\"#luckysheet-modal-dialog-pivotTable-list, #luckysheet-modal-dialog-config-filter, #luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column, #luckysheet-modal-dialog-config-value\").css(\"cursor\", \"default\");\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-config-filter, #luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column, #luckysheet-modal-dialog-config-value\").mousemove(function (e) {\r\n if (_this.movestate) {\r\n if (_this.moveitemposition.length == 0) {\r\n _this.moveitemposition = [0];\r\n \r\n $(this).find(\".luckysheet-modal-dialog-slider-config-item\").each(function (i) {\r\n let $t = $(this), h = $t.outerHeight();\r\n _this.moveitemposition.push(_this.moveitemposition[i] + h + 2);\r\n });\r\n $(this).append('
');\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-slider-pivot-move\").css({ \"background\": \"#FD8585\", \"color\": \"#fff\", \"border\": \"1px solid #FD7070\" });\r\n let x = event.pageX, y = event.pageY, $container = $(this);\r\n let curtop = y - $container.offset().top + $container.scrollTop();\r\n let position = _this.moveitemposition;\r\n let row_index = luckysheet_searcharray(position, curtop);\r\n\r\n if (row_index == -1) {\r\n $(\"#luckysheet-modal-dialog-config-order-help\").css({ \"top\": position[position.length - 1] });\r\n }\r\n else if ((curtop - position[row_index - 1]) > (position[row_index] - position[row_index - 1]) / 2) {\r\n $(\"#luckysheet-modal-dialog-config-order-help\").css({ \"top\": position[row_index] });\r\n }\r\n else {\r\n $(\"#luckysheet-modal-dialog-config-order-help\").css({ \"top\": position[row_index - 1] });\r\n }\r\n }\r\n }).mouseleave(function () {\r\n if (_this.movestate) {\r\n $(\"#luckysheet-modal-dialog-slider-pivot-move\").css({ \"background\": \"#fff\", \"color\": \"#000\", \"border\": \"1px dotted #000\" });\r\n _this.moveitemposition = [];\r\n $(\"#luckysheet-modal-dialog-config-order-help\").remove();\r\n }\r\n }).mouseup(function (e) {\r\n if (_this.movestate) {\r\n let $t = $(this);\r\n let itemHTML;\r\n\r\n if (_this.movesave.containerid == $t.attr(\"id\")) {\r\n itemHTML = _this.movesave.obj.clone();\r\n }\r\n else {\r\n let name = _this.movesave.name, \r\n sumtype = \"\", \r\n nameindex = \"\";\r\n \r\n if ($t.attr(\"id\") == \"luckysheet-modal-dialog-config-value\") {\r\n let type = _this.pivot_data_type[_this.movesave.index.toString()];\r\n \r\n if (type == \"num\") {\r\n name = locale_pivotTable.valueStatisticsSUM+\":\" + name;\r\n sumtype = \"data-sumtype='SUM'\";\r\n nameindex = \"data-nameindex='0'\";\r\n }\r\n else {\r\n name = locale_pivotTable.valueStatisticsCOUNTA+\":\" + name;\r\n sumtype = \"data-sumtype='COUNTA'\";\r\n nameindex = \"data-nameindex='0'\";\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-config-value\").find(\".luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n if ($(this).find(\".luckysheet-modal-dialog-slider-config-item-txt\").text() == name) {\r\n let ni = parseFloat($(this).data(\"nameindex\")) + 1;\r\n name = name + ni.toString();\r\n $(this).data(\"nameindex\", ni);\r\n return false;\r\n }\r\n });\r\n }\r\n\r\n itemHTML = '
' + name + '
';\r\n }\r\n\r\n let x = event.pageX, y = event.pageY, $container = $(this);\r\n let curtop = y - $container.offset().top + $container.scrollTop();\r\n let position = _this.moveitemposition;\r\n let row_index = luckysheet_searcharray(position, curtop);\r\n\r\n if ((_this.movesave.containerid == \"luckysheet-modal-dialog-pivotTable-list\") || (_this.movesave.containerid == \"luckysheet-modal-dialog-config-value\" && _this.movesave.containerid != $t.attr(\"id\"))) {\r\n $(\"#luckysheet-modal-dialog-config-filter, #luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column\").find(\".luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n if ($(this).data(\"index\") == _this.movesave.index) {\r\n $(this).remove();\r\n }\r\n });\r\n }\r\n\r\n if (row_index == -1) {\r\n if ($t.find(\".luckysheet-modal-dialog-slider-config-item\").length == 0) {\r\n $t.append(itemHTML);\r\n }\r\n else {\r\n $t.find(\".luckysheet-modal-dialog-slider-config-item\").last().after(itemHTML);\r\n }\r\n\r\n }\r\n else if ((curtop - position[row_index - 1]) > (position[row_index] - position[row_index - 1]) / 2) {\r\n $t.find(\".luckysheet-modal-dialog-slider-config-item\").eq(row_index - 1).after(itemHTML);\r\n }\r\n else {\r\n $t.find(\".luckysheet-modal-dialog-slider-config-item\").eq(row_index - 1).before(itemHTML);\r\n }\r\n\r\n if (_this.movesave.containerid == \"luckysheet-modal-dialog-pivotTable-list\") {\r\n\r\n }\r\n else if (_this.movesave.containerid == \"luckysheet-modal-dialog-config-value\" && _this.movesave.containerid != $t.attr(\"id\")) {\r\n\r\n }\r\n else {\r\n _this.movesave.obj.remove();\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-pivotTable-list\").find(\".luckysheet-modal-dialog-slider-list-item\").each(function () {\r\n let $seleted = $(this).find(\".luckysheet-slider-list-item-selected\");\r\n if ($(this).data(\"index\") == _this.movesave.index && $seleted.find(\"i\").length == 0) {\r\n $seleted.append('');\r\n }\r\n });\r\n\r\n _this.refreshPivotTable();\r\n\r\n $(\"#luckysheet-modal-dialog-slider-pivot-move\").remove();\r\n _this.movestate = false;\r\n $(\"#luckysheet-modal-dialog-pivotTable-list, #luckysheet-modal-dialog-config-filter, #luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column, #luckysheet-modal-dialog-config-value\").css(\"cursor\", \"default\");\r\n _this.moveitemposition = [];\r\n $(\"#luckysheet-modal-dialog-config-order-help\").remove();\r\n _this.showvaluecolrow();\r\n e.stopPropagation();\r\n }\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-pivotTable-list\").on(\"click\", \".luckysheet-slider-list-item-selected\", function () {\r\n let $t = $(this), \r\n $item = $t.parent(), \r\n index = $item.data(\"index\"), \r\n name = $item.data(\"name\");\r\n \r\n if ($t.find(\"i\").length == 0) {\r\n $t.append('');\r\n\r\n let type = _this.pivot_data_type[index.toString()], \r\n itemHTML;\r\n\r\n if (type == \"num\") {\r\n itemHTML = '
求和:' + name + '
';\r\n $(\"#luckysheet-modal-dialog-config-value\").append(itemHTML);\r\n }\r\n else {\r\n itemHTML = '
' + name + '
';\r\n \r\n let $column = $(\"#luckysheet-modal-dialog-config-column\"), \r\n $row = $(\"#luckysheet-modal-dialog-config-row\");\r\n let columnitem = $column.find(\".luckysheet-modal-dialog-slider-config-item\"), \r\n rowitem = $row.find(\".luckysheet-modal-dialog-slider-config-item\");\r\n\r\n if (columnitem.length < 2) {\r\n $column.append(itemHTML);\r\n }\r\n else if (rowitem.length < 2) {\r\n $row.append(itemHTML);\r\n }\r\n else {\r\n $column.append(itemHTML);\r\n }\r\n }\r\n }\r\n else {\r\n $t.find(\"i\").remove();\r\n $(\"#luckysheet-modal-dialog-config-filter, #luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column, #luckysheet-modal-dialog-config-value\").find(\".luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n if ($(this).data(\"index\") == index) {\r\n if ($(this).parent().attr(\"id\") == \"luckysheet-modal-dialog-config-value\") {\r\n _this.resetOrderby($(this));\r\n }\r\n $(this).remove();\r\n }\r\n });\r\n }\r\n\r\n _this.refreshPivotTable();\r\n _this.showvaluecolrow();\r\n });\r\n\r\n $(\"#luckysheet-dialog-pivotTable-clearitem\").click(function () {\r\n $(\"#luckysheet-modal-dialog-config-filter, #luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column, #luckysheet-modal-dialog-config-value\").find(\".luckysheet-modal-dialog-slider-config-item\").each(function () {\r\n $(this).remove();\r\n });\r\n\r\n $(\"#luckysheet-modal-dialog-pivotTable-list\").find(\".luckysheet-modal-dialog-slider-list-item\").each(function () {\r\n $(this).find(\".luckysheet-slider-list-item-selected\").find(\"i\").remove();\r\n });\r\n\r\n _this.refreshPivotTable();\r\n _this.showvaluecolrow();\r\n });\r\n }\r\n\r\n if (restore == null) {\r\n restore = false;\r\n }\r\n\r\n if (_this.celldata.length <= 1 && _this.celldata[0].length <= 1) {\r\n if(isEditMode()){\r\n alert(locale_pivotTable.errorIncreaseRange);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_pivotTable.errorIncreaseRange);\r\n }\r\n }\r\n\r\n let selecteditem = \"\", \r\n selecteditemIndex = 1, \r\n selecteditemtest = {}, \r\n selecteditemNullIndex = 1;\r\n\r\n for (let i = 0; i < _this.celldata[0].length; i++) {\r\n let name;\r\n if(!!_this.celldata[0][i] && !!_this.celldata[0][i][\"m\"]){\r\n name = _this.celldata[0][i][\"m\"];\r\n }\r\n else{\r\n name = getcellvalue(0, i, _this.celldata); \r\n }\r\n\r\n if(name != null){\r\n name = name.toString();\r\n }\r\n\r\n if (name == null || $.trim(name.toString()).length == 0) {\r\n name = locale_pivotTable.titleColumn+\" \" + selecteditemNullIndex;\r\n }\r\n selecteditemNullIndex++\r\n\r\n if (name in selecteditemtest) {\r\n name = name + selecteditemIndex++;\r\n if (name in selecteditemtest) {\r\n name = name + selecteditemIndex++;\r\n if (name in selecteditemtest) {\r\n name = name + selecteditemIndex++;\r\n }\r\n }\r\n }\r\n selecteditemtest[name] = 1;\r\n\r\n let dataother = \"\", style = \"\";\r\n\r\n if (restore && _this.filterparm != null) {\r\n if (_this.filterparm[i.toString()] != null) {\r\n let itemset = _this.filterparm[i.toString()];\r\n if (itemset.rowhidden != null) {\r\n dataother += \"data-rowhidden='\" + JSON.stringify(itemset.rowhidden) + \"'\";\r\n }\r\n\r\n if (itemset.selected != null) {\r\n dataother += \"data-selected='\" + JSON.stringify(itemset.selected) + \"'\";\r\n }\r\n\r\n if (itemset.caljs != null) {\r\n let caljsset = itemset.caljs;\r\n if (caljsset.value != null) {\r\n dataother += \"data-byconditionvalue='\" + caljsset.value + \"'\";\r\n }\r\n\r\n if (caljsset.type != null) {\r\n dataother += \"data-byconditiontype='\" + caljsset.type + \"'\";\r\n }\r\n\r\n if (caljsset.text != null) {\r\n dataother += \"data-byconditiontext='\" + caljsset.text + \"'\";\r\n }\r\n\r\n if (caljsset.value1 != null) {\r\n dataother += \"data-byconditionvalue1='\" + caljsset.value1 + \"'\";\r\n }\r\n\r\n if (caljsset.value2 != null) {\r\n dataother += \"data-byconditionvalue2='\" + caljsset.value2 + \"'\";\r\n }\r\n\r\n }\r\n }\r\n }\r\n\r\n if (dataother.length > 0) {\r\n style = \"display:block;\";\r\n }\r\n\r\n selecteditem += '
' + name + '
';\r\n }\r\n $(\"#luckysheet-modal-dialog-pivotTable-list\").html(selecteditem);\r\n\r\n $(\"#luckysheetpivottablevaluecolrowshow\").hide();\r\n $(\"#luckysheetpivottablevaluecolrow\").prop(\"checked\", true);\r\n $(\"#luckysheetpivottablevaluecolrow1\").prop(\"checked\", false);\r\n\r\n $(\"#luckysheet-modal-dialog-config-filter, #luckysheet-modal-dialog-config-row, #luckysheet-modal-dialog-config-column, #luckysheet-modal-dialog-config-value\").empty();\r\n \r\n if (restore) {\r\n if (_this.filter != null && _this.filter.length > 0) {\r\n for (let i = 0; i < _this.filter.length; i++) {\r\n let item = _this.filter[i];\r\n\r\n let itemHTML = '
' + item.name + '
';\r\n\r\n $(\"#luckysheet-modal-dialog-config-filter\").append(itemHTML);\r\n\r\n let $seleted = $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").eq(item.index).find(\".luckysheet-slider-list-item-selected\");\r\n if ($seleted.find(\"i\").length == 0) {\r\n $seleted.append('');\r\n }\r\n }\r\n }\r\n\r\n if (_this.row != null && _this.row.length > 0) {\r\n for (let i = 0; i < _this.row.length; i++) {\r\n let item = _this.row[i];\r\n let otherset = \"\";\r\n\r\n if (item.order != null) {\r\n otherset += \"data-order = '\" + item.order + \"'\";\r\n }\r\n\r\n if (item.orderby != null) {\r\n otherset += \"data-orderby = '\" + item.orderby + \"'\";\r\n }\r\n\r\n if (item.order != null) {\r\n otherset += \"data-stastic = '\" + item.stastic + \"'\";\r\n }\r\n\r\n let itemHTML = '
' + item.name + '
';\r\n\r\n $(\"#luckysheet-modal-dialog-config-row\").append(itemHTML);\r\n\r\n let $seleted = $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").eq(item.index).find(\".luckysheet-slider-list-item-selected\");\r\n if ($seleted.find(\"i\").length == 0) {\r\n $seleted.append('');\r\n }\r\n }\r\n }\r\n\r\n if (_this.column != null && _this.column.length > 0) {\r\n for (let i = 0; i < _this.column.length; i++) {\r\n let item = _this.column[i];\r\n let otherset = \"\";\r\n\r\n if (item.order != null) {\r\n otherset += \"data-order = '\" + item.order + \"'\";\r\n }\r\n\r\n if (item.orderby != null) {\r\n otherset += \"data-orderby = '\" + item.orderby + \"'\";\r\n }\r\n\r\n if (item.order != null) {\r\n otherset += \"data-stastic = '\" + item.stastic + \"'\";\r\n }\r\n\r\n let itemHTML = '
' + item.name + '
';\r\n\r\n $(\"#luckysheet-modal-dialog-config-column\").append(itemHTML);\r\n\r\n let $seleted = $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").eq(item.index).find(\".luckysheet-slider-list-item-selected\");\r\n if ($seleted.find(\"i\").length == 0) {\r\n $seleted.append('');\r\n }\r\n }\r\n }\r\n\r\n if (_this.values != null && _this.values.length > 0) {\r\n for (let i = 0; i < _this.values.length; i++) {\r\n let item = _this.values[i];\r\n let otherset = \"\";\r\n\r\n if (item.sumtype != null) {\r\n otherset += \"data-sumtype = '\" + item.sumtype + \"'\";\r\n }\r\n\r\n if (item.nameindex != null) {\r\n otherset += \"data-nameindex = '\" + item.nameindex + \"'\";\r\n }\r\n\r\n let itemHTML = '
' + _this.getSumTypeName(item.sumtype) + \":\" + item.name + '
';\r\n\r\n $(\"#luckysheet-modal-dialog-config-value\").append(itemHTML);\r\n\r\n let $seleted = $(\"#luckysheet-modal-dialog-pivotTable-list .luckysheet-modal-dialog-slider-list-item\").eq(item.index).find(\".luckysheet-slider-list-item-selected\");\r\n if ($seleted.find(\"i\").length == 0) {\r\n $seleted.append('');\r\n }\r\n }\r\n\r\n if (_this.values.length >= 2) {\r\n $(\"#luckysheetpivottablevaluecolrowshow\").show();\r\n if (_this.showType == \"column\") {\r\n $(\"#luckysheetpivottablevaluecolrow\").prop(\"checked\", true);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow']\").addClass(\"ui-state-active\");\r\n\r\n $(\"#luckysheetpivottablevaluecolrow1\").prop(\"checked\", false);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow1']\").removeClass(\"ui-state-active\");\r\n }\r\n else {\r\n $(\"#luckysheetpivottablevaluecolrow1\").prop(\"checked\", true);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow1']\").addClass(\"ui-state-active\");\r\n\r\n $(\"#luckysheetpivottablevaluecolrow\").prop(\"checked\", false);\r\n $(\"#luckysheetpivottablevaluecolrowshow label[for='luckysheetpivottablevaluecolrow']\").removeClass(\"ui-state-active\");\r\n }\r\n }\r\n }\r\n }\r\n\r\n $(\"#luckysheet-dialog-pivotTable-range\").html(getRangetxt(_this.pivotDataSheetIndex, _this.pivot_select_save));\r\n $(\"#luckysheet-modal-dialog-slider-pivot\").show();\r\n \r\n luckysheetsizeauto(false);\r\n },\r\n getComposeArray: function (data) {\r\n if (data.length == 0) {\r\n return [];\r\n }\r\n \r\n let ret = [];\r\n for (let i = 0; i < data.length; i++) {\r\n let name = \"\";\r\n for (let x = 0; x <= i; x++) {\r\n if(!!data[x] && !!data[x][\"m\"]){\r\n name += data[x][\"m\"];\r\n }\r\n else{\r\n name += getcellvalue(x, null, data);\r\n }\r\n }\r\n \r\n ret.push(name);\r\n }\r\n\r\n return ret;\r\n },\r\n getnameArray: function (data, field) {\r\n if (data.length == 0) {\r\n return [];\r\n }\r\n\r\n if (field.length == 0) {\r\n return [];\r\n }\r\n\r\n let ret = [];\r\n for (let i = 0; i < field.length; i++) {\r\n let c_value;\r\n if(!!data[field[i].index] && !!data[field[i].index][\"m\"]){\r\n c_value = data[field[i].index][\"m\"];\r\n }\r\n else{\r\n c_value = getcellvalue(field[i].index, null, data);\r\n }\r\n \r\n ret.push(c_value);\r\n }\r\n\r\n return ret;\r\n },\r\n getTitleFromGroup: function (group, config, dataposition) {\r\n let _this = this;\r\n let orderbygroup = _this.orderbygroup(group, config, dataposition);\r\n\r\n return _this.generategrouparraymain(orderbygroup, config);\r\n },\r\n orderbygroup: function (group, config, dataposition) {\r\n let _this = this;\r\n\r\n let stackset = [];\r\n if (group.length == 0) {\r\n return [];\r\n }\r\n stackset = group;\r\n\r\n let d = null, \r\n alllength = stackset.length, \r\n alllengthInital = stackset.length, \r\n a = 0;\r\n\r\n while (alllength != 0) {\r\n d = stackset[a++];\r\n alllength--;\r\n\r\n if (d.children != null && d.children.length > 0) {\r\n d.children = _this.orderbygroupchildren(d.children, config[d.index].orderby, config[d.index].order, dataposition);\r\n \r\n for (let i = 0; i < d.children.length; i++) {\r\n stackset.push(d.children[i]);\r\n alllength++;\r\n }\r\n }\r\n }\r\n\r\n return group.splice(0, alllengthInital);\r\n },\r\n orderbygroupchildren: function (childrens, orderby, order, dataposition) {\r\n if (childrens.length == 0) {\r\n return [];\r\n }\r\n\r\n let isAsc = false;\r\n if (order == null || order == \"asc\") {\r\n isAsc = true;\r\n }\r\n\r\n const _locale = locale();\r\n const locale_filter = _locale.filter;\r\n\r\n let a = function (x, y) {\r\n let f = null, s = null;\r\n\r\n if (orderby == \"self\" || orderby == null) {\r\n if(x.name == null){\r\n f = locale_filter.valueBlank;\r\n }\r\n else{\r\n f = x.name.toString();\r\n }\r\n\r\n if(y.name == null){\r\n s = locale_filter.valueBlank;\r\n }\r\n else{\r\n s = y.name.toString();\r\n }\r\n \r\n if (isdatetime(f) && isdatetime(s)) {\r\n return diff(f, s);\r\n }\r\n }\r\n else {\r\n f = parseFloat(dataposition[x.orderby].result);\r\n s = parseFloat(dataposition[y.orderby].result);\r\n }\r\n\r\n if (!isNaN(f) && !isNaN(s)) {\r\n return numeral(f).value() - numeral(s).value();\r\n }\r\n else if(isNaN(f) && isNaN(s)){\r\n return f.localeCompare(s);\r\n }\r\n else if (isNaN(f)) {\r\n return 1;\r\n }\r\n else if (isNaN(s)) {\r\n return -1;\r\n }\r\n }\r\n\r\n let d = function (x, y) {\r\n let f = null, s = null;\r\n\r\n if (orderby == \"self\" || orderby == null) {\r\n if(x.name == null){\r\n f = locale_filter.valueBlank;\r\n }\r\n else{\r\n f = x.name.toString();\r\n }\r\n\r\n if(y.name == null){\r\n s = locale_filter.valueBlank;\r\n }\r\n else{\r\n s = y.name.toString();\r\n }\r\n\r\n if (isdatetime(f) && isdatetime(s)) {\r\n return diff(f, s);\r\n }\r\n }\r\n else {\r\n f = parseFloat(dataposition[x.orderby].result);\r\n s = parseFloat(dataposition[y.orderby].result);\r\n }\r\n\r\n if (!isNaN(f) && !isNaN(s)) {\r\n return numeral(s).value() - numeral(f).value();\r\n }\r\n else if(isNaN(f) && isNaN(s)){\r\n return s.localeCompare(f);\r\n }\r\n else if (isNaN(f)) {\r\n return -1;\r\n }\r\n else if (isNaN(s)) {\r\n return 1;\r\n }\r\n }\r\n\r\n if (isAsc) {\r\n return childrens.sort(a);\r\n }\r\n else {\r\n return childrens.sort(d);\r\n }\r\n },\r\n generategroupaddstatic: function (arr, name) {\r\n let stasticarr = [];\r\n const _locale = locale();\r\n const locale_pivotTable = _locale.pivotTable;\r\n for (let a = 0; a < arr[0].length; a++) {\r\n if (a == 0) {\r\n if (name == locale_pivotTable.valueSum) {\r\n stasticarr.push(name);\r\n }\r\n else {\r\n stasticarr.push({ \"name\": name, \"issum\": true });\r\n }\r\n\r\n }\r\n else {\r\n stasticarr.push(\"\");\r\n }\r\n }\r\n\r\n return stasticarr;\r\n },\r\n generategrouparraymain: function (group, config) {\r\n let _this = this;\r\n\r\n //生成数组\r\n let ret = [];\r\n for (let i = 0; i < group.length; i++) {\r\n let name = group[i].name;\r\n let arr = _this.generategrouparray(group[i].children, config, 1);\r\n\r\n if (config[0].stastic == \"1\" || config[0].stastic == null) {\r\n arr.push(_this.generategroupaddstatic(arr, name));\r\n }\r\n\r\n ret = ret.concat(arr);\r\n }\r\n\r\n return ret;\r\n },\r\n generategrouparray: function (group, config, level) {\r\n let _this = this;\r\n\r\n let ret = [];\r\n for (let i = 0; i < group.length; i++) {\r\n let name = group[i].name;\r\n let arr;\r\n\r\n if (group[i].children == 0 || group[i].children.length == 0) {\r\n arr = [name];\r\n ret.push(arr);\r\n }\r\n else {\r\n arr = _this.generategrouparray(group[i].children, config, level + 1);\r\n\r\n for (let a = 0; a < arr.length; a++) {\r\n arr[a].unshift(name);\r\n }\r\n\r\n if (config[level].stastic == \"1\" || config[level].stastic == null) {\r\n arr.push(_this.generategroupaddstatic(arr, name));\r\n }\r\n\r\n ret = ret.concat(arr);\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n addStatisticsData: function (dataposition, valueobj, indicator, d_value) {\r\n if (dataposition[indicator] == null) {\r\n dataposition[indicator] = { \r\n \"data\": [], \r\n \"count\": 0, \r\n \"max\": -Infinity, \r\n \"min\": Infinity, \r\n \"counta\": 0, \r\n \"countunique\": 0, \r\n \"countuniquedata\": {}, \r\n \"sum\": 0, \r\n \"digitaldata\": [], \r\n \"sumtype\": valueobj.sumtype, \r\n \"index\": valueobj.index, \r\n \"name\": valueobj.fullname, \r\n \"acc\": 0 \r\n };\r\n }\r\n\r\n if (isdatatypemulti(d_value)[\"num\"] === true) {\r\n let num = numFormat(d_value);\r\n dataposition[indicator][\"digitaldata\"].push(num);\r\n dataposition[indicator][\"count\"] += 1;\r\n dataposition[indicator][\"sum\"] += num;\r\n\r\n if (num > dataposition[indicator][\"max\"]) {\r\n dataposition[indicator][\"max\"] = num;\r\n }\r\n\r\n if (num < dataposition[indicator][\"min\"]) {\r\n dataposition[indicator][\"min\"] = num;\r\n }\r\n\r\n let newAcc = numfloatlen(num);\r\n\r\n if(newAcc > dataposition[indicator][\"acc\"]){\r\n dataposition[indicator][\"acc\"] = newAcc;\r\n }\r\n }\r\n\r\n if (d_value != \"\") {\r\n dataposition[indicator][\"data\"].push(d_value);\r\n dataposition[indicator][\"counta\"] += 1;\r\n if (!(d_value in dataposition[indicator][\"countuniquedata\"])) {\r\n dataposition[indicator][\"countuniquedata\"][d_value] = 1;\r\n dataposition[indicator][\"countunique\"] += 1;\r\n }\r\n }\r\n },\r\n dataHandler: function (column, row, values, showType, celldata) {\r\n //column:[{\"index\":1, name:\"列1\", \"order\":\"asc\", \"orderby\":\"self/0/1/2\", \"stastic\":\"0/1\"}]\r\n //row:[{\"index\":1, name:\"列3\", \"order\":\"asc\", \"orderby\":\"self/0/1/2\", \"stastic\":\"0/1\"}]\r\n //values:[{\"index\":1, \"sumtype\":\"SUM/COUNT/COUNTA/COUNTUNIQUE/AVERAGE/MAX/MIN/MEDIAN/PRODUCT/STDEV/STDEVP/let/VARP\", \"name\":\"求和:fyc\"}]\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_filter = _locale.filter;\r\n const locale_pivotTable = _locale.pivotTable;\r\n \r\n\r\n if (showType == null) {\r\n showType = \"column\";\r\n }\r\n\r\n if ((column.length == 0 && row.length == 0 && values.length == 0) || celldata.length == 0) {\r\n _this.pivotDatas = [];\r\n return [];\r\n }\r\n\r\n //生成透视表值及定位\r\n let dataposition = {}, \r\n data = celldata, \r\n datarowtitle = [], \r\n datarowtitlegroup = [], \r\n datarowposition = {}, \r\n datarowposition_i = 0, \r\n datacoltitle = [], \r\n datacoltitlegroup = [], \r\n datacolposition = {}, \r\n datacolposition_i = 0;\r\n\r\n for (let i = 1; i < data.length; i++) {\r\n let d = data[i];\r\n let groupbyrowtxt = \"\", \r\n groupbycoltxt = \"\", \r\n rowtxt = \"\", \r\n rowtitle = [], \r\n rowtitlename = [], \r\n coltxt = \"\", \r\n coltitle = [], \r\n coltitlename = [];\r\n\r\n //[\"四川\", \"成都\", \"邛崃\"] 转换为 [\"四川\", \"四川成都\", \"四川成都邛崃\"]\r\n rowtitlename = _this.getnameArray(d, row);\r\n coltitlename = _this.getnameArray(d, column);\r\n\r\n rowtitle = _this.getComposeArray(rowtitlename);\r\n coltitle = _this.getComposeArray(coltitlename);\r\n\r\n if (rowtitle.length > 0) {\r\n rowtitle.unshift(locale_pivotTable.valueSum);\r\n }\r\n\r\n if (coltitle.length > 0) {\r\n coltitle.unshift(locale_pivotTable.valueSum);\r\n }\r\n\r\n let curentLevelobj_row = datarowposition, \r\n curentLevelarr_row = datarowtitlegroup;\r\n \r\n for (let r = 0; r < rowtitle.length; r++) {\r\n let item = rowtitle[r], name = r == 0 ? locale_pivotTable.valueSum : rowtitlename[r - 1];//修改\r\n\r\n if (curentLevelobj_row[r.toString()] != null && curentLevelobj_row[r.toString()][item] != null) {//修改\r\n curentLevelarr_row = curentLevelarr_row[curentLevelobj_row[r.toString()][item]].children;\r\n }\r\n else {\r\n let orderby = r == 0 ? \"self\" : ((row[r - 1].orderby == \"self\" || row[r - 1].orderby == null) ? item : (showType == \"column\" ? item + values[parseInt(row[r - 1].orderby)].fullname : item + locale_pivotTable.valueSum));\r\n \r\n if(name == null){\r\n name = locale_filter.valueBlank;\r\n }\r\n\r\n curentLevelarr_row.push({ \"name\": name, \"fullname\": item, \"index\": r, \"orderby\": orderby, \"children\": [] });\r\n\r\n if (curentLevelobj_row[r.toString()] == null) {\r\n curentLevelobj_row[r.toString()] = {};\r\n }\r\n\r\n if (curentLevelobj_row[r.toString()][item] == null) {\r\n curentLevelobj_row[r.toString()][item] = curentLevelarr_row.length - 1;\r\n }\r\n\r\n curentLevelarr_row = curentLevelarr_row[curentLevelarr_row.length - 1].children;\r\n }\r\n }\r\n\r\n let curentLevelobj_col = datacolposition, \r\n curentLevelarr_col = datacoltitlegroup;\r\n\r\n for (let r = 0; r < coltitle.length; r++) {\r\n let item = coltitle[r], name = r == 0 ? locale_pivotTable.valueSum : coltitlename[r - 1];\r\n\r\n if (curentLevelobj_col[r.toString()] != null && curentLevelobj_col[r.toString()][item] != null) {\r\n curentLevelarr_col = curentLevelarr_col[curentLevelobj_col[r.toString()][item]].children;\r\n }\r\n else {\r\n let orderby = r == 0 ? \"self\" : ((column[r - 1].orderby == \"self\" || column[r - 1].orderby == null) ? item : (showType == \"column\" ? locale_pivotTable.valueSum + item : values[parseInt(column[r - 1].orderby)].fullname + item));\r\n \r\n if(name == null){\r\n name = locale_filter.valueBlank;\r\n }\r\n\r\n curentLevelarr_col.push({ \"name\": name, \"fullname\": item, \"index\": r, \"orderby\": orderby, \"children\": [] });\r\n\r\n if (curentLevelobj_col[r.toString()] == null) {\r\n curentLevelobj_col[r.toString()] = {};\r\n }\r\n\r\n if (curentLevelobj_col[r.toString()][item] == null) {\r\n curentLevelobj_col[r.toString()][item] = curentLevelarr_col.length - 1;\r\n }\r\n\r\n curentLevelarr_col = curentLevelarr_col[curentLevelarr_col.length - 1].children;\r\n }\r\n }\r\n\r\n let v_str = \"\";\r\n for (let v = 0; v < values.length; v++) {\r\n let d_value = getcellvalue(values[v].index, null, d);\r\n\r\n let coltitle_c = [].concat(coltitle), rowtitle_c = [].concat(rowtitle);\r\n if (showType == \"column\") {\r\n if (coltitle_c.length > 0) {\r\n coltitle_c.push(\"\")\r\n coltitle_c = coltitle_c.join(values[v].fullname + \"|||\").split(\"|||\").slice(0, coltitle_c.length - 1);\r\n }\r\n else {\r\n coltitle_c.push(values[v].fullname);\r\n }\r\n }\r\n else {\r\n if (rowtitle_c.length > 0) {\r\n rowtitle_c.push(\"\")\r\n rowtitle_c = rowtitle_c.join(values[v].fullname + \"|||\").split(\"|||\").slice(0, rowtitle_c.length - 1);\r\n }\r\n else {\r\n rowtitle_c.push(values[v].fullname);\r\n }\r\n }\r\n\r\n if (coltitle_c.length == 0) {\r\n coltitle_c.push(\"\");\r\n }\r\n\r\n if (rowtitle_c.length == 0) {\r\n rowtitle_c.push(\"\");\r\n }\r\n\r\n for (let r = 0; r < rowtitle_c.length; r++) {\r\n for (let c = 0; c < coltitle_c.length; c++) {\r\n let indicator = rowtitle_c[r] + coltitle_c[c];\r\n _this.addStatisticsData(dataposition, values[v], indicator, d_value);\r\n }\r\n }\r\n }\r\n }\r\n\r\n //计算值列\r\n //SUM/COUNT/COUNTA/COUNTUNIQUE/AVERAGE/MAX/MIN/MEDIAN/PRODUCT/STDEV/STDEVP/let/VARP\r\n for (let indicator in dataposition) {\r\n let json = dataposition[indicator];\r\n\r\n if (json.sumtype == \"SUM\") {\r\n json.result = json.sum;\r\n }\r\n else if (json.sumtype == \"COUNT\") {\r\n json.result = json.count;\r\n }\r\n else if (json.sumtype == \"COUNTA\") {\r\n json.result = json.counta;\r\n }\r\n else if (json.sumtype == \"COUNTUNIQUE\") {\r\n json.result = json.countunique;\r\n }\r\n else if (json.sumtype == \"AVERAGE\") {\r\n json.result = numFormat(json.sum / json.count);\r\n }\r\n else if (json.sumtype == \"MAX\") {\r\n json.result = json.max;\r\n }\r\n else if (json.sumtype == \"MIN\") {\r\n json.result = json.min;\r\n }\r\n else if (json.sumtype == \"MEDIAN\") {\r\n let numArr = json.digitaldata.sort(function(a, b){ return a - b });\r\n let numLen = numArr.length;\r\n let numindex = parseInt(numLen / 2);\r\n\r\n if(numLen % 2 == 0){\r\n json.result = (numArr[numindex - 1] + numArr[numindex]) / 2;\r\n }\r\n else{\r\n json.result = numArr[numindex];\r\n }\r\n }\r\n else if (json.sumtype == \"PRODUCT\") {\r\n json.result = new Function(\"return \" + json.digitaldata.join(\"*\"))();\r\n }\r\n else if (json.sumtype == \"STDEV\") {\r\n let mean = json.sum / json.count;\r\n json.result = analysis.STDEV(mean, json.digitaldata);\r\n }\r\n else if (json.sumtype == \"STDEVP\") {\r\n let mean = json.sum / json.count;\r\n json.result = analysis.STDEVP(mean, json.digitaldata);\r\n }\r\n else if (json.sumtype == \"let\") {\r\n let mean = json.sum / json.count;\r\n json.result = analysis.let(mean, json.digitaldata);\r\n }\r\n else if (json.sumtype == \"VARP\") {\r\n let mean = json.sum / json.count;\r\n json.result = analysis.VARP(mean, json.digitaldata);\r\n }\r\n\r\n let newAcc = numfloatlen(json.result);\r\n if(newAcc > json.acc){\r\n json.acc = newAcc;\r\n }\r\n\r\n json.result = numFormat(json.result, json.acc);\r\n }\r\n\r\n datarowtitle = _this.getTitleFromGroup(datarowtitlegroup, row, dataposition);\r\n datacoltitle = _this.getTitleFromGroup(datacoltitlegroup, column, dataposition);\r\n\r\n //加入值到列/行形成新的表头\r\n if (showType == \"column\") {\r\n if (datacoltitle.length > 0 && datacoltitle[0].length > 0) {\r\n datacoltitle = _this.addValuesToTitle(datacoltitle, values);\r\n }\r\n else {\r\n for (let v = 0; v < values.length; v++) {\r\n datacoltitle.push([values[v].fullname]);\r\n }\r\n }\r\n }\r\n else {\r\n if (datarowtitle.length > 0 && datarowtitle[0].length > 0) {\r\n datarowtitle = _this.addValuesToTitle(datarowtitle, values);\r\n }\r\n else {\r\n for (let v = 0; v < values.length; v++) {\r\n datarowtitle.push([values[v].fullname]);\r\n }\r\n }\r\n }\r\n\r\n let datacoltitle_index = datacoltitle;\r\n datacoltitle = luckysheetArray.transpose(datacoltitle, false);\r\n\r\n let valuenslen = values.length == 0 ? 0 : 1;\r\n let rowLen = (datacoltitle.length == 0 ? valuenslen : datacoltitle.length) + (datarowtitle.length == 0 ? valuenslen : datarowtitle.length), colLen = (datacoltitle.length == 0 ? valuenslen : datacoltitle[0].length) + (datarowtitle.length == 0 ? valuenslen : datarowtitle[0].length);\r\n\r\n let rowOver = datacoltitle.length, colOver = datarowtitle.length == 0 ? 0 : datarowtitle[0].length;\r\n\r\n let retdata = [];\r\n for (let r = 0; r < rowLen; r++) {\r\n retdata[r] = new Array(colLen);\r\n\r\n for (let c = 0; c < colLen; c++) {\r\n let drt = datarowtitle[r - rowOver];\r\n \r\n if (r < rowOver && c < colOver) {\r\n //空白列头\r\n retdata[r][c] = \"\";\r\n }\r\n else if (r < rowOver && c >= colOver) {\r\n //列标题\r\n if (datacoltitle[r] != null) {\r\n if (getObjType(datacoltitle[r][c - colOver]) == \"object\") {\r\n retdata[r][c] = datacoltitle[r][c - colOver].name + locale_pivotTable.valueSum;\r\n }\r\n else {\r\n retdata[r][c] = datacoltitle[r][c - colOver];\r\n }\r\n }\r\n else {\r\n retdata[r][c] = \"\";\r\n }\r\n }\r\n else if (r >= rowOver && c < colOver) {\r\n //行标题\r\n if (drt != null) {\r\n if (getObjType(drt[c]) == \"object\") {\r\n retdata[r][c] = drt[c].name + locale_pivotTable.valueSum;\r\n }\r\n else {\r\n retdata[r][c] = drt[c];\r\n }\r\n }\r\n else {\r\n retdata[r][c] = \"\";\r\n }\r\n }\r\n else {\r\n //单元格内容\r\n let prefix = \"\";\r\n if (drt != null) {\r\n if (!(drt instanceof Array) || drt.length == 1) {\r\n if (drt instanceof Array) {\r\n prefix = drt[0];\r\n }\r\n else {\r\n prefix = drt;\r\n }\r\n }\r\n else {\r\n for (let x = 0; x < drt.length; x++) {\r\n if (getObjType(drt[x]) == \"object\") {\r\n prefix += drt[x].name;\r\n }\r\n else {\r\n prefix += drt[x];\r\n }\r\n }\r\n }\r\n }\r\n\r\n let suffix = \"\";\r\n let dct = datacoltitle_index[c - colOver];\r\n if (dct != null) {\r\n if (!(dct instanceof Array) || dct.length == 1) {\r\n if (dct instanceof Array) {\r\n suffix = dct[0];\r\n }\r\n else {\r\n suffix = dct;\r\n }\r\n }\r\n else {\r\n for (let x = 0; x < dct.length; x++) {\r\n if (getObjType(dct[x]) == \"object\") {\r\n suffix += dct[x].name;\r\n }\r\n else {\r\n suffix += dct[x];\r\n }\r\n }\r\n }\r\n }\r\n\r\n let indicator = prefix;\r\n\r\n if (prefix != \"\" && suffix != \"\") {\r\n indicator = prefix + suffix;\r\n }\r\n else if (prefix == \"\") {\r\n indicator = suffix;\r\n }\r\n\r\n if (dataposition[indicator] == null) {\r\n retdata[r][c] = \"\";\r\n }\r\n else {\r\n retdata[r][c] = dataposition[indicator].result;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (values.length == 1 && column.length > 0 && row.length > 0 ) {\r\n retdata[0][0] = values[0].fullname;\r\n retdata.splice(column.length, 1);\r\n }\r\n else if(values.length == 1 && column.length > 0){\r\n // 0: (6) [\"English\", \"foreign language\", \"mathematics\", \"science\", \"Sum\", undefined]\r\n // 1: (6) [\"CountA:score\", \"CountA:score\", \"CountA:score\", \"CountA:score\", \"CountA:score\", undefined]\r\n // 2: (6) [3, 3, 3, 3, 12, \"\"]\r\n //The above format does not meet viewing habits,Process retdata into the correct format\r\n let titleRow = retdata.splice(column.length, 1);\r\n let newRetdata = [];\r\n for(let r=0;r 0){\r\n for(let a = 0; a < _this.row.length; a++){\r\n obj[_this.row[a][\"index\"]] = _this.pivotDatas[row_index][a];\r\n }\r\n }\r\n\r\n //列\r\n if(_this.column != null && _this.column.length > 0){\r\n for(let b = 0; b < _this.column.length; b++){\r\n obj[_this.column[b][\"index\"]] = _this.pivotDatas[b][col_index];\r\n }\r\n }\r\n\r\n let rowArr = [];\r\n for(let j = 1; j < _this.celldata.length; j++){\r\n let isEqual = true\r\n\r\n for(let x in obj){\r\n let value;\r\n if(!!_this.celldata[j][x] && !!_this.celldata[j][x][\"m\"]){\r\n value = _this.celldata[j][x][\"m\"];\r\n }\r\n else{\r\n value = getcellvalue(j, x, _this.celldata); \r\n }\r\n\r\n if(value != null){\r\n value = value.toString();\r\n }\r\n else{\r\n value = locale_filter.valueBlank;\r\n }\r\n\r\n if(value != obj[x]){\r\n isEqual = false;\r\n break;\r\n }\r\n }\r\n\r\n if(isEqual){\r\n rowArr.push(j);\r\n }\r\n }\r\n\r\n for(let r = 0; r < rowArr.length; r++){\r\n for(let c = 0; c < _this.celldata[0].length; c++){\r\n let value;\r\n if(!!_this.celldata[rowArr[r]][c] && !!_this.celldata[rowArr[r]][c][\"m\"]){\r\n value = _this.celldata[rowArr[r]][c][\"m\"];\r\n }\r\n else{\r\n value = getcellvalue(rowArr[r], c, _this.celldata); \r\n }\r\n\r\n if(value != null){\r\n value = value.toString();\r\n }\r\n else{\r\n value = \"\";\r\n }\r\n\r\n d[r + 1][c] = value;\r\n }\r\n }\r\n\r\n Store.luckysheet_select_save = [{ \"row\": [0, rowArr.length], \"column\": [0, _this.celldata[0].length - 1] }];\r\n\r\n Store.clearjfundo = false;\r\n jfrefreshgrid(d, Store.luckysheet_select_save);\r\n selectHightlightShow();\r\n Store.clearjfundo = true;\r\n }\r\n}\r\n\r\nexport default pivotTable;","import Store from \"../store\";\r\n\r\n//sparkline设置\r\nlet createClass = function (/* [baseclass, [mixin, ...]], definition */) {\r\n let Class, args;\r\n Class = function () {\r\n this.init.apply(this, arguments);\r\n };\r\n if (arguments.length > 1) {\r\n if (arguments[0]) {\r\n Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]);\r\n Class._super = arguments[0].prototype;\r\n } else {\r\n Class.prototype = arguments[arguments.length - 1];\r\n }\r\n if (arguments.length > 2) {\r\n args = Array.prototype.slice.call(arguments, 1, -1);\r\n args.unshift(Class.prototype);\r\n $.extend.apply($, args);\r\n }\r\n } else {\r\n Class.prototype = arguments[0];\r\n }\r\n Class.prototype.cls = Class;\r\n return Class;\r\n};\r\n\r\n/**\r\n * Wraps a format string for tooltips\r\n * {{x}}\r\n * {{x.2}\r\n * {{x:months}}\r\n */\r\nlet SPFormat = createClass({\r\n fre: /\\{\\{([\\w.]+?)(:(.+?))?\\}\\}/g,\r\n precre: /(\\w+)\\.(\\d+)/,\r\n\r\n init: function (format, fclass) {\r\n this.format = format;\r\n this.fclass = fclass;\r\n },\r\n\r\n render: function (fieldset, lookups, options) {\r\n let self = this,\r\n fields = fieldset,\r\n match, token, lookupkey, fieldvalue, prec;\r\n return this.format.replace(this.fre, function () {\r\n let lookup;\r\n token = arguments[1];\r\n lookupkey = arguments[3];\r\n match = self.precre.exec(token);\r\n if (match) {\r\n prec = match[2];\r\n token = match[1];\r\n } else {\r\n prec = false;\r\n }\r\n fieldvalue = fields[token];\r\n if (fieldvalue === undefined) {\r\n return '';\r\n }\r\n if (lookupkey && lookups && lookups[lookupkey]) {\r\n lookup = lookups[lookupkey];\r\n if (lookup.get) { // RangeMap\r\n return lookups[lookupkey].get(fieldvalue) || fieldvalue;\r\n } else {\r\n return lookups[lookupkey][fieldvalue] || fieldvalue;\r\n }\r\n }\r\n if (isNumber(fieldvalue)) {\r\n if (options.get('numberFormatter')) {\r\n fieldvalue = options.get('numberFormatter')(fieldvalue);\r\n } else {\r\n fieldvalue = formatNumber(fieldvalue, prec,\r\n options.get('numberDigitGroupCount'),\r\n options.get('numberDigitGroupSep'),\r\n options.get('numberDecimalMark'));\r\n }\r\n }\r\n return fieldvalue;\r\n });\r\n }\r\n});\r\n\r\n// convience method to avoid needing the new operator\r\n$.spformat = function(format, fclass) {\r\n return new SPFormat(format, fclass);\r\n};\r\n\r\nlet clipval = function (val, min, max) {\r\n if (val < min) {\r\n return min;\r\n }\r\n if (val > max) {\r\n return max;\r\n }\r\n return val;\r\n};\r\n\r\nlet quartile = function (values, q) {\r\n let vl;\r\n if (q === 2) {\r\n vl = Math.floor(values.length / 2);\r\n return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2;\r\n } else {\r\n if (values.length % 2 ) { // odd\r\n vl = (values.length * q + q) / 4;\r\n return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];\r\n } else { //even\r\n vl = (values.length * q + 2) / 4;\r\n return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];\r\n\r\n }\r\n }\r\n};\r\n\r\nlet normalizeValue = function (val) {\r\n let nf;\r\n switch (val) {\r\n case 'undefined':\r\n val = undefined;\r\n break;\r\n case 'null':\r\n val = null;\r\n break;\r\n case 'true':\r\n val = true;\r\n break;\r\n case 'false':\r\n val = false;\r\n break;\r\n default:\r\n nf = parseFloat(val);\r\n if (val == nf) {\r\n val = nf;\r\n }\r\n }\r\n return val;\r\n};\r\n\r\nlet normalizeValues = function (vals) {\r\n let i, result = [];\r\n for (i = vals.length; i--;) {\r\n result[i] = normalizeValue(vals[i]);\r\n }\r\n return result;\r\n};\r\n\r\n\r\nlet all = function (val, arr, ignoreNull) {\r\n let i;\r\n for (i = arr.length; i--; ) {\r\n if (ignoreNull && arr[i] === null) continue;\r\n if (arr[i] !== val) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n};\r\n\r\n// sums the numeric values in an array, ignoring other values\r\nlet sum = function (vals) {\r\n let total = 0, i;\r\n for (i = vals.length; i--;) {\r\n total += typeof vals[i] === 'number' ? vals[i] : 0;\r\n }\r\n return total;\r\n};\r\n\r\nlet remove = function (vals, filter) {\r\n let i, vl, result = [];\r\n for (i = 0, vl = vals.length; i < vl; i++) {\r\n if (vals[i] !== filter) {\r\n result.push(vals[i]);\r\n }\r\n }\r\n return result;\r\n};\r\n\r\nlet isNumber = function (num) {\r\n return !isNaN(parseFloat(num)) && isFinite(num);\r\n};\r\n\r\nlet formatNumber = function (num, prec, groupsize, groupsep, decsep) {\r\n let p, i;\r\n num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split('');\r\n p = (p = $.inArray('.', num)) < 0 ? num.length : p;\r\n if (p < num.length) {\r\n num[p] = decsep;\r\n }\r\n for (i = p - groupsize; i > 0; i -= groupsize) {\r\n num.splice(i, 0, groupsep);\r\n }\r\n return num.join('');\r\n};\r\n\r\n\r\nlet RangeMap = createClass({\r\n init: function (map) {\r\n let key, range, rangelist = [];\r\n for (key in map) {\r\n if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) {\r\n range = key.split(':');\r\n range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]);\r\n range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]);\r\n range[2] = map[key];\r\n rangelist.push(range);\r\n }\r\n }\r\n this.map = map;\r\n this.rangelist = rangelist || false;\r\n },\r\n\r\n get: function (value) {\r\n let rangelist = this.rangelist,\r\n i, range, result;\r\n if ((result = this.map[value]) !== undefined) {\r\n return result;\r\n }\r\n if (rangelist) {\r\n for (i = rangelist.length; i--;) {\r\n range = rangelist[i];\r\n if (range[0] <= value && range[1] >= value) {\r\n return range[2];\r\n }\r\n }\r\n }\r\n return undefined;\r\n }\r\n});\r\n\r\n// Convenience function\r\n$.range_map = function(map) {\r\n return new RangeMap(map);\r\n};\r\n\r\nconst luckysheetSparkline = {\r\n defaultOption:{\r\n // Settings common to most/all chart types\r\n common: {\r\n type: 'line',\r\n lineColor: '#2ec7c9',\r\n fillColor: '#CCF3F4',\r\n defaultPixelsPerValue: 3,\r\n width: 'auto',\r\n height: 'auto',\r\n composite: false,\r\n tagValuesAttribute: 'values',\r\n tagOptionsPrefix: 'spark',\r\n enableTagOptions: false,\r\n enableHighlight: true,\r\n highlightLighten: 1.4,\r\n tooltipSkipNull: true,\r\n tooltipPrefix: '',\r\n tooltipSuffix: '',\r\n disableHiddenCheck: false,\r\n numberFormatter: false,\r\n numberDigitGroupCount: 3,\r\n numberDigitGroupSep: ',',\r\n numberDecimalMark: '.',\r\n disableTooltips: true,\r\n disableInteraction: true,\r\n offsetX:0,\r\n offsetY:0\r\n },\r\n // Defaults for line charts\r\n //=LINESPL\r\n line: {\r\n spotColor: 0,\r\n highlightSpotColor: '#5f5',\r\n highlightLineColor: '#f22',\r\n spotRadius: 1.5,\r\n minSpotColor: 0,\r\n maxSpotColor: 0,\r\n lineWidth: 1,\r\n normalRangeMin: undefined,\r\n normalRangeMax: undefined,\r\n normalRangeColor: '#ccc',\r\n drawNormalOnTop: true,\r\n chartRangeMin: undefined,\r\n chartRangeMax: undefined,\r\n chartRangeMinX: undefined,\r\n chartRangeMaxX: undefined,\r\n // tooltipFormat: new SPFormat(' {{prefix}}{{y}}{{suffix}}')\r\n },\r\n // Defaults for bar charts\r\n bar: {\r\n barColor: '#fc5c5c',\r\n negBarColor: '#97b552',\r\n stackedBarColor: [\"#2ec7c9\", \"#fc5c5c\", \"#5ab1ef\", \"#ffb980\", \"#d87a80\", \"#8d98b3\", \"#e5cf0d\", \"#97b552\", \"#95706d\",\"#dc69aa\",\"#07a2a4\",\"#9a7fd1\",\"#588dd5\",\"#f5994e\",\"#c05050\",\"#59678c\",\"#c9ab00\",\"#7eb00a\",\"#6f5553\",\"#c14089\"],\r\n zeroColor: undefined,\r\n nullColor: undefined,\r\n zeroAxis: true,\r\n barWidth: 4,\r\n barSpacing: 1,\r\n chartRangeMax: undefined,\r\n chartRangeMin: undefined,\r\n chartRangeClip: false,\r\n colorMap: undefined,\r\n // tooltipFormat: new SPFormat(' {{prefix}}{{value}}{{suffix}}')\r\n },\r\n column: {\r\n barColor: '#fc5c5c',\r\n negBarColor: '#97b552',\r\n stackedBarColor: [\"#2ec7c9\", \"#fc5c5c\", \"#5ab1ef\", \"#ffb980\", \"#d87a80\", \"#8d98b3\", \"#e5cf0d\", \"#97b552\", \"#95706d\",\"#dc69aa\",\"#07a2a4\",\"#9a7fd1\",\"#588dd5\",\"#f5994e\",\"#c05050\",\"#59678c\",\"#c9ab00\",\"#7eb00a\",\"#6f5553\",\"#c14089\"],\r\n zeroColor: undefined,\r\n nullColor: undefined,\r\n zeroAxis: true,\r\n barWidth: 4,\r\n barSpacing: 1,\r\n chartRangeMax: undefined,\r\n chartRangeMin: undefined,\r\n chartRangeClip: false,\r\n colorMap: undefined,\r\n // tooltipFormat: new SPFormat(' {{prefix}}{{value}}{{suffix}}')\r\n },\r\n // Defaults for tristate charts\r\n tristate: {\r\n barWidth: 4,\r\n barSpacing: 1,\r\n posBarColor: '#fc5c5c',\r\n negBarColor: '#97b552',\r\n zeroBarColor: '#999',\r\n colorMap: {},\r\n // tooltipFormat: new SPFormat(' {{value:map}}'),\r\n // tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } }\r\n },\r\n // Defaults for discrete charts\r\n discrete: {\r\n lineHeight: 'auto',\r\n thresholdColor: \"#fc5c5c\",\r\n thresholdValue: 0,\r\n chartRangeMax: undefined,\r\n chartRangeMin: undefined,\r\n chartRangeClip: false,\r\n // tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}')\r\n },\r\n // Defaults for bullet charts\r\n bullet: {\r\n targetColor: '#f33',\r\n targetWidth: 3, // width of the target bar in pixels\r\n performanceColor: '#33f',\r\n rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff','#6D87FF','#5876FF','#4465FF','#2F54FF','#1A43FF','#0532FF'],\r\n base: undefined, // set this to a number to change the base start number\r\n // tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'),\r\n // tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} }\r\n },\r\n // Defaults for pie charts\r\n pie: {\r\n offset: 0,\r\n sliceColors: [\"#2ec7c9\", \"#fc5c5c\", \"#5ab1ef\", \"#ffb980\", \"#d87a80\", \"#8d98b3\", \"#e5cf0d\", \"#97b552\", \"#95706d\",\"#dc69aa\",\"#07a2a4\",\"#9a7fd1\",\"#588dd5\",\"#f5994e\",\"#c05050\",\"#59678c\",\"#c9ab00\",\"#7eb00a\",\"#6f5553\",\"#c14089\"],\r\n borderWidth: 0,\r\n borderColor: '#000',\r\n // tooltipFormat: new SPFormat(' {{value}} ({{percent.1}}%)')\r\n },\r\n // Defaults for box plots\r\n box: {\r\n raw: false,\r\n boxLineColor: '#000',\r\n boxFillColor: '#cdf',\r\n whiskerColor: '#000',\r\n outlierLineColor: '#5E5E5E',\r\n outlierFillColor: '#fff',\r\n medianColor: '#f00',\r\n showOutliers: true,\r\n outlierIQR: 1.5,\r\n spotRadius: 1.5,\r\n target: undefined,\r\n targetColor: '#4a2',\r\n chartRangeMax: undefined,\r\n chartRangeMin: undefined,\r\n // tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'),\r\n // tooltipFormatFieldlistKey: 'field',\r\n // tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median',\r\n // uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier',\r\n // lw: 'Left Whisker', rw: 'Right Whisker'} }\r\n }\r\n },\r\n line:{\r\n type: 'line',\r\n init: function (el, values, options, width, height) {\r\n //line._super.init.call(this, el, values, options, width, height);\r\n this.vertices = [];\r\n this.regionMap = [];\r\n this.xvalues = [];\r\n this.yvalues = [];\r\n this.yminmax = [];\r\n this.hightlightSpotId = null;\r\n this.lastShapeId = null;\r\n //this.initTarget();\r\n },\r\n getRegion: function (el, x, y) {\r\n let i,\r\n regionMap = this.regionMap; // maps regions to value positions\r\n for (i = regionMap.length; i--;) {\r\n if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) {\r\n return regionMap[i][2];\r\n }\r\n }\r\n return undefined;\r\n },\r\n getCurrentRegionFields: function () {\r\n let currentRegion = this.currentRegion;\r\n return {\r\n isNull: this.yvalues[currentRegion] === null,\r\n x: this.xvalues[currentRegion],\r\n y: this.yvalues[currentRegion],\r\n color: this.options.get('lineColor'),\r\n fillColor: this.options.get('fillColor'),\r\n offset: currentRegion\r\n };\r\n },\r\n renderHighlight: function () {\r\n let currentRegion = this.currentRegion,\r\n target = this.target,\r\n vertex = this.vertices[currentRegion],\r\n options = this.options,\r\n spotRadius = options.get('spotRadius'),\r\n highlightSpotColor = options.get('highlightSpotColor'),\r\n highlightLineColor = options.get('highlightLineColor'),\r\n highlightSpot, highlightLine;\r\n\r\n if (!vertex) {\r\n return;\r\n }\r\n if (spotRadius && highlightSpotColor) {\r\n highlightSpot = target.drawCircle(vertex[0], vertex[1],\r\n spotRadius, undefined, highlightSpotColor);\r\n this.highlightSpotId = highlightSpot.id;\r\n target.insertAfterShape(this.lastShapeId, highlightSpot);\r\n }\r\n if (highlightLineColor) {\r\n highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0],\r\n this.canvasTop + this.canvasHeight, highlightLineColor);\r\n this.highlightLineId = highlightLine.id;\r\n target.insertAfterShape(this.lastShapeId, highlightLine);\r\n }\r\n },\r\n removeHighlight: function () {\r\n let target = this.target;\r\n if (this.highlightSpotId) {\r\n target.removeShapeId(this.highlightSpotId);\r\n this.highlightSpotId = null;\r\n }\r\n if (this.highlightLineId) {\r\n target.removeShapeId(this.highlightLineId);\r\n this.highlightLineId = null;\r\n }\r\n },\r\n scanValues: function () {\r\n let values = this.values,\r\n valcount = values.length,\r\n xvalues = this.xvalues,\r\n yvalues = this.yvalues,\r\n yminmax = this.yminmax,\r\n i, val, isStr, isArray, sp;\r\n for (i = 0; i < valcount; i++) {\r\n val = values[i];\r\n isStr = typeof(values[i]) === 'string';\r\n isArray = typeof(values[i]) === 'object' && values[i] instanceof Array;\r\n sp = isStr && values[i].split(':');\r\n if (isStr && sp.length === 2) { // x:y\r\n xvalues.push(Number(sp[0]));\r\n yvalues.push(Number(sp[1]));\r\n yminmax.push(Number(sp[1]));\r\n } else if (isArray) {\r\n xvalues.push(val[0]);\r\n yvalues.push(val[1]);\r\n yminmax.push(val[1]);\r\n } else {\r\n xvalues.push(i);\r\n if (values[i] === null || values[i] === 'null') {\r\n yvalues.push(null);\r\n } else {\r\n yvalues.push(Number(val));\r\n yminmax.push(Number(val));\r\n }\r\n }\r\n }\r\n if (this.options.get('xvalues')) {\r\n xvalues = this.options.get('xvalues');\r\n }\r\n\r\n this.maxy = this.maxyorg = Math.max.apply(Math, yminmax);\r\n this.miny = this.minyorg = Math.min.apply(Math, yminmax);\r\n\r\n this.maxx = Math.max.apply(Math, xvalues);\r\n this.minx = Math.min.apply(Math, xvalues);\r\n\r\n this.xvalues = xvalues;\r\n this.yvalues = yvalues;\r\n this.yminmax = yminmax;\r\n\r\n },\r\n processRangeOptions: function () {\r\n let options = this.options,\r\n normalRangeMin = options.get('normalRangeMin'),\r\n normalRangeMax = options.get('normalRangeMax');\r\n\r\n if (normalRangeMin !== undefined) {\r\n if (normalRangeMin < this.miny) {\r\n this.miny = normalRangeMin;\r\n }\r\n if (normalRangeMax > this.maxy) {\r\n this.maxy = normalRangeMax;\r\n }\r\n }\r\n if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) {\r\n this.miny = options.get('chartRangeMin');\r\n }\r\n if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) {\r\n this.maxy = options.get('chartRangeMax');\r\n }\r\n if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) {\r\n this.minx = options.get('chartRangeMinX');\r\n }\r\n if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) {\r\n this.maxx = options.get('chartRangeMaxX');\r\n }\r\n\r\n },\r\n drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) {\r\n let normalRangeMin = this.options.get('normalRangeMin'),\r\n normalRangeMax = this.options.get('normalRangeMax'),\r\n ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))),\r\n height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey);\r\n //(x1, y1, x2, y2, lineColor, lineWidth)\r\n if(height==0 && normalRangeMin==normalRangeMax){\r\n height=1;\r\n }\r\n this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append();\r\n },\r\n render: function (el,userValues) {\r\n this.vertices = [];\r\n this.regionMap = [];\r\n this.xvalues = [];\r\n this.yvalues = [];\r\n this.yminmax = [];\r\n this.hightlightSpotId = null;\r\n this.lastShapeId = null;\r\n\r\n this.values = userValues;\r\n\r\n let options = this.options,\r\n target = this.target,\r\n\r\n canvasWidth = el.mergedOptions.width,\r\n canvasHeight = el.mergedOptions.height,\r\n\r\n vertices = this.vertices,\r\n spotRadius = options.get('spotRadius'),\r\n regionMap = this.regionMap,\r\n rangex, rangey, yvallast,\r\n canvasTop, canvasLeft,\r\n vertex, path, paths, x, y, xnext, xpos, xposnext,\r\n last, next, yvalcount, lineShapes, fillShapes, plen,\r\n valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i;\r\n\r\n // if (!line._super.render.call(this)) {\r\n // return;\r\n // }\r\n\r\n this.scanValues();\r\n this.processRangeOptions();\r\n\r\n xvalues = this.xvalues;\r\n yvalues = this.yvalues;\r\n\r\n if (!this.yminmax.length || this.yvalues.length < 2) {\r\n // empty or all null valuess\r\n return;\r\n }\r\n\r\n canvasTop = canvasLeft = 0;\r\n\r\n rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx;\r\n rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny;\r\n yvallast = this.yvalues.length - 1;\r\n\r\n if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) {\r\n spotRadius = 0;\r\n }\r\n if (spotRadius) {\r\n // adjust the canvas size as required so that spots will fit\r\n hlSpotsEnabled = options.get('highlightSpotColor') && !options.get('disableInteraction');\r\n if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) {\r\n canvasHeight -= Math.ceil(spotRadius);\r\n }\r\n if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) {\r\n canvasHeight -= Math.ceil(spotRadius);\r\n canvasTop += Math.ceil(spotRadius);\r\n }\r\n if (hlSpotsEnabled ||\r\n ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) {\r\n canvasLeft += Math.ceil(spotRadius);\r\n canvasWidth -= Math.ceil(spotRadius);\r\n }\r\n if (hlSpotsEnabled || options.get('spotColor') ||\r\n (options.get('minSpotColor') || options.get('maxSpotColor') &&\r\n (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) {\r\n canvasWidth -= Math.ceil(spotRadius);\r\n }\r\n }\r\n\r\n\r\n canvasHeight--;\r\n\r\n if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) {\r\n this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);\r\n }\r\n\r\n path = [];\r\n paths = [path];\r\n last = next = null;\r\n yvalcount = yvalues.length;\r\n for (i = 0; i < yvalcount; i++) {\r\n x = xvalues[i];\r\n xnext = xvalues[i + 1];\r\n y = yvalues[i];\r\n xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex));\r\n xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth;\r\n next = xpos + ((xposnext - xpos) / 2);\r\n regionMap[i] = [last || 0, next, i];\r\n last = next;\r\n if (y === null) {\r\n if (i) {\r\n if (yvalues[i - 1] !== null) {\r\n path = [];\r\n paths.push(path);\r\n }\r\n vertices.push(null);\r\n }\r\n } else {\r\n if (y < this.miny) {\r\n y = this.miny;\r\n }\r\n if (y > this.maxy) {\r\n y = this.maxy;\r\n }\r\n if (!path.length) {\r\n // previous value was null\r\n path.push([xpos, canvasTop + canvasHeight]);\r\n }\r\n vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))];\r\n path.push(vertex);\r\n vertices.push(vertex);\r\n }\r\n }\r\n\r\n lineShapes = [];\r\n fillShapes = [];\r\n plen = paths.length;\r\n for (i = 0; i < plen; i++) {\r\n path = paths[i];\r\n if (path.length) {\r\n if (options.get('fillColor')) {\r\n path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]);\r\n fillShapes.push(path.slice(0));\r\n path.pop();\r\n }\r\n // if there's only a single point in this path, then we want to display it\r\n // as a vertical line which means we keep path[0] as is\r\n if (path.length > 2) {\r\n // else we want the first value\r\n path[0] = [path[0][0], path[1][1]];\r\n }\r\n lineShapes.push(path);\r\n }\r\n }\r\n\r\n // draw the fill first, then optionally the normal range, then the line on top of that\r\n plen = fillShapes.length;\r\n for (i = 0; i < plen; i++) {\r\n target.drawShape(fillShapes[i],\r\n options.get('fillColor'), options.get('fillColor')).append();\r\n }\r\n\r\n\r\n\r\n plen = lineShapes.length;\r\n for (i = 0; i < plen; i++) {\r\n target.drawShape(lineShapes[i], options.get('lineColor'), undefined,\r\n options.get('lineWidth')).append();\r\n }\r\n\r\n if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) {\r\n this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);\r\n }\r\n \r\n if (spotRadius && options.get('valueSpots')) {\r\n valueSpots = options.get('valueSpots');\r\n if (valueSpots.get === undefined) {\r\n valueSpots = new RangeMap(valueSpots);\r\n }\r\n for (i = 0; i < yvalcount; i++) {\r\n color = valueSpots.get(yvalues[i]);\r\n if (color) {\r\n target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)),\r\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))),\r\n spotRadius, undefined,\r\n color).append();\r\n }\r\n }\r\n\r\n }\r\n if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) {\r\n target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)),\r\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))),\r\n spotRadius, undefined,\r\n options.get('spotColor')).append();\r\n }\r\n if (this.maxy !== this.minyorg) {\r\n if (spotRadius && options.get('minSpotColor')) {\r\n x = xvalues[$.inArray(this.minyorg, yvalues)];\r\n target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),\r\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))),\r\n spotRadius, undefined,\r\n options.get('minSpotColor')).append();\r\n }\r\n if (spotRadius && options.get('maxSpotColor')) {\r\n x = xvalues[$.inArray(this.maxyorg, yvalues)];\r\n target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),\r\n canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))),\r\n spotRadius, undefined,\r\n options.get('maxSpotColor')).append();\r\n }\r\n }\r\n\r\n // this.lastShapeId = target.getLastShapeId();\r\n // this.canvasTop = canvasTop;\r\n // target.render();\r\n\r\n }\r\n },\r\n bar:{\r\n type: 'bar',\r\n\r\n init: function (el, values) {\r\n let options = this.options;\r\n let width = el.mergedOptions.height;\r\n let height = el.mergedOptions.width;\r\n\r\n this.canvasWidth = el.mergedOptions.height;\r\n this.canvasHeight = el.mergedOptions.width;\r\n\r\n let barWidth = parseInt(options.get('barWidth'), 10),\r\n barSpacing = parseInt(options.get('barSpacing'), 10),\r\n chartRangeMin = options.get('chartRangeMin'),\r\n chartRangeMax = options.get('chartRangeMax'),\r\n chartRangeClip = options.get('chartRangeClip'),\r\n stackMin = Infinity,\r\n stackMax = -Infinity,\r\n isStackString, groupMin, groupMax, stackRanges,\r\n numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax,\r\n stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf;\r\n //bar._super.init.call(this, el, values, options, width, height);\r\n\r\n this.values = values;\r\n\r\n // scan values to determine whether to stack bars\r\n for (i = 0, vlen = values.length; i < vlen; i++) {\r\n val = values[i];\r\n isStackString = typeof(val) === 'string' && val.indexOf(':') > -1;\r\n if (isStackString || $.isArray(val)) {\r\n stacked = true;\r\n if (isStackString) {\r\n val = values[i] = normalizeValues(val.split(':'));\r\n }\r\n val = remove(val, null); // min/max will treat null as zero\r\n groupMin = Math.min.apply(Math, val);\r\n groupMax = Math.max.apply(Math, val);\r\n if (groupMin < stackMin) {\r\n stackMin = groupMin;\r\n }\r\n if (groupMax > stackMax) {\r\n stackMax = groupMax;\r\n }\r\n }\r\n }\r\n\r\n this.stacked = stacked;\r\n this.regionShapes = {};\r\n this.barWidth = Math.floor(width/values.length)-barSpacing;\r\n this.barSpacing = barSpacing;\r\n this.totalBarWidth = this.barWidth + barSpacing;\r\n //this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);\r\n this.width = width;\r\n //this.initTarget();\r\n\r\n if (chartRangeClip) {\r\n clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin;\r\n clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax;\r\n }\r\n\r\n numValues = [];\r\n stackRanges = stacked ? [] : numValues;\r\n let stackTotals = [];\r\n let stackRangesNeg = [];\r\n for (i = 0, vlen = values.length; i < vlen; i++) {\r\n if (stacked) {\r\n vlist = values[i];\r\n values[i] = svals = [];\r\n stackTotals[i] = 0;\r\n stackRanges[i] = stackRangesNeg[i] = 0;\r\n for (j = 0, slen = vlist.length; j < slen; j++) {\r\n val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j];\r\n if (val !== null) {\r\n if (val > 0) {\r\n stackTotals[i] += val;\r\n }\r\n if (stackMin < 0 && stackMax > 0) {\r\n if (val < 0) {\r\n stackRangesNeg[i] += Math.abs(val);\r\n } else {\r\n stackRanges[i] += val;\r\n }\r\n } else {\r\n stackRanges[i] += Math.abs(val);\r\n // stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin));\r\n }\r\n numValues.push(val);\r\n }\r\n }\r\n } else {\r\n val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i];\r\n val = values[i] = normalizeValue(val);\r\n if (val !== null) {\r\n numValues.push(val);\r\n }\r\n }\r\n }\r\n this.max = max = Math.max.apply(Math, numValues);\r\n this.min = min = Math.min.apply(Math, numValues);\r\n this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;\r\n this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;\r\n\r\n if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) {\r\n min = options.get('chartRangeMin');\r\n }\r\n if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) {\r\n max = options.get('chartRangeMax');\r\n }\r\n\r\n this.zeroAxis = zeroAxis = options.get('zeroAxis', true);\r\n if (min <= 0 && max >= 0 && zeroAxis) {\r\n xaxisOffset = 0;\r\n } else if (zeroAxis == false) {\r\n xaxisOffset = min;\r\n } else if (min > 0) {\r\n xaxisOffset = 0;\r\n } else {\r\n xaxisOffset = max;\r\n }\r\n this.xaxisOffset = xaxisOffset;\r\n\r\n range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - xaxisOffset;\r\n\r\n // as we plot zero/min values a single pixel line, we add a pixel to all other\r\n // values - Reduce the effective canvas size to suit\r\n this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1;\r\n this.isNeg = false;\r\n if (min < xaxisOffset) {\r\n // yMaxCalc = (stacked && max >= 0) ? stackMax : max;\r\n // yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight;\r\n yoffset = Math.floor(this.canvasHeight/2);\r\n this.isNeg = true;\r\n if (yoffset !== Math.ceil(yoffset)) {\r\n this.canvasHeightEf -= 2;\r\n yoffset = Math.ceil(yoffset);\r\n }\r\n } else {\r\n yoffset = 0;\r\n }\r\n this.yoffset = yoffset;\r\n\r\n if ($.isArray(options.get('colorMap'))) {\r\n this.colorMapByIndex = options.get('colorMap');\r\n this.colorMapByValue = null;\r\n } else {\r\n this.colorMapByIndex = null;\r\n this.colorMapByValue = options.get('colorMap');\r\n if (this.colorMapByValue && this.colorMapByValue.get === undefined) {\r\n this.colorMapByValue = new RangeMap(this.colorMapByValue);\r\n }\r\n }\r\n\r\n this.range = range;\r\n },\r\n\r\n getRegion: function (el, x, y) {\r\n let result = Math.floor(x / this.totalBarWidth);\r\n return (result < 0 || result >= this.values.length) ? undefined : result;\r\n },\r\n\r\n getCurrentRegionFields: function () {\r\n let currentRegion = this.currentRegion,\r\n values = ensureArray(this.values[currentRegion]),\r\n result = [],\r\n value, i;\r\n for (i = values.length; i--;) {\r\n value = values[i];\r\n result.push({\r\n isNull: value === null,\r\n value: value,\r\n color: this.calcColor(i, value, currentRegion),\r\n offset: currentRegion\r\n });\r\n }\r\n return result;\r\n },\r\n\r\n calcColor: function (stacknum, value, valuenum) {\r\n let colorMapByIndex = this.colorMapByIndex,\r\n colorMapByValue = this.colorMapByValue,\r\n options = this.options,\r\n color, newColor;\r\n if (this.stacked) {\r\n color = options.get('stackedBarColor');\r\n } else {\r\n color = (value < 0) ? options.get('negBarColor') : options.get('barColor');\r\n }\r\n if (value === 0 && options.get('zeroColor') !== undefined) {\r\n color = options.get('zeroColor');\r\n }\r\n if (colorMapByValue && (newColor = colorMapByValue.get(value))) {\r\n color = newColor;\r\n } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {\r\n color = colorMapByIndex[valuenum];\r\n }\r\n return $.isArray(color) ? color[stacknum % color.length] : color;\r\n },\r\n\r\n /**\r\n * Render bar(s) for a region\r\n */\r\n renderRegion: function (valuenum, highlight) {\r\n let vals = this.values[valuenum],\r\n options = this.options,\r\n xaxisOffset = this.xaxisOffset,\r\n result = [],\r\n range = this.range,\r\n stacked = this.stacked,\r\n target = this.target,\r\n x = valuenum * this.totalBarWidth,\r\n canvasHeightEf = this.canvasHeightEf,\r\n yoffset = this.yoffset,\r\n y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin;\r\n\r\n vals = $.isArray(vals) ? vals : [vals];\r\n valcount = vals.length;\r\n val = vals[0];\r\n isNull = all(null, vals);\r\n allMin = all(xaxisOffset, vals, true);\r\n\r\n if (isNull) {\r\n if (options.get('nullColor')) {\r\n color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options);\r\n y = (yoffset > 0) ? yoffset - 1 : yoffset;\r\n return target.drawRect(y, x, 0, this.barWidth - 1, color, color);\r\n } else {\r\n return undefined;\r\n }\r\n }\r\n yoffsetNeg = yoffset;\r\n if(this.isNeg){\r\n canvasHeightEf = Math.floor(canvasHeightEf/2);\r\n }\r\n for (i = 0; i < valcount; i++) {\r\n val = vals[i];\r\n\r\n if (stacked && val === xaxisOffset) {\r\n if (!allMin || minPlotted) {\r\n continue;\r\n }\r\n minPlotted = true;\r\n }\r\n\r\n if (range > 0) {\r\n height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range)));\r\n } else {\r\n height = canvasHeightEf;\r\n }\r\n\r\n if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {\r\n y = yoffsetNeg - height;\r\n yoffsetNeg += height;\r\n } else {\r\n if(stacked){\r\n y = yoffset;\r\n yoffset += height;\r\n }\r\n else{\r\n y = yoffset;\r\n yoffset -= height;\r\n }\r\n \r\n }\r\n color = this.calcColor(i, val, valuenum);\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, options);\r\n }\r\n result.push(target.drawRect(y, x, height - 1, this.barWidth - 1,color, color));\r\n }\r\n if (result.length === 1) {\r\n return result[0];\r\n }\r\n return result;\r\n }\r\n },\r\n column:{\r\n type: 'column',\r\n\r\n init: function (el, values) {\r\n let options = this.options;\r\n let width = el.mergedOptions.width;\r\n let height = el.mergedOptions.height;\r\n\r\n this.canvasWidth = el.mergedOptions.width;\r\n this.canvasHeight = el.mergedOptions.height;\r\n\r\n let barWidth = parseInt(options.get('barWidth'), 10),\r\n barSpacing = parseInt(options.get('barSpacing'), 10),\r\n chartRangeMin = options.get('chartRangeMin'),\r\n chartRangeMax = options.get('chartRangeMax'),\r\n chartRangeClip = options.get('chartRangeClip'),\r\n stackMin = Infinity,\r\n stackMax = -Infinity,\r\n isStackString, groupMin, groupMax, stackRanges,\r\n numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax,\r\n stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf;\r\n //bar._super.init.call(this, el, values, options, width, height);\r\n\r\n this.values = values;\r\n\r\n // scan values to determine whether to stack bars\r\n for (i = 0, vlen = values.length; i < vlen; i++) {\r\n val = values[i];\r\n isStackString = typeof(val) === 'string' && val.indexOf(':') > -1;\r\n if (isStackString || $.isArray(val)) {\r\n stacked = true;\r\n if (isStackString) {\r\n val = values[i] = normalizeValues(val.split(':'));\r\n }\r\n val = remove(val, null); // min/max will treat null as zero\r\n groupMin = Math.min.apply(Math, val);\r\n groupMax = Math.max.apply(Math, val);\r\n if (groupMin < stackMin) {\r\n stackMin = groupMin;\r\n }\r\n if (groupMax > stackMax) {\r\n stackMax = groupMax;\r\n }\r\n }\r\n }\r\n\r\n this.stacked = stacked;\r\n this.regionShapes = {};\r\n this.barWidth = Math.floor(width/values.length)-barSpacing;\r\n this.barSpacing = barSpacing;\r\n this.totalBarWidth = this.barWidth + barSpacing;\r\n //this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);\r\n this.width = width;\r\n //this.initTarget();\r\n\r\n if (chartRangeClip) {\r\n clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin;\r\n clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax;\r\n }\r\n\r\n numValues = [];\r\n stackRanges = stacked ? [] : numValues;\r\n let stackTotals = [];\r\n let stackRangesNeg = [];\r\n for (i = 0, vlen = values.length; i < vlen; i++) {\r\n if (stacked) {\r\n vlist = values[i];\r\n values[i] = svals = [];\r\n stackTotals[i] = 0;\r\n stackRanges[i] = stackRangesNeg[i] = 0;\r\n for (j = 0, slen = vlist.length; j < slen; j++) {\r\n val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j];\r\n if (val !== null) {\r\n if (val > 0) {\r\n stackTotals[i] += val;\r\n }\r\n if (stackMin < 0 && stackMax > 0) {\r\n if (val < 0) {\r\n stackRangesNeg[i] += Math.abs(val);\r\n } else {\r\n stackRanges[i] += val;\r\n }\r\n } else {\r\n stackRanges[i] += Math.abs(val);\r\n // stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin));\r\n }\r\n numValues.push(val);\r\n }\r\n }\r\n } else {\r\n val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i];\r\n val = values[i] = normalizeValue(val);\r\n if (val !== null) {\r\n numValues.push(val);\r\n }\r\n }\r\n }\r\n this.max = max = Math.max.apply(Math, numValues);\r\n this.min = min = Math.min.apply(Math, numValues);\r\n this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;\r\n this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;\r\n\r\n if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) {\r\n min = options.get('chartRangeMin');\r\n }\r\n if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) {\r\n max = options.get('chartRangeMax');\r\n }\r\n\r\n this.zeroAxis = zeroAxis = options.get('zeroAxis', true);\r\n if (min <= 0 && max >= 0 && zeroAxis) {\r\n xaxisOffset = 0;\r\n } else if (zeroAxis == false) {\r\n xaxisOffset = min;\r\n } else if (min > 0) {\r\n xaxisOffset = 0;\r\n } else {\r\n xaxisOffset = max;\r\n }\r\n this.xaxisOffset = xaxisOffset;\r\n\r\n range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - xaxisOffset;\r\n\r\n // as we plot zero/min values a single pixel line, we add a pixel to all other\r\n // values - Reduce the effective canvas size to suit\r\n this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1;\r\n this.isNeg = false;\r\n if (min < xaxisOffset) {\r\n // yMaxCalc = (stacked && max >= 0) ? stackMax : max;\r\n // yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight;\r\n yoffset = Math.floor(this.canvasHeight/2);\r\n this.isNeg = true;\r\n if (yoffset !== Math.ceil(yoffset)) {\r\n this.canvasHeightEf -= 2;\r\n yoffset = Math.ceil(yoffset);\r\n }\r\n } else {\r\n yoffset = this.canvasHeight;\r\n }\r\n this.yoffset = yoffset;\r\n\r\n if ($.isArray(options.get('colorMap'))) {\r\n this.colorMapByIndex = options.get('colorMap');\r\n this.colorMapByValue = null;\r\n } else {\r\n this.colorMapByIndex = null;\r\n this.colorMapByValue = options.get('colorMap');\r\n if (this.colorMapByValue && this.colorMapByValue.get === undefined) {\r\n this.colorMapByValue = new RangeMap(this.colorMapByValue);\r\n }\r\n }\r\n\r\n this.range = range;\r\n },\r\n\r\n getRegion: function (el, x, y) {\r\n let result = Math.floor(x / this.totalBarWidth);\r\n return (result < 0 || result >= this.values.length) ? undefined : result;\r\n },\r\n\r\n getCurrentRegionFields: function () {\r\n let currentRegion = this.currentRegion,\r\n values = ensureArray(this.values[currentRegion]),\r\n result = [],\r\n value, i;\r\n for (i = values.length; i--;) {\r\n value = values[i];\r\n result.push({\r\n isNull: value === null,\r\n value: value,\r\n color: this.calcColor(i, value, currentRegion),\r\n offset: currentRegion\r\n });\r\n }\r\n return result;\r\n },\r\n\r\n calcColor: function (stacknum, value, valuenum) {\r\n let colorMapByIndex = this.colorMapByIndex,\r\n colorMapByValue = this.colorMapByValue,\r\n options = this.options,\r\n color, newColor;\r\n if (this.stacked) {\r\n color = options.get('stackedBarColor');\r\n } else {\r\n color = (value < 0) ? options.get('negBarColor') : options.get('barColor');\r\n }\r\n if (value === 0 && options.get('zeroColor') !== undefined) {\r\n color = options.get('zeroColor');\r\n }\r\n if (colorMapByValue && (newColor = colorMapByValue.get(value))) {\r\n color = newColor;\r\n } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {\r\n color = colorMapByIndex[valuenum];\r\n }\r\n return $.isArray(color) ? color[stacknum % color.length] : color;\r\n },\r\n\r\n /**\r\n * Render bar(s) for a region\r\n */\r\n renderRegion: function (valuenum, highlight) {\r\n let vals = this.values[valuenum],\r\n options = this.options,\r\n xaxisOffset = this.xaxisOffset,\r\n result = [],\r\n range = this.range,\r\n stacked = this.stacked,\r\n target = this.target,\r\n x = valuenum * this.totalBarWidth,\r\n canvasHeightEf = this.canvasHeightEf,\r\n yoffset = this.yoffset,\r\n y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin;\r\n\r\n vals = $.isArray(vals) ? vals : [vals];\r\n valcount = vals.length;\r\n val = vals[0];\r\n isNull = all(null, vals);\r\n allMin = all(xaxisOffset, vals, true);\r\n\r\n if (isNull) {\r\n if (options.get('nullColor')) {\r\n color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options);\r\n y = (yoffset > 0) ? yoffset - 1 : yoffset;\r\n return target.drawRect(x, y, this.barWidth - 1, 0, color, color);\r\n } else {\r\n return undefined;\r\n }\r\n }\r\n yoffsetNeg = yoffset;\r\n if(this.isNeg){\r\n canvasHeightEf = Math.floor(canvasHeightEf/2);\r\n }\r\n for (i = 0; i < valcount; i++) {\r\n val = vals[i];\r\n\r\n if (stacked && val === xaxisOffset) {\r\n if (!allMin || minPlotted) {\r\n continue;\r\n }\r\n minPlotted = true;\r\n }\r\n\r\n if (range > 0) {\r\n height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range)));\r\n } else {\r\n height = canvasHeightEf;\r\n }\r\n\r\n if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {\r\n y = yoffsetNeg;\r\n yoffsetNeg += height;\r\n } else {\r\n y = yoffset - height;\r\n yoffset -= height;\r\n }\r\n color = this.calcColor(i, val, valuenum);\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, options);\r\n }\r\n result.push(target.drawRect(x, y, this.barWidth - 1, height - 1, color, color));\r\n }\r\n if (result.length === 1) {\r\n return result[0];\r\n }\r\n return result;\r\n }\r\n },\r\n tristate:{\r\n type: 'tristate',\r\n init: function(el, values) {\r\n let options = this.options;\r\n let width = el.mergedOptions.width;\r\n let height = el.mergedOptions.height;\r\n\r\n this.canvasWidth = el.mergedOptions.width;\r\n this.canvasHeight = el.mergedOptions.height;\r\n\r\n let barWidth = parseInt(options.get('barWidth'), 10),\r\n barSpacing = parseInt(options.get('barSpacing'), 10);\r\n //tristate._super.init.call(this, el, values, options, width, height);\r\n\r\n this.regionShapes = {};\r\n this.barWidth = barWidth;\r\n this.barSpacing = barSpacing;\r\n this.totalBarWidth = barWidth + barSpacing;\r\n this.values = $.map(values, Number);\r\n this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);\r\n\r\n if ($.isArray(options.get('colorMap'))) {\r\n this.colorMapByIndex = options.get('colorMap');\r\n this.colorMapByValue = null;\r\n } else {\r\n this.colorMapByIndex = null;\r\n this.colorMapByValue = options.get('colorMap');\r\n if (this.colorMapByValue && this.colorMapByValue.get === undefined) {\r\n this.colorMapByValue = new RangeMap(this.colorMapByValue);\r\n }\r\n }\r\n //this.initTarget();\r\n },\r\n\r\n getRegion: function (el, x, y) {\r\n return Math.floor(x / this.totalBarWidth);\r\n },\r\n\r\n getCurrentRegionFields: function () {\r\n let currentRegion = this.currentRegion;\r\n return {\r\n isNull: this.values[currentRegion] === undefined,\r\n value: this.values[currentRegion],\r\n color: this.calcColor(this.values[currentRegion], currentRegion),\r\n offset: currentRegion\r\n };\r\n },\r\n\r\n calcColor: function (value, valuenum) {\r\n let values = this.values,\r\n options = this.options,\r\n colorMapByIndex = this.colorMapByIndex,\r\n colorMapByValue = this.colorMapByValue,\r\n color, newColor;\r\n\r\n if (colorMapByValue && (newColor = colorMapByValue.get(value))) {\r\n color = newColor;\r\n } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {\r\n color = colorMapByIndex[valuenum];\r\n } else if (values[valuenum] < 0) {\r\n color = options.get('negBarColor');\r\n } else if (values[valuenum] > 0) {\r\n color = options.get('posBarColor');\r\n } else {\r\n color = options.get('zeroBarColor');\r\n }\r\n return color;\r\n },\r\n\r\n renderRegion: function (valuenum, highlight) {\r\n let values = this.values,\r\n options = this.options,\r\n target = this.target,\r\n canvasHeight, height, halfHeight,\r\n x, y, color;\r\n\r\n canvasHeight = this.canvasHeight;\r\n halfHeight = Math.round(canvasHeight / 2);\r\n\r\n x = valuenum * this.totalBarWidth;\r\n if (values[valuenum] < 0) {\r\n y = halfHeight;\r\n height = halfHeight - 1;\r\n } else if (values[valuenum] > 0) {\r\n y = 0;\r\n height = halfHeight - 1;\r\n } else {\r\n y = halfHeight - 1;\r\n height = 2;\r\n }\r\n color = this.calcColor(values[valuenum], valuenum);\r\n if (color === null) {\r\n return;\r\n }\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, options);\r\n }\r\n return target.drawRect(x, y, this.barWidth - 1, height - 1, color, color);\r\n }\r\n },\r\n discrete:{\r\n type: 'discrete',\r\n\r\n init: function(el, values) {\r\n let options = this.options;\r\n let width = el.mergedOptions.width;\r\n let height = el.mergedOptions.height;\r\n\r\n this.canvasWidth = el.mergedOptions.width;\r\n this.canvasHeight = el.mergedOptions.height;\r\n\r\n this.regionShapes = {};\r\n this.values = values = $.map(values, Number);\r\n this.min = Math.min.apply(Math, values);\r\n this.max = Math.max.apply(Math, values);\r\n this.range = this.max - this.min;\r\n this.width = width;\r\n this.interval = Math.floor(width / values.length);\r\n this.itemWidth = width / values.length;\r\n if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) {\r\n this.min = options.get('chartRangeMin');\r\n }\r\n if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) {\r\n this.max = options.get('chartRangeMax');\r\n }\r\n //this.initTarget();\r\n if (this.target) {\r\n this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight');\r\n }\r\n },\r\n\r\n getRegion: function (el, x, y) {\r\n return Math.floor(x / this.itemWidth);\r\n },\r\n\r\n getCurrentRegionFields: function () {\r\n let currentRegion = this.currentRegion;\r\n return {\r\n isNull: this.values[currentRegion] === undefined,\r\n value: this.values[currentRegion],\r\n offset: currentRegion\r\n };\r\n },\r\n\r\n renderRegion: function (valuenum, highlight) {\r\n let values = this.values,\r\n options = this.options,\r\n min = this.min,\r\n max = this.max,\r\n range = this.range,\r\n interval = this.interval,\r\n target = this.target,\r\n canvasHeight = this.canvasHeight,\r\n lineHeight = this.lineHeight,\r\n pheight = canvasHeight - lineHeight,\r\n ytop, val, color, x;\r\n\r\n val = clipval(values[valuenum], min, max);\r\n x = valuenum * interval;\r\n ytop = Math.round(pheight - pheight * ((val - min) / range));\r\n color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor');\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, options);\r\n }\r\n //return target.drawLine(x, ytop, x, ytop + lineHeight, color);\r\n\r\n return this.target.drawRect(x, ytop, interval<=2?1:interval-2, lineHeight, color, color);\r\n }\r\n },\r\n bullet:{\r\n type: 'bullet',\r\n init: function(el, values) {\r\n\r\n let options = this.options;\r\n let width = el.mergedOptions.width;\r\n let height = el.mergedOptions.height;\r\n\r\n this.canvasWidth = el.mergedOptions.width;\r\n this.canvasHeight = el.mergedOptions.height;\r\n\r\n let min, max, vals;\r\n //bullet._super.init.call(this, el, values, options, width, height);\r\n\r\n // values: target, performance, range1, range2, range3\r\n this.values = values = normalizeValues(values);\r\n // target or performance could be null\r\n vals = values.slice();\r\n vals[0] = vals[0] === null ? vals[2] : vals[0];\r\n vals[1] = values[1] === null ? vals[2] : vals[1];\r\n min = Math.min.apply(Math, values);\r\n max = Math.max.apply(Math, values);\r\n if (options.get('base') === undefined) {\r\n min = min < 0 ? min : 0;\r\n } else {\r\n min = options.get('base');\r\n }\r\n this.min = min;\r\n this.max = max;\r\n this.range = max - min;\r\n this.shapes = {};\r\n this.valueShapes = {};\r\n this.regiondata = {};\r\n this.width = width;\r\n //this.target = this.$el.simpledraw(width, height, options.get('composite'));\r\n if (!values.length) {\r\n this.disabled = true;\r\n }\r\n //this.initTarget();\r\n },\r\n\r\n getRegion: function (el, x, y) {\r\n let shapeid = this.target.getShapeAt(el, x, y);\r\n return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;\r\n },\r\n\r\n getCurrentRegionFields: function () {\r\n let currentRegion = this.currentRegion;\r\n return {\r\n fieldkey: currentRegion.substr(0, 1),\r\n value: this.values[currentRegion.substr(1)],\r\n region: currentRegion\r\n };\r\n },\r\n\r\n changeHighlight: function (highlight) {\r\n let currentRegion = this.currentRegion,\r\n shapeid = this.valueShapes[currentRegion],\r\n shape;\r\n delete this.shapes[shapeid];\r\n switch (currentRegion.substr(0, 1)) {\r\n case 'r':\r\n shape = this.renderRange(currentRegion.substr(1), highlight);\r\n break;\r\n case 'p':\r\n shape = this.renderPerformance(highlight);\r\n break;\r\n case 't':\r\n shape = this.renderTarget(highlight);\r\n break;\r\n }\r\n this.valueShapes[currentRegion] = shape.id;\r\n this.shapes[shape.id] = currentRegion;\r\n this.target.replaceWithShape(shapeid, shape);\r\n },\r\n\r\n renderRange: function (rn, highlight) {\r\n let rangeval = this.values[rn],\r\n rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)),\r\n color = this.options.get('rangeColors')[rn - 2];\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, this.options);\r\n }\r\n return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color);\r\n },\r\n\r\n renderPerformance: function (highlight) {\r\n let perfval = this.values[1],\r\n perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)),\r\n color = this.options.get('performanceColor');\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, this.options);\r\n }\r\n return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1,\r\n Math.round(this.canvasHeight * 0.4) - 1, color, color);\r\n },\r\n\r\n renderTarget: function (highlight) {\r\n let targetval = this.values[0],\r\n x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)),\r\n targettop = Math.round(this.canvasHeight * 0.10),\r\n targetheight = this.canvasHeight - (targettop * 2),\r\n color = this.options.get('targetColor');\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, this.options);\r\n }\r\n return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color);\r\n },\r\n\r\n render: function (el,userValues) {\r\n this.init(el,userValues);\r\n let vlen = this.values.length,\r\n target = this.target,\r\n i, shape;\r\n // if (!bullet._super.render.call(this)) {\r\n // return;\r\n // }\r\n for (i = 2; i < vlen; i++) {\r\n shape = this.renderRange(i).append();\r\n this.shapes[shape.id] = 'r' + i;\r\n this.valueShapes['r' + i] = shape.id;\r\n }\r\n if (this.values[1] !== null) {\r\n shape = this.renderPerformance().append();\r\n this.shapes[shape.id] = 'p1';\r\n this.valueShapes.p1 = shape.id;\r\n }\r\n if (this.values[0] !== null) {\r\n shape = this.renderTarget().append();\r\n this.shapes[shape.id] = 't0';\r\n this.valueShapes.t0 = shape.id;\r\n }\r\n //target.render();\r\n }\r\n },\r\n pie:{\r\n type: 'pie',\r\n\r\n init: function(el, values) {\r\n\r\n let options = this.options;\r\n let width = el.mergedOptions.width;\r\n let height = el.mergedOptions.height;\r\n\r\n this.canvasWidth = el.mergedOptions.width;\r\n this.canvasHeight = el.mergedOptions.height;\r\n\r\n let total = 0, i;\r\n\r\n //pie._super.init.call(this, el, values, options, width, height);\r\n\r\n this.shapes = {}; // map shape ids to value offsets\r\n this.valueShapes = {}; // maps value offsets to shape ids\r\n this.values = values = $.map(values, Number);\r\n\r\n if (options.get('width') === 'auto') {\r\n this.width = this.height;\r\n }\r\n\r\n if (values.length > 0) {\r\n for (i = values.length; i--;) {\r\n total += values[i];\r\n }\r\n }\r\n this.total = total;\r\n //this.initTarget();\r\n this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2);\r\n },\r\n\r\n getRegion: function (el, x, y) {\r\n let shapeid = this.target.getShapeAt(el, x, y);\r\n return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;\r\n },\r\n\r\n getCurrentRegionFields: function () {\r\n let currentRegion = this.currentRegion;\r\n return {\r\n isNull: this.values[currentRegion] === undefined,\r\n value: this.values[currentRegion],\r\n percent: this.values[currentRegion] / this.total * 100,\r\n color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],\r\n offset: currentRegion\r\n };\r\n },\r\n\r\n changeHighlight: function (highlight) {\r\n let currentRegion = this.currentRegion,\r\n newslice = this.renderSlice(currentRegion, highlight),\r\n shapeid = this.valueShapes[currentRegion];\r\n delete this.shapes[shapeid];\r\n this.target.replaceWithShape(shapeid, newslice);\r\n this.valueShapes[currentRegion] = newslice.id;\r\n this.shapes[newslice.id] = currentRegion;\r\n },\r\n\r\n renderSlice: function (valuenum, highlight) {\r\n let target = this.target,\r\n options = this.options,\r\n radius = this.radius,\r\n borderWidth = options.get('borderWidth'),\r\n offset = options.get('offset'),\r\n circle = 2 * Math.PI,\r\n values = this.values,\r\n total = this.total,\r\n next = offset ? (2*Math.PI)*(offset/360) : 0,\r\n start, end, i, vlen, color;\r\n\r\n vlen = values.length;\r\n for (i = 0; i < vlen; i++) {\r\n start = next;\r\n end = next;\r\n if (total > 0) { // avoid divide by zero\r\n end = next + (circle * (values[i] / total));\r\n }\r\n if (valuenum === i) {\r\n color = options.get('sliceColors')[i % options.get('sliceColors').length];\r\n if (highlight) {\r\n color = this.calcHighlightColor(color, options);\r\n }\r\n\r\n return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color);\r\n }\r\n next = end;\r\n }\r\n },\r\n\r\n render: function (el,userValues) {\r\n this.init(el,userValues);\r\n let target = this.target,\r\n values = this.values,\r\n options = this.options,\r\n radius = this.radius,\r\n borderWidth = options.get('borderWidth'),\r\n shape, i;\r\n\r\n // if (!pie._super.render.call(this)) {\r\n // return;\r\n // }\r\n if (borderWidth) {\r\n target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),\r\n options.get('borderColor'), undefined, borderWidth).append();\r\n }\r\n for (i = values.length; i--;) {\r\n if (values[i]) { // don't render zero values\r\n shape = this.renderSlice(i).append();\r\n this.valueShapes[i] = shape.id; // store just the shapeid\r\n this.shapes[shape.id] = i;\r\n }\r\n }\r\n //target.render();\r\n }\r\n },\r\n box:{\r\n type: 'box',\r\n\r\n init: function(el, values) {\r\n\r\n let options = this.options;\r\n let width = el.mergedOptions.width;\r\n let height = el.mergedOptions.height;\r\n\r\n this.canvasWidth = el.mergedOptions.width;\r\n this.canvasHeight = el.mergedOptions.height;\r\n\r\n //box._super.init.call(this, el, values, options, width, height);\r\n this.values = $.map(values, Number);\r\n this.width = options.get('width') === 'auto' ? '4.0em' : width;\r\n //this.initTarget();\r\n if (!this.values.length) {\r\n this.disabled = 1;\r\n }\r\n },\r\n\r\n /**\r\n * Simulate a single region\r\n */\r\n getRegion: function () {\r\n return 1;\r\n },\r\n\r\n getCurrentRegionFields: function () {\r\n let result = [\r\n { field: 'lq', value: this.quartiles[0] },\r\n { field: 'med', value: this.quartiles[1] },\r\n { field: 'uq', value: this.quartiles[2] }\r\n ];\r\n if (this.loutlier !== undefined) {\r\n result.push({ field: 'lo', value: this.loutlier});\r\n }\r\n if (this.routlier !== undefined) {\r\n result.push({ field: 'ro', value: this.routlier});\r\n }\r\n if (this.lwhisker !== undefined) {\r\n result.push({ field: 'lw', value: this.lwhisker});\r\n }\r\n if (this.rwhisker !== undefined) {\r\n result.push({ field: 'rw', value: this.rwhisker});\r\n }\r\n return result;\r\n },\r\n\r\n render: function (el,userValues) {\r\n this.init(el,userValues);\r\n\r\n let target = this.target,\r\n values = this.values,\r\n vlen = values.length,\r\n options = this.options,\r\n canvasWidth = this.canvasWidth,\r\n canvasHeight = this.canvasHeight,\r\n minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'),\r\n maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'),\r\n canvasLeft = 0,\r\n lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i,\r\n size, unitSize;\r\n\r\n // if (!box._super.render.call(this)) {\r\n // return;\r\n // }\r\n\r\n if (options.get('raw')) {\r\n if (options.get('showOutliers') && values.length > 5) {\r\n loutlier = values[0];\r\n lwhisker = values[1];\r\n q1 = values[2];\r\n q2 = values[3];\r\n q3 = values[4];\r\n rwhisker = values[5];\r\n routlier = values[6];\r\n } else {\r\n lwhisker = values[0];\r\n q1 = values[1];\r\n q2 = values[2];\r\n q3 = values[3];\r\n rwhisker = values[4];\r\n }\r\n } else {\r\n values.sort(function (a, b) { return a - b; });\r\n q1 = quartile(values, 1);\r\n q2 = quartile(values, 2);\r\n q3 = quartile(values, 3);\r\n iqr = q3 - q1;\r\n if (options.get('showOutliers')) {\r\n lwhisker = rwhisker = undefined;\r\n for (i = 0; i < vlen; i++) {\r\n if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) {\r\n lwhisker = values[i];\r\n }\r\n if (values[i] < q3 + (iqr * options.get('outlierIQR'))) {\r\n rwhisker = values[i];\r\n }\r\n }\r\n loutlier = values[0];\r\n routlier = values[vlen - 1];\r\n } else {\r\n lwhisker = values[0];\r\n rwhisker = values[vlen - 1];\r\n }\r\n }\r\n this.quartiles = [q1, q2, q3];\r\n this.lwhisker = lwhisker;\r\n this.rwhisker = rwhisker;\r\n this.loutlier = loutlier;\r\n this.routlier = routlier;\r\n\r\n unitSize = canvasWidth / (maxValue - minValue + 1);\r\n if (options.get('showOutliers')) {\r\n canvasLeft = Math.ceil(options.get('spotRadius'));\r\n canvasWidth -= 2 * Math.ceil(options.get('spotRadius'));\r\n unitSize = canvasWidth / (maxValue - minValue + 1);\r\n if (loutlier < lwhisker) {\r\n target.drawCircle((loutlier - minValue) * unitSize + canvasLeft,\r\n canvasHeight / 2,\r\n options.get('spotRadius'),\r\n options.get('outlierLineColor'),\r\n options.get('outlierFillColor')).append();\r\n }\r\n if (routlier > rwhisker) {\r\n target.drawCircle((routlier - minValue) * unitSize + canvasLeft,\r\n canvasHeight / 2,\r\n options.get('spotRadius'),\r\n options.get('outlierLineColor'),\r\n options.get('outlierFillColor')).append();\r\n }\r\n }\r\n\r\n // box\r\n target.drawRect(\r\n Math.round((q1 - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight * 0.1),\r\n Math.round((q3 - q1) * unitSize),\r\n Math.round(canvasHeight * 0.8),\r\n options.get('boxLineColor'),\r\n options.get('boxFillColor')).append();\r\n // left whisker\r\n target.drawLine(\r\n Math.round((lwhisker - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight / 2),\r\n Math.round((q1 - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight / 2),\r\n options.get('lineColor')).append();\r\n target.drawLine(\r\n Math.round((lwhisker - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight / 4),\r\n Math.round((lwhisker - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight - canvasHeight / 4),\r\n options.get('whiskerColor')).append();\r\n // right whisker\r\n target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight / 2),\r\n Math.round((q3 - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight / 2),\r\n options.get('lineColor')).append();\r\n target.drawLine(\r\n Math.round((rwhisker - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight / 4),\r\n Math.round((rwhisker - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight - canvasHeight / 4),\r\n options.get('whiskerColor')).append();\r\n // median line\r\n target.drawLine(\r\n Math.round((q2 - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight * 0.1),\r\n Math.round((q2 - minValue) * unitSize + canvasLeft),\r\n Math.round(canvasHeight * 0.9),\r\n options.get('medianColor')).append();\r\n if (options.get('target')) {\r\n size = Math.ceil(options.get('spotRadius'));\r\n target.drawLine(\r\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft),\r\n Math.round((canvasHeight / 2) - size),\r\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft),\r\n Math.round((canvasHeight / 2) + size),\r\n options.get('targetColor')).append();\r\n target.drawLine(\r\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft - size),\r\n Math.round(canvasHeight / 2),\r\n Math.round((options.get('target') - minValue) * unitSize + canvasLeft + size),\r\n Math.round(canvasHeight / 2),\r\n options.get('targetColor')).append();\r\n }\r\n //target.render();\r\n }\r\n },\r\n shapeCount:0,\r\n shapes:{},\r\n shapeseq:[],\r\n lastShapeId:null,\r\n mergedOptions:null,\r\n init:function(userValues, userOptions){\r\n let extendedOptions, defaults, base;\r\n userOptions = userOptions || {};\r\n let _this = this;\r\n defaults = this.defaultOption;\r\n base = defaults.common;\r\n extendedOptions = defaults[userOptions.type || base.type];\r\n\r\n _this.shapeCount = 0;\r\n _this.shapes = {};\r\n _this.shapeseq = [];\r\n _this.lastShapeId = null;\r\n\r\n _this.mergedOptions = $.extend({}, base, extendedOptions, userOptions);\r\n _this.mergedOptions.width = _this.mergedOptions.width;\r\n _this.mergedOptions.height = _this.mergedOptions.height;\r\n _this[_this.mergedOptions.type].render(_this, userValues);\r\n\r\n return { shapes:_this.shapes, shapeseq:_this.shapeseq, offsetX:_this.mergedOptions.offsetX, offsetY:_this.mergedOptions.offsetY, pixelWidth:_this.mergedOptions.width, pixelHeight:_this.mergedOptions.height};\r\n\r\n },\r\n _getContext: function (lineColor, fillColor, lineWidth) {\r\n let context;\r\n if(this.ctx != null){\r\n context = this.ctx;\r\n }\r\n else{\r\n context = $(\"#\" + this._canvasID ).get(0).getContext('2d');\r\n }\r\n\r\n if (lineColor !== undefined) {\r\n context.strokeStyle = lineColor;\r\n }\r\n context.lineWidth = lineWidth === undefined ? 1 : lineWidth;\r\n if (fillColor !== undefined) {\r\n context.fillStyle = fillColor;\r\n }\r\n return context;\r\n },\r\n\r\n reset: function () {\r\n let context = this._getContext();\r\n context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);\r\n this.shapes = {};\r\n this.shapeseq = [];\r\n this.currentTargetShapeId = undefined;\r\n },\r\n\r\n _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) {\r\n let context = this._getContext(lineColor, fillColor, lineWidth),\r\n i, plen;\r\n context.beginPath();\r\n context.moveTo(path[0][0] + 0.5 + this.offsetX, path[0][1] + 0.5 + this.offsetY);\r\n \r\n for (i = 1, plen = path.length; i < plen; i++) {\r\n context.lineTo(path[i][0] + 0.5 + this.offsetX, path[i][1] + 0.5 + this.offsetY); // the 0.5 offset gives us crisp pixel-width lines\r\n }\r\n if (lineColor !== undefined) {\r\n context.stroke();\r\n }\r\n if (fillColor !== undefined) {\r\n context.fill();\r\n }\r\n if (this.targetX !== undefined && this.targetY !== undefined &&\r\n context.isPointInPath(this.targetX + this.offsetX, this.targetY + this.offsetY)) {\r\n this.currentTargetShapeId = shapeid;\r\n }\r\n },\r\n\r\n _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {\r\n let context = this._getContext(lineColor, fillColor, lineWidth);\r\n context.beginPath();\r\n x+=this.offsetX;\r\n y+=this.offsetY;\r\n context.arc(x, y, radius, 0, 2 * Math.PI, false);\r\n if (this.targetX !== undefined && this.targetY !== undefined &&\r\n context.isPointInPath(this.targetX+this.offsetX, this.targetY+this.offsetY)) {\r\n this.currentTargetShapeId = shapeid;\r\n }\r\n if (lineColor !== undefined) {\r\n context.stroke();\r\n }\r\n if (fillColor !== undefined) {\r\n context.fill();\r\n }\r\n },\r\n\r\n _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {\r\n let context = this._getContext(lineColor, fillColor);\r\n x+=this.offsetX;\r\n y+=this.offsetY;\r\n context.beginPath();\r\n context.moveTo(x, y);\r\n context.arc(x, y, radius, startAngle, endAngle, false);\r\n context.lineTo(x, y);\r\n context.closePath();\r\n if (lineColor !== undefined) {\r\n context.stroke();\r\n }\r\n if (fillColor) {\r\n context.fill();\r\n }\r\n if (this.targetX !== undefined && this.targetY !== undefined &&\r\n context.isPointInPath(this.targetX+this.offsetX, this.targetY+this.offsetY)) {\r\n this.currentTargetShapeId = shapeid;\r\n }\r\n },\r\n\r\n _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) {\r\n // x+=this.offsetX;\r\n // y+=this.offsetY;\r\n return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor);\r\n },\r\n\r\n appendShape: function (shape) {\r\n this.shapes[shape.id] = shape;\r\n this.shapeseq.push(shape.id);\r\n this.lastShapeId = shape.id;\r\n return shape.id;\r\n },\r\n\r\n replaceWithShape: function (shapeid, shape) {\r\n let shapeseq = this.shapeseq,\r\n i;\r\n this.shapes[shape.id] = shape;\r\n for (i = shapeseq.length; i--;) {\r\n if (shapeseq[i] == shapeid) {\r\n shapeseq[i] = shape.id;\r\n }\r\n }\r\n delete this.shapes[shapeid];\r\n },\r\n\r\n replaceWithShapes: function (shapeids, shapes) {\r\n let shapeseq = this.shapeseq,\r\n shapemap = {},\r\n sid, i, first;\r\n\r\n for (i = shapeids.length; i--;) {\r\n shapemap[shapeids[i]] = true;\r\n }\r\n for (i = shapeseq.length; i--;) {\r\n sid = shapeseq[i];\r\n if (shapemap[sid]) {\r\n shapeseq.splice(i, 1);\r\n delete this.shapes[sid];\r\n first = i;\r\n }\r\n }\r\n for (i = shapes.length; i--;) {\r\n shapeseq.splice(first, 0, shapes[i].id);\r\n this.shapes[shapes[i].id] = shapes[i];\r\n }\r\n\r\n },\r\n\r\n insertAfterShape: function (shapeid, shape) {\r\n let shapeseq = this.shapeseq,\r\n i;\r\n for (i = shapeseq.length; i--;) {\r\n if (shapeseq[i] === shapeid) {\r\n shapeseq.splice(i + 1, 0, shape.id);\r\n this.shapes[shape.id] = shape;\r\n return;\r\n }\r\n }\r\n },\r\n\r\n removeShapeId: function (shapeid) {\r\n let shapeseq = this.shapeseq,\r\n i;\r\n for (i = shapeseq.length; i--;) {\r\n if (shapeseq[i] === shapeid) {\r\n shapeseq.splice(i, 1);\r\n break;\r\n }\r\n }\r\n delete this.shapes[shapeid];\r\n },\r\n\r\n getShapeAt: function (el, x, y) {\r\n this.targetX = x;\r\n this.targetY = y;\r\n this.render();\r\n return this.currentTargetShapeId;\r\n },\r\n _canvasID:\"luckysheetTableContent\",\r\n render: function (shapeseq, shapes, offsetX, offsetY, pixelWidth, pixelHeight,canvasid,ctx) {\r\n if(canvasid==null){\r\n canvasid = \"luckysheetTableContent\";\r\n }\r\n this._canvasID = canvasid;\r\n\r\n if(ctx != null){\r\n this.ctx = ctx;\r\n }\r\n\r\n let shapeCount = shapeseq.length,\r\n context = this._getContext(),\r\n shapeid, shape, i;\r\n this.offsetX = offsetX;\r\n this.offsetY = offsetY;\r\n this.pixelWidth = pixelWidth;\r\n this.pixelHeight = pixelHeight;\r\n //context.clearRect(this.offsetX, this.offsetY, this.pixelWidth, this.pixelHeight);\r\n\r\n // qkSparkSetting.currentSparkVlaue = {\r\n // shapeseq : shapeseq,\r\n // shapes:shapes,\r\n // shapeCount:shapeCount,\r\n // el:this\r\n // }\r\n\r\n for (i = 0; i < shapeCount; i++) {\r\n shapeid = shapeseq[i];\r\n shape = shapes[shapeid];\r\n this['_draw' + shape.type].apply(this, shape.args);\r\n }\r\n // if (!this.interact) {\r\n // // not interactive so no need to keep the shapes array\r\n // this.shapes = {};\r\n // this.shapeseq = [];\r\n // }\r\n },\r\n drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) {\r\n return this.drawShape([[x1, y1], [x2, y2]], lineColor, lineWidth);\r\n },\r\n\r\n drawShape: function (path, lineColor, fillColor, lineWidth) {\r\n return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]);\r\n },\r\n\r\n drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) {\r\n return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]);\r\n },\r\n\r\n drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) {\r\n return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]);\r\n },\r\n\r\n drawRect: function (x, y, width, height, lineColor, fillColor) {\r\n return this._genShape('Rect', [x, y, width, height, lineColor, fillColor]);\r\n },\r\n _genShape: function (shapetype, shapeargs) {\r\n let id = this.shapeCount++;\r\n shapeargs.unshift(id);\r\n // return new VShape(this, id, shapetype, shapeargs);\r\n // this.target = target;\r\n // this.id = id;\r\n // this.type = type;\r\n // this.args = args;\r\n let shape = { id:id, type:shapetype, args:shapeargs };\r\n this.shapes[id] = shape;\r\n this.shapeseq.push(id);\r\n this.lastShapeId = id;\r\n return {\r\n append:function(){\r\n return shape;\r\n },\r\n get:function(){\r\n return id;\r\n }\r\n };\r\n }\r\n\r\n}\r\n\r\nlet barHighlightMixin = {\r\n changeHighlight: function (highlight) {\r\n let currentRegion = this.currentRegion,\r\n target = this.target,\r\n shapeids = this.regionShapes[currentRegion],\r\n newShapes;\r\n // will be null if the region value was null\r\n if (shapeids) {\r\n newShapes = this.renderRegion(currentRegion, highlight);\r\n if ($.isArray(newShapes) || $.isArray(shapeids)) {\r\n target.replaceWithShapes(shapeids, newShapes);\r\n this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) {\r\n return newShape.id;\r\n });\r\n } else {\r\n target.replaceWithShape(shapeids, newShapes);\r\n this.regionShapes[currentRegion] = newShapes.id;\r\n }\r\n }\r\n },\r\n render: function (el,userValues) {\r\n this.init(el, userValues);\r\n let values = this.values,\r\n target = this.target,\r\n regionShapes = this.regionShapes,\r\n shapes, ids, i, j;\r\n\r\n // if (!this.cls._super.render.call(this)) {\r\n // return;\r\n // }\r\n for (i = values.length; i--;) {\r\n shapes = this.renderRegion(i);\r\n if (shapes) {\r\n if ($.isArray(shapes)) {\r\n ids = [];\r\n for (j = shapes.length; j--;) {\r\n shapes[j].append();\r\n ids.push(shapes[j].id);\r\n }\r\n regionShapes[i] = ids;\r\n } else {\r\n shapes.append();\r\n regionShapes[i] = shapes.id; // store just the shapeid\r\n }\r\n } else {\r\n // null value\r\n regionShapes[i] = null;\r\n }\r\n }\r\n //target.render();\r\n }\r\n};\r\n\r\nlet _luckysheetSparkLineOptions = {\r\n get:function(type){\r\n return luckysheetSparkline.mergedOptions[type];\r\n }\r\n}\r\n\r\nlet _luckysheetSparkLineTarget = {\r\n drawLine:function(x1, y1, x2, y2, lineColor, lineWidth){\r\n return luckysheetSparkline.drawLine(x1, y1, x2, y2, lineColor, lineWidth);\r\n },\r\n\r\n drawShape:function(path, lineColor, fillColor, lineWidth){\r\n return luckysheetSparkline.drawShape(path, lineColor, fillColor, lineWidth);\r\n },\r\n\r\n drawCircle:function(x, y, radius, lineColor, fillColor, lineWidth){\r\n return luckysheetSparkline.drawCircle(x, y, radius, lineColor, fillColor, lineWidth);\r\n },\r\n\r\n drawPieSlice:function(x, y, radius, startAngle, endAngle, lineColor, fillColor){\r\n return luckysheetSparkline.drawPieSlice(x, y, radius, startAngle, endAngle, lineColor, fillColor);\r\n },\r\n\r\n drawRect:function(x, y, width, height, lineColor, fillColor){\r\n return luckysheetSparkline.drawRect(x, y, width, height, lineColor, fillColor);\r\n }\r\n}\r\n\r\nfor(let item in luckysheetSparkline){\r\n if(item in {\"line\":null, \"bar\":null, \"column\":null, \"tristate\":null, \"discrete\":null, \"bullet\":null, \"pie\":null, \"box\":null}){\r\n luckysheetSparkline[item].options = _luckysheetSparkLineOptions;\r\n luckysheetSparkline[item].target = _luckysheetSparkLineTarget;\r\n }\r\n\r\n if(item in {\"bar\":null, \"column\":null, \"tristate\":null, \"discrete\":null}){\r\n luckysheetSparkline[item].changeHighlight = barHighlightMixin.changeHighlight;\r\n luckysheetSparkline[item].render = barHighlightMixin.render;\r\n }\r\n}\r\n\r\nexport default luckysheetSparkline;\r\n","import pivotTable from '../controllers/pivotTable';\r\nimport conditionformat from '../controllers/conditionformat';\r\nimport alternateformat from '../controllers/alternateformat';\r\nimport luckysheetSparkline from '../controllers/sparkline';\r\nimport menuButton from '../controllers/menuButton';\r\nimport dataVerificationCtrl from '../controllers/dataVerificationCtrl';\r\nimport { luckysheetdefaultstyle, luckysheet_CFiconsImg,luckysheetdefaultFont } from '../controllers/constant';\r\nimport { luckysheet_searcharray } from '../controllers/sheetSearch';\r\nimport { dynamicArrayCompute } from './dynamicArray';\r\nimport browser from './browser';\r\nimport { isRealNull, isRealNum } from './validate';\r\nimport { getMeasureText,getCellTextInfo } from './getRowlen';\r\nimport { getRealCellValue } from './getdata';\r\nimport { getBorderInfoComputeRange } from './border';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { getObjType, chatatABC, luckysheetfontformat } from '../utils/util';\r\nimport { isInlineStringCell } from '../controllers/inlineString';\r\nimport method from './method';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport sheetmanage from '../controllers/sheetmanage';\r\n\r\nfunction luckysheetDrawgridRowTitle(scrollHeight, drawHeight, offsetTop) {\r\n if (scrollHeight == null) {\r\n scrollHeight = $(\"#luckysheet-cell-main\").scrollTop();\r\n }\r\n\r\n if (drawHeight == null) {\r\n drawHeight = Store.luckysheetTableContentHW[1];\r\n }\r\n\r\n if (offsetTop == null) {\r\n offsetTop = Store.columnHeaderHeight;\r\n }\r\n \r\n let luckysheetTableContent = $(\"#luckysheetTableContent\").get(0).getContext(\"2d\");\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.scale(Store.devicePixelRatio, Store.devicePixelRatio);\r\n\r\n luckysheetTableContent.clearRect(\r\n 0,\r\n offsetTop ,\r\n (Store.rowHeaderWidth - 1) ,\r\n drawHeight\r\n );\r\n\r\n luckysheetTableContent.font = luckysheetdefaultFont();\r\n luckysheetTableContent.textBaseline = luckysheetdefaultstyle.textBaseline; //基准线 垂直居中\r\n luckysheetTableContent.fillStyle = luckysheetdefaultstyle.fillStyle;\r\n\r\n let dataset_row_st, dataset_row_ed;\r\n dataset_row_st = luckysheet_searcharray(Store.visibledatarow, scrollHeight);\r\n dataset_row_ed = luckysheet_searcharray(Store.visibledatarow, scrollHeight + drawHeight);\r\n\r\n if (dataset_row_st == -1) {\r\n dataset_row_st = 0;\r\n }\r\n if (dataset_row_ed == -1) {\r\n dataset_row_ed = Store.visibledatarow.length - 1;\r\n }\r\n \r\n\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.rect(0, offsetTop-1, Store.rowHeaderWidth -1, drawHeight-2);\r\n luckysheetTableContent.clip();\r\n\r\n let end_r, start_r;\r\n let bodrder05 = 0.5;//Default 0.5\r\n let preEndR;\r\n for (let r = dataset_row_st; r <= dataset_row_ed; r++) {\r\n if (r == 0) {\r\n start_r = -scrollHeight - 1;\r\n }\r\n else {\r\n start_r = Store.visibledatarow[r - 1] - scrollHeight - 1;\r\n }\r\n end_r = Store.visibledatarow[r] - scrollHeight;\r\n\r\n //若超出绘制区域终止\r\n // if(end_r > scrollHeight + drawHeight){\r\n // break;\r\n // }\r\n let firstOffset = (dataset_row_st==r)?-2:0;\r\n let lastOffset = (dataset_row_ed==r)?-2:0;\r\n //列标题单元格渲染前触发,return false 则不渲染该单元格\r\n if(!method.createHookFunction(\"rowTitleCellRenderBefore\", r+1, {\r\n r:r,\r\n top:(start_r + offsetTop + firstOffset),\r\n width:Store.rowHeaderWidth -1,\r\n height:(end_r - start_r + 1+lastOffset-firstOffset)\r\n }, luckysheetTableContent)){ continue; }\r\n\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n\r\n }\r\n else {\r\n luckysheetTableContent.fillStyle = \"#ffffff\";\r\n luckysheetTableContent.fillRect(\r\n 0,\r\n (start_r + offsetTop + firstOffset) , \r\n Store.rowHeaderWidth -1,\r\n (end_r - start_r + 1+lastOffset-firstOffset) \r\n )\r\n luckysheetTableContent.fillStyle = \"#000000\";\r\n\r\n //行标题栏序列号\r\n luckysheetTableContent.save();//save scale before draw text\r\n luckysheetTableContent.scale(Store.zoomRatio,Store.zoomRatio);\r\n let textMetrics = getMeasureText(r+1, luckysheetTableContent); \r\n //luckysheetTableContent.measureText(r + 1);\r\n\r\n let horizonAlignPos = (Store.rowHeaderWidth - textMetrics.width) / 2;\r\n let verticalAlignPos = (start_r + (end_r - start_r) / 2 + offsetTop) ;\r\n\r\n luckysheetTableContent.fillText(r + 1, horizonAlignPos/Store.zoomRatio, verticalAlignPos/Store.zoomRatio);\r\n luckysheetTableContent.restore();//restore scale after draw text\r\n }\r\n\r\n //vertical\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (Store.rowHeaderWidth - 2 + bodrder05) ,\r\n (start_r + offsetTop - 2)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (Store.rowHeaderWidth - 2 + bodrder05) ,\r\n (end_r + offsetTop - 2)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n\r\n luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n\r\n //行标题栏横线,horizen\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] == null && Store.config[\"rowhidden\"][r+1] != null) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n -1,\r\n (end_r + offsetTop - 4 + bodrder05) \r\n );\r\n luckysheetTableContent.lineTo(\r\n (Store.rowHeaderWidth - 1) ,\r\n (end_r + offsetTop - 4 + bodrder05) \r\n );\r\n // luckysheetTableContent.lineWidth = 1;\r\n // luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n else if(Store.config[\"rowhidden\"]==null || Store.config[\"rowhidden\"][r] == null){\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n -1,\r\n (end_r + offsetTop - 2 + bodrder05) \r\n );\r\n luckysheetTableContent.lineTo(\r\n (Store.rowHeaderWidth - 1) ,\r\n (end_r + offsetTop - 2 + bodrder05) \r\n );\r\n\r\n // luckysheetTableContent.lineWidth = 1;\r\n // luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n\r\n }\r\n\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r-1] != null && preEndR!=null) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n -1,\r\n (preEndR + offsetTop + bodrder05) \r\n );\r\n luckysheetTableContent.lineTo(\r\n (Store.rowHeaderWidth - 1) ,\r\n (preEndR + offsetTop + bodrder05) \r\n );\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n\r\n preEndR = end_r;\r\n\r\n //列标题单元格渲染前触发,return false 则不渲染该单元格\r\n method.createHookFunction(\"rowTitleCellRenderAfter\", r+1, {\r\n r:r,\r\n top:(start_r + offsetTop + firstOffset),\r\n width:Store.rowHeaderWidth -1,\r\n height:(end_r - start_r + 1+lastOffset-firstOffset)\r\n }, luckysheetTableContent)\r\n\r\n }\r\n\r\n //行标题栏竖线\r\n // luckysheetTableContent.beginPath();\r\n // luckysheetTableContent.moveTo(\r\n // (Store.rowHeaderWidth - 2 + 0.5) ,\r\n // (offsetTop - 1) \r\n // );\r\n // luckysheetTableContent.lineTo(\r\n // (Store.rowHeaderWidth - 2 + 0.5) ,\r\n // (Store.rh_height + offsetTop) \r\n // );\r\n // luckysheetTableContent.lineWidth = 1;\r\n // luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n // luckysheetTableContent.closePath();\r\n // luckysheetTableContent.stroke();\r\n\r\n\r\n //清除canvas左上角区域 防止列标题栏序列号溢出显示\r\n // luckysheetTableContent.clearRect(0, 0, Store.rowHeaderWidth , Store.columnHeaderHeight );\r\n\r\n // Must be restored twice, otherwise it will be enlarged under window.devicePixelRatio = 1.5\r\n luckysheetTableContent.restore();\r\n luckysheetTableContent.restore();\r\n \r\n}\r\n\r\nfunction luckysheetDrawgridColumnTitle(scrollWidth, drawWidth, offsetLeft) {\r\n if (scrollWidth == null) {\r\n scrollWidth = $(\"#luckysheet-cell-main\").scrollLeft();\r\n }\r\n\r\n if (drawWidth == null) {\r\n drawWidth = Store.luckysheetTableContentHW[0];\r\n }\r\n\r\n if (offsetLeft == null) {\r\n offsetLeft = Store.rowHeaderWidth;\r\n }\r\n \r\n let luckysheetTableContent = $(\"#luckysheetTableContent\").get(0).getContext(\"2d\");\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.scale(Store.devicePixelRatio, Store.devicePixelRatio);\r\n luckysheetTableContent.clearRect(\r\n offsetLeft ,\r\n 0,\r\n drawWidth ,\r\n (Store.columnHeaderHeight - 1) \r\n );\r\n\r\n\r\n luckysheetTableContent.font = luckysheetdefaultFont();\r\n luckysheetTableContent.textBaseline = luckysheetdefaultstyle.textBaseline; //基准线 垂直居中\r\n luckysheetTableContent.fillStyle = luckysheetdefaultstyle.fillStyle;\r\n\r\n let dataset_col_st, dataset_col_ed;\r\n dataset_col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollWidth);\r\n dataset_col_ed = luckysheet_searcharray(Store.visibledatacolumn, scrollWidth + drawWidth);\r\n\r\n if (dataset_col_st == -1) {\r\n dataset_col_st = 0;\r\n }\r\n if (dataset_col_ed == -1) {\r\n dataset_col_ed = Store.visibledatacolumn.length - 1;\r\n }\r\n \r\n luckysheetTableContent.save();\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.rect(offsetLeft-1, 0, drawWidth, Store.columnHeaderHeight -1);\r\n luckysheetTableContent.clip();\r\n\r\n // console.log(offsetLeft, 0, drawWidth, Store.columnHeaderHeight -1);\r\n\r\n let end_c, start_c;\r\n let bodrder05 = 0.5;//Default 0.5\r\n let preEndC;\r\n for (let c = dataset_col_st; c <= dataset_col_ed; c++) {\r\n if (c == 0) {\r\n start_c = -scrollWidth;\r\n }\r\n else {\r\n start_c = Store.visibledatacolumn[c - 1] - scrollWidth;\r\n }\r\n end_c = Store.visibledatacolumn[c] - scrollWidth;\r\n\r\n //若超出绘制区域终止\r\n // if(end_c > scrollWidth + drawWidth+1){\r\n // break;\r\n // }\r\n let abc = chatatABC(c);\r\n //列标题单元格渲染前触发,return false 则不渲染该单元格\r\n if(!method.createHookFunction(\"columnTitleCellRenderBefore\", abc, {\r\n c:c,\r\n left:(start_c + offsetLeft - 1),\r\n width:(end_c - start_c),\r\n height:Store.columnHeaderHeight -1\r\n }, luckysheetTableContent)){ continue; }\r\n \r\n if (Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][c] != null) {\r\n\r\n }\r\n else {\r\n luckysheetTableContent.fillStyle = \"#ffffff\";\r\n luckysheetTableContent.fillRect(\r\n (start_c + offsetLeft - 1) , \r\n 0, \r\n (end_c - start_c) ,\r\n Store.columnHeaderHeight -1\r\n )\r\n luckysheetTableContent.fillStyle = \"#000000\";\r\n\r\n //列标题栏序列号\r\n luckysheetTableContent.save();//save scale before draw text\r\n luckysheetTableContent.scale(Store.zoomRatio,Store.zoomRatio);\r\n \r\n let textMetrics = getMeasureText(abc, luckysheetTableContent);\r\n //luckysheetTableContent.measureText(abc);\r\n\r\n let horizonAlignPos = Math.round((start_c + (end_c - start_c) / 2 + offsetLeft) - textMetrics.width / 2);\r\n let verticalAlignPos = Math.round(Store.columnHeaderHeight / 2 );\r\n \r\n luckysheetTableContent.fillText(abc, horizonAlignPos/Store.zoomRatio, verticalAlignPos/Store.zoomRatio);\r\n luckysheetTableContent.restore();//restore scale after draw text\r\n }\r\n\r\n //列标题栏竖线 vertical\r\n if (Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][c] == null && Store.config[\"colhidden\"][c+1] != null) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (end_c + offsetLeft - 4 + bodrder05) ,\r\n 0\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft - 4 + bodrder05) ,\r\n (Store.columnHeaderHeight - 2) \r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n else if(Store.config[\"colhidden\"]==null || Store.config[\"colhidden\"][c] == null) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (end_c + offsetLeft - 2 + bodrder05) ,\r\n 0\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft - 2 + bodrder05) ,\r\n (Store.columnHeaderHeight - 2) \r\n );\r\n\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n\r\n if (Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][c-1] != null && preEndC!=null) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (preEndC + offsetLeft + bodrder05) ,\r\n 0\r\n );\r\n luckysheetTableContent.lineTo(\r\n (preEndC + offsetLeft + bodrder05) ,\r\n (Store.columnHeaderHeight - 2) \r\n );\r\n // luckysheetTableContent.lineWidth = 1;\r\n // luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n\r\n\r\n //horizen\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (start_c + offsetLeft - 1), \r\n (Store.columnHeaderHeight - 2 + bodrder05) \r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft - 1), \r\n (Store.columnHeaderHeight - 2 + bodrder05) \r\n );\r\n // luckysheetTableContent.lineWidth = 1;\r\n\r\n // luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle; \r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n\r\n preEndC = end_c;\r\n\r\n method.createHookFunction(\"columnTitleCellRenderAfter\", abc, {\r\n c:c,\r\n left:(start_c + offsetLeft - 1),\r\n width:(end_c - start_c),\r\n height:Store.columnHeaderHeight -1\r\n }, luckysheetTableContent)\r\n }\r\n\r\n //列标题栏横线\r\n // luckysheetTableContent.beginPath();\r\n // luckysheetTableContent.moveTo(\r\n // (offsetLeft - 1) ,\r\n // (Store.columnHeaderHeight - 2 + 0.5) \r\n // );\r\n // luckysheetTableContent.lineTo(\r\n // (Store.ch_width + offsetLeft - 2) ,\r\n // (Store.columnHeaderHeight - 2 + 0.5) \r\n // );\r\n // luckysheetTableContent.lineWidth = 1;\r\n // luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n // luckysheetTableContent.closePath();\r\n // luckysheetTableContent.stroke();\r\n\r\n //清除canvas左上角区域 防止列标题栏序列号溢出显示\r\n // luckysheetTableContent.clearRect(0, 0, Store.rowHeaderWidth , Store.columnHeaderHeight );\r\n\r\n // Must be restored twice, otherwise it will be enlarged under window.devicePixelRatio = 1.5\r\n luckysheetTableContent.restore();\r\n luckysheetTableContent.restore();\r\n\r\n}\r\n\r\nfunction luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, offsetLeft, offsetTop, columnOffsetCell, rowOffsetCell, mycanvas) {\r\n\r\n if(Store.flowdata == null){\r\n return;\r\n }\r\n\r\n let sheetFile = sheetmanage.getSheetByIndex();\r\n\r\n // console.trace();\r\n clearTimeout(Store.measureTextCacheTimeOut);\r\n \r\n //参数未定义处理\r\n if (scrollWidth == null) {\r\n scrollWidth = $(\"#luckysheet-cell-main\").scrollLeft();\r\n }\r\n if (scrollHeight == null) {\r\n scrollHeight = $(\"#luckysheet-cell-main\").scrollTop();\r\n }\r\n\r\n if (drawWidth == null) {\r\n drawWidth = Store.luckysheetTableContentHW[0];\r\n }\r\n if (drawHeight == null) {\r\n drawHeight = Store.luckysheetTableContentHW[1];\r\n }\r\n\r\n if (offsetLeft == null) {\r\n offsetLeft = Store.rowHeaderWidth;\r\n }\r\n if (offsetTop == null) {\r\n offsetTop = Store.columnHeaderHeight;\r\n }\r\n\r\n if (columnOffsetCell == null) {\r\n columnOffsetCell = 0;\r\n }\r\n if (rowOffsetCell == null) {\r\n rowOffsetCell = 0;\r\n }\r\n\r\n //表格canvas\r\n let luckysheetTableContent = null;\r\n if(mycanvas == null){\r\n luckysheetTableContent = $(\"#luckysheetTableContent\").get(0).getContext(\"2d\");\r\n }\r\n else {\r\n if(getObjType(mycanvas) == \"object\"){\r\n try{\r\n luckysheetTableContent = mycanvas.get(0).getContext(\"2d\");\r\n }\r\n catch(err){\r\n luckysheetTableContent = mycanvas;\r\n }\r\n }\r\n else{\r\n luckysheetTableContent = $(\"#\" + mycanvas).get(0).getContext(\"2d\");\r\n }\r\n }\r\n\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.scale(Store.devicePixelRatio, Store.devicePixelRatio);\r\n \r\n luckysheetTableContent.clearRect(\r\n 0, \r\n 0, \r\n Store.luckysheetTableContentHW[0],\r\n Store.luckysheetTableContentHW[1]\r\n );\r\n\r\n //表格渲染区域 起止行列下标\r\n let dataset_row_st, \r\n dataset_row_ed, \r\n dataset_col_st, \r\n dataset_col_ed;\r\n\r\n dataset_row_st = luckysheet_searcharray(Store.visibledatarow, scrollHeight);\r\n dataset_row_ed = luckysheet_searcharray(Store.visibledatarow, scrollHeight + drawHeight);\r\n\r\n if (dataset_row_st == -1) {\r\n dataset_row_st = 0;\r\n }\r\n\r\n dataset_row_st += rowOffsetCell;\r\n\r\n if (dataset_row_ed == -1) {\r\n dataset_row_ed = Store.visibledatarow.length - 1;\r\n }\r\n\r\n dataset_row_ed += rowOffsetCell;\r\n\r\n if (dataset_row_ed >= Store.visibledatarow.length) {\r\n dataset_row_ed = Store.visibledatarow.length - 1;\r\n }\r\n\r\n dataset_col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollWidth);\r\n dataset_col_ed = luckysheet_searcharray(Store.visibledatacolumn, scrollWidth + drawWidth);\r\n \r\n if (dataset_col_st == -1) {\r\n dataset_col_st = 0;\r\n }\r\n\r\n dataset_col_st += columnOffsetCell;\r\n\r\n if (dataset_col_ed == -1) {\r\n dataset_col_ed = Store.visibledatacolumn.length - 1;\r\n }\r\n\r\n dataset_col_ed += columnOffsetCell;\r\n\r\n if (dataset_col_ed >= Store.visibledatacolumn.length) {\r\n dataset_col_ed = Store.visibledatacolumn.length - 1;\r\n }\r\n\r\n //表格渲染区域 起止行列坐标\r\n let fill_row_st, \r\n fill_row_ed, \r\n fill_col_st, \r\n fill_col_ed;\r\n\r\n if(dataset_row_st == 0){\r\n fill_row_st = 0;\r\n }\r\n else{\r\n fill_row_st = Store.visibledatarow[dataset_row_st - 1];\r\n }\r\n\r\n fill_row_ed = Store.visibledatarow[dataset_row_ed];\r\n\r\n if(dataset_col_st == 0){\r\n fill_col_st = 0;\r\n }\r\n else{\r\n fill_col_st = Store.visibledatacolumn[dataset_col_st - 1];\r\n }\r\n\r\n fill_col_ed = Store.visibledatacolumn[dataset_col_ed];\r\n\r\n //表格canvas 初始化处理\r\n luckysheetTableContent.fillStyle = \"#ffffff\";\r\n luckysheetTableContent.fillRect(\r\n (offsetLeft - 1) , \r\n (offsetTop - 1) , \r\n (fill_col_ed - scrollWidth) , \r\n (fill_row_ed - scrollHeight)\r\n );\r\n luckysheetTableContent.font = luckysheetdefaultFont();\r\n // luckysheetTableContent.textBaseline = \"top\";\r\n luckysheetTableContent.fillStyle = luckysheetdefaultstyle.fillStyle;\r\n\r\n //表格渲染区域 非空单元格行列 起止坐标\r\n let cellupdate = [];\r\n let mergeCache = {};\r\n let borderOffset = {};\r\n\r\n let bodrder05 = 0.5;//Default 0.5\r\n\r\n // 钩子函数\r\n method.createHookFunction(\"cellAllRenderBefore\",Store.flowdata,sheetFile,luckysheetTableContent);\r\n \r\n for (let r = dataset_row_st; r <= dataset_row_ed; r++) {\r\n let start_r;\r\n if (r == 0) {\r\n start_r = -scrollHeight - 1;\r\n }\r\n else {\r\n start_r = Store.visibledatarow[r - 1] - scrollHeight - 1;\r\n }\r\n\r\n let end_r = Store.visibledatarow[r] - scrollHeight;\r\n\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n \r\n for (let c = dataset_col_st; c <= dataset_col_ed; c++) {\r\n let start_c;\r\n if (c == 0) {\r\n start_c = -scrollWidth;\r\n }\r\n else {\r\n start_c = Store.visibledatacolumn[c - 1] - scrollWidth;\r\n }\r\n\r\n let end_c = Store.visibledatacolumn[c] - scrollWidth;\r\n \r\n if (Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][c] != null) {\r\n continue\r\n }\r\n \r\n let firstcolumnlen = Store.defaultcollen;\r\n if (Store.config[\"columnlen\"] != null && Store.config[\"columnlen\"][c] != null) {\r\n firstcolumnlen = Store.config[\"columnlen\"][c];\r\n }\r\n\r\n\r\n\r\n if (Store.flowdata[r] != null && Store.flowdata[r][c] != null) {\r\n let value = Store.flowdata[r][c];\r\n\r\n if(getObjType(value) == \"object\" && (\"mc\" in value)){\r\n borderOffset[r + \"_\" + c] = { \r\n \"start_r\": start_r,\r\n \"start_c\": start_c, \r\n \"end_r\": end_r, \r\n \"end_c\": end_c \r\n };\r\n\r\n if(\"rs\" in value[\"mc\"]){\r\n let key = \"r\"+ r + \"c\" + c;\r\n mergeCache[key] = cellupdate.length;\r\n }\r\n else{\r\n let key = \"r\"+ value[\"mc\"].r + \"c\" + value[\"mc\"].c;\r\n let margeMain = cellupdate[mergeCache[key]];\r\n\r\n if(margeMain == null){\r\n mergeCache[key] = cellupdate.length;\r\n cellupdate.push({\r\n \"r\": r, \r\n \"c\": c, \r\n \"start_c\": start_c, \r\n \"start_r\": start_r, \r\n \"end_r\": end_r, \r\n \"end_c\": end_c, \r\n \"firstcolumnlen\": firstcolumnlen, \r\n });\r\n }\r\n else{\r\n if(margeMain.c == c){\r\n margeMain.end_r += (end_r - start_r - 1);\r\n }\r\n \r\n if(margeMain.r == r){\r\n margeMain.end_c += (end_c - start_c);\r\n margeMain.firstcolumnlen += firstcolumnlen;\r\n }\r\n }\r\n\r\n continue;\r\n }\r\n }\r\n }\r\n else{\r\n //空单元格渲染前\r\n // if(!method.createHookFunction(\"cellRenderBefore\", Store.flowdata[r][c], {\r\n // r:r,\r\n // c:c,\r\n // \"start_r\": cellsize[1],\r\n // \"start_c\":cellsize[0], \r\n // \"end_r\": cellsize[3], \r\n // \"end_c\": cellsize[2] \r\n // }, sheetFile,luckysheetTableContent)){ continue; }\r\n }\r\n\r\n\r\n cellupdate.push({\r\n \"r\": r, \r\n \"c\": c, \r\n \"start_r\": start_r, \r\n \"start_c\": start_c, \r\n \"end_r\": end_r, \r\n \"end_c\": end_c, \r\n \"firstcolumnlen\": firstcolumnlen, \r\n });\r\n borderOffset[r + \"_\" + c] = { \r\n \"start_r\": start_r, \r\n \"start_c\": start_c, \r\n \"end_r\": end_r, \r\n \"end_c\": end_c \r\n };\r\n }\r\n }\r\n\r\n //动态数组公式计算\r\n let dynamicArray_compute = dynamicArrayCompute(Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray\"]);\r\n\r\n //交替颜色计算\r\n let af_compute = alternateformat.getComputeMap();\r\n\r\n //条件格式计算\r\n let cf_compute = conditionformat.getComputeMap();\r\n\r\n //表格渲染区域 溢出单元格配置保存\r\n let cellOverflowMap = getCellOverflowMap(luckysheetTableContent, dataset_col_st, dataset_col_ed,dataset_row_st,dataset_row_ed);\r\n\r\n let mcArr = [];\r\n\r\n for(let cud = 0; cud < cellupdate.length; cud++){\r\n let item = cellupdate[cud];\r\n let r = item.r, \r\n c = item.c, \r\n start_r = item.start_r, \r\n start_c = item.start_c, \r\n end_r = item.end_r, \r\n end_c = item.end_c;\r\n let firstcolumnlen = item.firstcolumnlen;\r\n\r\n if(Store.flowdata[r] == null){\r\n continue;\r\n }\r\n\r\n // //有值单元格渲染前\r\n // if(!method.createHookFunction(\"cellRenderBefore\", Store.flowdata[r][c], {\r\n // r:r,\r\n // c:c,\r\n // \"start_r\": cellsize[1],\r\n // \"start_c\":cellsize[0], \r\n // \"end_r\": cellsize[3], \r\n // \"end_c\": cellsize[2] \r\n // }, sheetFile,luckysheetTableContent)){ continue; }\r\n \r\n if(Store.flowdata[r][c] == null){ //空单元格\r\n nullCellRender(r, c, start_r, start_c, end_r, end_c,luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05);\r\n }\r\n else{\r\n let cell = Store.flowdata[r][c];\r\n let value = null;\r\n\r\n if((typeof cell == \"object\") && \"mc\" in cell){\r\n mcArr.push(cellupdate[cud]);\r\n // continue;\r\n }\r\n else{\r\n value = getRealCellValue(r,c);\r\n } \r\n\r\n if(value == null || value.toString().length == 0){\r\n nullCellRender(r, c, start_r, start_c, end_r, end_c,luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05);\r\n \r\n //sparklines渲染\r\n let borderfix = menuButton.borderfix(Store.flowdata, r, c);\r\n let cellsize = [\r\n (start_c + offsetLeft + borderfix[0]), \r\n (start_r + offsetTop + borderfix[1]), \r\n (end_c - start_c - 3 + borderfix[2]), \r\n (end_r - start_r - 3 - 1 + borderfix[3])\r\n ];\r\n sparklinesRender(r, c, cellsize[0], cellsize[1], \"luckysheetTableContent\", luckysheetTableContent);\r\n }\r\n else{\r\n if((r + \"_\" + c) in dynamicArray_compute){//动态数组公式\r\n value = dynamicArray_compute[r + \"_\" + c].v;\r\n }\r\n \r\n cellRender(r, c, start_r, start_c, end_r, end_c, value,luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05);\r\n }\r\n }\r\n\r\n // method.createHookFunction(\"cellRenderAfter\", Store.flowdata[r][c], {\r\n // r:r,\r\n // c:c,\r\n // \"start_r\": start_r,\r\n // \"start_c\": start_c, \r\n // \"end_r\": end_r, \r\n // \"end_c\": end_c \r\n // }, sheetFile,luckysheetTableContent)\r\n }\r\n\r\n //合并单元格再处理\r\n for(let m = 0; m < mcArr.length; m++){\r\n let item = mcArr[m];\r\n let r = item.r, \r\n c = item.c, \r\n start_r = item.start_r, \r\n start_c = item.start_c, \r\n end_r = item.end_r-1, \r\n end_c = item.end_c-1;\r\n let firstcolumnlen = item.firstcolumnlen;\r\n\r\n let cell = Store.flowdata[r][c];\r\n let value = null;\r\n\r\n let margeMaindata = cell[\"mc\"];\r\n\r\n value = getRealCellValue(margeMaindata.r,margeMaindata.c);\r\n\r\n r = margeMaindata.r;\r\n c = margeMaindata.c;\r\n\r\n let mainCell = Store.flowdata[r][c];\r\n\r\n if (c == 0) {\r\n start_c = -scrollWidth;\r\n }\r\n else {\r\n start_c = Store.visibledatacolumn[c - 1] - scrollWidth;\r\n }\r\n\r\n if (r == 0) {\r\n start_r = -scrollHeight - 1;\r\n }\r\n else {\r\n start_r = Store.visibledatarow[r - 1] - scrollHeight - 1;\r\n }\r\n\r\n end_r = Store.visibledatarow[r+mainCell[\"mc\"].rs-1] - scrollHeight;\r\n end_c = Store.visibledatacolumn[c+mainCell[\"mc\"].cs-1] - scrollWidth;\r\n\r\n if(value == null || value.toString().length == 0){\r\n nullCellRender(r, c, start_r, start_c, end_r, end_c,luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05, true);\r\n \r\n //sparklines渲染\r\n let borderfix = menuButton.borderfix(Store.flowdata, r, c);\r\n let cellsize = [\r\n (start_c + offsetLeft + borderfix[0]), \r\n (start_r + offsetTop + borderfix[1]), \r\n (end_c - start_c - 3 + borderfix[2]), \r\n (end_r - start_r - 3 - 1 + borderfix[3])\r\n ];\r\n sparklinesRender(r, c, cellsize[0], cellsize[1], \"luckysheetTableContent\", luckysheetTableContent);\r\n }\r\n else{\r\n if((r + \"_\" + c) in dynamicArray_compute){//动态数组公式\r\n value = dynamicArray_compute[r + \"_\" + c].v;\r\n }\r\n cellRender(r, c, start_r, start_c, end_r, end_c, value, luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05, true);\r\n }\r\n }\r\n\r\n //数据透视表边框渲染\r\n for (let r = dataset_row_st; r <= dataset_row_ed; r++) {\r\n let start_r;\r\n if (r == 0) {\r\n start_r = -scrollHeight - 1;\r\n }\r\n else {\r\n start_r = Store.visibledatarow[r - 1] - scrollHeight - 1;\r\n }\r\n\r\n let end_r = Store.visibledatarow[r] - scrollHeight;\r\n \r\n for (let c = dataset_col_st; c <= dataset_col_ed; c++) {\r\n let start_c;\r\n if (c == 0) {\r\n start_c = -scrollWidth;\r\n }\r\n else {\r\n start_c = Store.visibledatacolumn[c - 1] - scrollWidth;\r\n }\r\n\r\n let end_c = Store.visibledatacolumn[c] - scrollWidth;\r\n\r\n\r\n //数据透视表\r\n if (!!Store.luckysheetcurrentisPivotTable && pivotTable.drawPivotTable) {\r\n if ((c == 0 || c == 5) && r <= 11) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (end_c - 2 + bodrder05 + offsetLeft), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c - 2 + bodrder05 + offsetLeft), \r\n (end_r - 2 + bodrder05 + offsetTop)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = \"#000000\";\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n\r\n if ((r == 2 || r == 11) && c <= 5) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (start_c - 1 + offsetLeft), \r\n (end_r - 2 + bodrder05 + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c - 2 + bodrder05 + offsetLeft), \r\n (end_r - 2 + bodrder05 + offsetTop)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = \"#000000\";\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n\r\n if (r == 6 && c == 3) {\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.font=\"bold 30px Arial\";\r\n luckysheetTableContent.fillStyle = \"#626675\";\r\n luckysheetTableContent.textAlign=\"center\"; \r\n luckysheetTableContent.fillText(\r\n locale().pivotTable.title, \r\n (start_c + (end_c - start_c) / 2 + 4 + offsetLeft), \r\n (start_r + (end_r - start_r) / 2 - 1 + offsetTop)\r\n );\r\n luckysheetTableContent.restore();\r\n }\r\n }\r\n else if (!!Store.luckysheetcurrentisPivotTable) {\r\n if (c < pivotTable.pivotTableBoundary[1] && r < pivotTable.pivotTableBoundary[0]) {\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (end_c - 2 + bodrder05 + offsetLeft), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c - 2 + bodrder05 + offsetLeft), \r\n (end_r - 2 + bodrder05 + offsetTop)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = \"#000000\";\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (start_c - 1 + offsetLeft), \r\n (end_r - 2 + bodrder05 + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c - 2 + offsetLeft), \r\n (end_r - 2 + bodrder05 + offsetTop)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = \"#000000\";\r\n luckysheetTableContent.closePath();\r\n luckysheetTableContent.stroke();\r\n }\r\n }\r\n }\r\n }\r\n\r\n //边框单独渲染\r\n if(Store.config[\"borderInfo\"] != null && Store.config[\"borderInfo\"].length > 0){\r\n //边框渲染\r\n let borderLeftRender = function(style, color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, canvas){\r\n let linetype = style;\r\n\r\n let m_st = (start_c - 2 + bodrder05 + offsetLeft);\r\n let m_ed = (start_r + offsetTop-1);\r\n let line_st = (start_c - 2 + bodrder05 + offsetLeft);\r\n let line_ed = (end_r - 2 + bodrder05 + offsetTop);\r\n canvas.save();\r\n menuButton.setLineDash(canvas, linetype, \"v\", m_st, m_ed, line_st, line_ed);\r\n\r\n canvas.strokeStyle = color;\r\n \r\n canvas.stroke();\r\n canvas.closePath();\r\n canvas.restore();\r\n }\r\n\r\n let borderRightRender = function(style, color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, canvas){\r\n let linetype = style;\r\n\r\n let m_st = (end_c - 2 + bodrder05 + offsetLeft);\r\n let m_ed = (start_r + offsetTop-1);\r\n let line_st = (end_c - 2 + bodrder05 + offsetLeft);\r\n let line_ed = (end_r - 2 + bodrder05 + offsetTop);\r\n canvas.save();\r\n menuButton.setLineDash(canvas, linetype, \"v\", m_st, m_ed, line_st, line_ed);\r\n\r\n canvas.strokeStyle = color;\r\n \r\n canvas.stroke();\r\n canvas.closePath();\r\n canvas.restore();\r\n }\r\n\r\n let borderBottomRender = function(style, color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, canvas){\r\n let linetype = style;\r\n\r\n let m_st = (start_c - 2 + bodrder05 + offsetLeft);\r\n let m_ed = (end_r - 2 + bodrder05 + offsetTop);\r\n let line_st = (end_c - 2 + bodrder05 + offsetLeft);\r\n let line_ed = (end_r - 2 + bodrder05 + offsetTop);\r\n canvas.save();\r\n menuButton.setLineDash(canvas, linetype, \"h\", m_st, m_ed, line_st, line_ed);\r\n\r\n canvas.strokeStyle = color;\r\n \r\n canvas.stroke();\r\n canvas.closePath();\r\n canvas.restore();\r\n }\r\n\r\n let borderTopRender = function(style, color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, canvas){\r\n let linetype = style;\r\n\r\n let m_st = (start_c - 2 + bodrder05 + offsetLeft);\r\n let m_ed = (start_r - 1 + bodrder05 + offsetTop);\r\n let line_st = (end_c - 2 + bodrder05 + offsetLeft);\r\n let line_ed = (start_r - 1 + bodrder05 + offsetTop);\r\n canvas.save();\r\n menuButton.setLineDash(canvas, linetype, \"h\", m_st, m_ed, line_st, line_ed);\r\n\r\n canvas.strokeStyle = color;\r\n \r\n canvas.stroke();\r\n canvas.closePath();\r\n canvas.restore();\r\n }\r\n\r\n let borderInfoCompute = getBorderInfoComputeRange(dataset_row_st,dataset_row_ed,dataset_col_st,dataset_col_ed);\r\n \r\n for(let x in borderInfoCompute){\r\n //let bd_r = x.split(\"_\")[0], bd_c = x.split(\"_\")[1];\r\n\r\n let bd_r = x.substr(0, x.indexOf('_'));\r\n let bd_c = x.substr(x.indexOf('_') + 1);\r\n\r\n // if(bd_r < dataset_row_st || bd_r > dataset_row_ed || bd_c < dataset_col_st || bd_c > dataset_col_ed){\r\n // continue;\r\n // }\r\n\r\n if(borderOffset[bd_r + \"_\" + bd_c]){\r\n let start_r = borderOffset[bd_r + \"_\" + bd_c].start_r;\r\n let start_c = borderOffset[bd_r + \"_\" + bd_c].start_c;\r\n let end_r = borderOffset[bd_r + \"_\" + bd_c].end_r;\r\n let end_c = borderOffset[bd_r + \"_\" + bd_c].end_c;\r\n\r\n let cellOverflow_colInObj = cellOverflow_colIn(cellOverflowMap, bd_r, bd_c, dataset_col_st, dataset_col_ed);\r\n\r\n let borderLeft = borderInfoCompute[x].l;\r\n if(borderLeft != null && (!cellOverflow_colInObj.colIn || cellOverflow_colInObj.stc == bd_c)){\r\n borderLeftRender(borderLeft.style, borderLeft.color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, luckysheetTableContent);\r\n }\r\n\r\n let borderRight = borderInfoCompute[x].r;\r\n if(borderRight != null && (!cellOverflow_colInObj.colIn || cellOverflow_colInObj.colLast)){\r\n borderRightRender(borderRight.style, borderRight.color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, luckysheetTableContent);\r\n }\r\n\r\n let borderTop = borderInfoCompute[x].t;\r\n if(borderTop != null){\r\n borderTopRender(borderTop.style, borderTop.color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, luckysheetTableContent);\r\n }\r\n\r\n let borderBottom = borderInfoCompute[x].b;\r\n if(borderBottom != null){\r\n borderBottomRender(borderBottom.style, borderBottom.color, start_r, start_c, end_r, end_c, offsetLeft, offsetTop, luckysheetTableContent);\r\n }\r\n }\r\n }\r\n }\r\n\r\n //渲染表格时有尾列时,清除右边灰色区域,防止表格有值溢出\r\n if(dataset_col_ed == Store.visibledatacolumn.length - 1){\r\n luckysheetTableContent.clearRect(\r\n (fill_col_ed - scrollWidth + offsetLeft) - 1 , \r\n (offsetTop) - 1 , \r\n (Store.ch_width - Store.visibledatacolumn[dataset_col_ed]) , \r\n (fill_row_ed - scrollHeight)\r\n );\r\n }\r\n\r\n luckysheetTableContent.restore();\r\n\r\n Store.measureTextCacheTimeOut = setTimeout(() => {\r\n Store.measureTextCache = {};\r\n Store.measureTextCellInfoCache = {};\r\n Store.cellOverflowMapCache = {};\r\n }, 100);\r\n\r\n}\r\n\r\n\r\n//sparklines渲染\r\nlet sparklinesRender = function(r, c, offsetX, offsetY, canvasid, ctx){\r\n if(Store.flowdata[r] == null || Store.flowdata[r][c] == null){\r\n return;\r\n }\r\n\r\n let sparklines = Store.flowdata[r][c].spl;\r\n if(sparklines != null){\r\n if(typeof sparklines == \"string\"){\r\n sparklines = new Function(\"return \" + sparklines)();\r\n }\r\n\r\n if(getObjType(sparklines) == \"object\"){\r\n let temp1 = sparklines;\r\n let x = temp1.offsetX;\r\n let y = temp1.offsetY;\r\n x = x == null ? 0 : x;\r\n y = y == null ? 0 : y;\r\n luckysheetSparkline.render(\r\n temp1.shapeseq, \r\n temp1.shapes, \r\n offsetX + x, \r\n offsetY + y, \r\n temp1.pixelWidth, \r\n temp1.pixelHeight, \r\n canvasid, \r\n ctx\r\n );\r\n }\r\n else if(getObjType(sparklines) == \"array\" && getObjType(sparklines[0]) == \"object\"){\r\n for(let i = 0; i < sparklines.length; i++){\r\n let temp1 = sparklines[i];\r\n let x = temp1.offsetX;\r\n let y = temp1.offsetY;\r\n x = x == null ? 0 : x;\r\n y = y == null ? 0 : y;\r\n luckysheetSparkline.render(\r\n temp1.shapeseq, \r\n temp1.shapes, \r\n offsetX + x, \r\n offsetY + y, \r\n temp1.pixelWidth, \r\n temp1.pixelHeight, \r\n canvasid, \r\n ctx\r\n );\r\n }\r\n }\r\n }\r\n}\r\n\r\n//空白单元格渲染 \r\nlet nullCellRender = function(r, c, start_r, start_c, end_r, end_c,luckysheetTableContent,af_compute,cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05,isMerge){\r\n let checksAF = alternateformat.checksAF(r, c, af_compute); //交替颜色\r\n let checksCF = conditionformat.checksCF(r, c, cf_compute); //条件格式\r\n\r\n let borderfix = menuButton.borderfix(Store.flowdata, r, c);\r\n\r\n //背景色\r\n let fillStyle = menuButton.checkstatus(Store.flowdata, r, c , \"bg\");\r\n\r\n if(checksAF != null && checksAF[1] != null){//交替颜色 \r\n fillStyle = checksAF[1];\r\n }\r\n\r\n if(checksCF != null && checksCF[\"cellColor\"] != null){//条件格式 \r\n fillStyle = checksCF[\"cellColor\"];\r\n }\r\n\r\n if(Store.flowdata[r][c] != null && Store.flowdata[r][c].tc != null){//标题色\r\n fillStyle = Store.flowdata[r][c].tc;\r\n }\r\n\r\n if(fillStyle==null){\r\n luckysheetTableContent.fillStyle = \"#FFFFFF\";\r\n }\r\n else{\r\n luckysheetTableContent.fillStyle = fillStyle;\r\n }\r\n \r\n\r\n let cellsize = [\r\n (start_c + offsetLeft + borderfix[0]), \r\n (start_r + offsetTop + borderfix[1]), \r\n (end_c - start_c + borderfix[2]-(!!isMerge?1:0)), \r\n (end_r - start_r + borderfix[3])\r\n ];\r\n\r\n //单元格渲染前,考虑到合并单元格会再次渲染一遍,统一放到这里\r\n if(!method.createHookFunction(\"cellRenderBefore\", Store.flowdata[r][c], {\r\n r:r,\r\n c:c,\r\n \"start_r\": cellsize[1],\r\n \"start_c\":cellsize[0], \r\n \"end_r\": cellsize[3] + cellsize[1], \r\n \"end_c\": cellsize[2] + cellsize[0]\r\n }, sheetmanage.getSheetByIndex(),luckysheetTableContent)){ return; }\r\n\r\n luckysheetTableContent.fillRect(cellsize[0], cellsize[1], cellsize[2], cellsize[3]);\r\n\r\n if((r + \"_\" + c) in dynamicArray_compute){\r\n let value = dynamicArray_compute[r + \"_\" + c].v;\r\n\r\n luckysheetTableContent.fillStyle = \"#000000\";\r\n //文本宽度和高度\r\n let fontset = luckysheetdefaultFont();\r\n luckysheetTableContent.font = fontset;\r\n\r\n //水平对齐 (默认为1,左对齐)\r\n let horizonAlignPos = (start_c + 4 + offsetLeft) ;\r\n\r\n //垂直对齐 (默认为2,下对齐)\r\n let verticalFixed = browser.luckysheetrefreshfixed();\r\n let verticalAlignPos = (end_r + offsetTop - 2) ; \r\n luckysheetTableContent.textBaseline = 'bottom';\r\n \r\n luckysheetTableContent.fillText(value == null ? \"\" : value, horizonAlignPos, verticalAlignPos);\r\n }\r\n\r\n //若单元格有批注\r\n if(Store.flowdata[r][c] != null && Store.flowdata[r][c].ps != null){\r\n let ps_w = 8*Store.zoomRatio, ps_h = 8*Store.zoomRatio; \r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo( (end_c + offsetLeft - 1- ps_w), (start_r + offsetTop));\r\n luckysheetTableContent.lineTo( (end_c + offsetLeft - 1), (start_r + offsetTop));\r\n luckysheetTableContent.lineTo( (end_c + offsetLeft - 1), (start_r + offsetTop + ps_h));\r\n luckysheetTableContent.fillStyle = \"#FC6666\";\r\n luckysheetTableContent.fill();\r\n luckysheetTableContent.closePath();\r\n }\r\n\r\n //此单元格 与 溢出单元格关系\r\n let cellOverflow_colInObj = cellOverflow_colIn(cellOverflowMap, r, c, dataset_col_st, dataset_col_ed);\r\n\r\n //此单元格 为 溢出单元格渲染范围最后一列,绘制溢出单元格内容\r\n if(cellOverflow_colInObj.colLast){\r\n cellOverflowRender(\r\n cellOverflow_colInObj.rowIndex,\r\n cellOverflow_colInObj.colIndex,\r\n cellOverflow_colInObj.stc,\r\n cellOverflow_colInObj.edc,\r\n luckysheetTableContent,\r\n scrollHeight,\r\n scrollWidth,\r\n offsetLeft,offsetTop,af_compute, cf_compute\r\n );\r\n }\r\n\r\n //即溢出单元格跨此单元格,此单元格不绘制右边框\r\n if(!cellOverflow_colInObj.colIn || cellOverflow_colInObj.colLast){\r\n //右边框\r\n if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (end_c + offsetLeft - 2 + bodrder05), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft - 2 + bodrder05), \r\n (end_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n\r\n luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n }\r\n\r\n //下边框\r\n if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (start_c + offsetLeft - 1), \r\n (end_r + offsetTop - 2 + bodrder05)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft - 1), \r\n (end_r + offsetTop - 2 + bodrder05)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n\r\n luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle; \r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n\r\n // 单元格渲染后\r\n method.createHookFunction(\"cellRenderAfter\", Store.flowdata[r][c], {\r\n r:r,\r\n c:c,\r\n \"start_r\": cellsize[1],\r\n \"start_c\":cellsize[0], \r\n \"end_r\": cellsize[3] + cellsize[1], \r\n \"end_c\": cellsize[2] + cellsize[0]\r\n }, sheetmanage.getSheetByIndex(),luckysheetTableContent)\r\n}\r\n\r\n\r\nlet cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05,isMerge){\r\n let cell = Store.flowdata[r][c];\r\n let cellWidth = end_c - start_c - 2;\r\n let cellHeight = end_r - start_r - 2;\r\n let space_width = 2, space_height = 2; //宽高方向 间隙\r\n\r\n //水平对齐\r\n let horizonAlign = menuButton.checkstatus(Store.flowdata, r, c, \"ht\");\r\n //垂直对齐\r\n let verticalAlign = menuButton.checkstatus(Store.flowdata, r, c, \"vt\");\r\n\r\n //交替颜色\r\n let checksAF = alternateformat.checksAF(r, c, af_compute); \r\n //条件格式\r\n let checksCF = conditionformat.checksCF(r, c, cf_compute); \r\n\r\n //单元格 背景颜色\r\n let fillStyle = menuButton.checkstatus(Store.flowdata, r, c, \"bg\");\r\n if(checksAF != null && checksAF[1] != null){ //若单元格有交替颜色 背景颜色\r\n fillStyle = checksAF[1];\r\n }\r\n if(checksCF != null && checksCF[\"cellColor\"] != null){ //若单元格有条件格式 背景颜色\r\n fillStyle = checksCF[\"cellColor\"];\r\n }\r\n // luckysheetTableContent.textBaseline = 'top';\r\n if(fillStyle==null){\r\n luckysheetTableContent.fillStyle = \"#FFFFFF\";\r\n }\r\n else{\r\n luckysheetTableContent.fillStyle = fillStyle;\r\n }\r\n\r\n let borderfix = menuButton.borderfix(Store.flowdata, r, c);\r\n // console.log(value, fillStyle,borderfix);\r\n let cellsize = [\r\n (start_c + offsetLeft + borderfix[0]), \r\n (start_r + offsetTop + borderfix[1]), \r\n (end_c - start_c + borderfix[2]-(!!isMerge?1:0)), \r\n (end_r - start_r + borderfix[3])\r\n ];\r\n\r\n //单元格渲染前,考虑到合并单元格会再次渲染一遍,统一放到这里\r\n if(!method.createHookFunction(\"cellRenderBefore\", Store.flowdata[r][c], {\r\n r:r,\r\n c:c,\r\n \"start_r\": cellsize[1],\r\n \"start_c\":cellsize[0], \r\n \"end_r\": cellsize[3] + cellsize[1], \r\n \"end_c\": cellsize[2] + cellsize[0]\r\n }, sheetmanage.getSheetByIndex(),luckysheetTableContent)){ return; }\r\n\r\n\r\n luckysheetTableContent.fillRect(cellsize[0], cellsize[1], cellsize[2], cellsize[3]);\r\n\r\n let dataVerification = dataVerificationCtrl.dataVerification;\r\n\r\n if(dataVerification != null && dataVerification[r + '_' + c] != null && !dataVerificationCtrl.validateCellData(value, dataVerification[r + '_' + c])){\r\n //单元格左上角红色小三角标示\r\n let dv_w = 5 * Store.zoomRatio, dv_h = 5 * Store.zoomRatio; //红色小三角宽高\r\n\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (start_c + offsetLeft), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (start_c + offsetLeft + dv_w), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (start_c + offsetLeft), \r\n (start_r + offsetTop + dv_h)\r\n );\r\n luckysheetTableContent.fillStyle = \"#FC6666\";\r\n luckysheetTableContent.fill();\r\n luckysheetTableContent.closePath();\r\n }\r\n\r\n //若单元格有批注(单元格右上角红色小三角标示)\r\n if(cell.ps != null){\r\n let ps_w = 8*Store.zoomRatio, ps_h = 8*Store.zoomRatio; //红色小三角宽高\r\n\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (end_c + offsetLeft - ps_w), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft), \r\n (start_r + offsetTop + ps_h)\r\n );\r\n luckysheetTableContent.fillStyle = \"#FC6666\";\r\n luckysheetTableContent.fill();\r\n luckysheetTableContent.closePath();\r\n }\r\n\r\n //若单元格强制为字符串,则显示绿色小三角\r\n if(cell.qp==1 && isRealNum(cell.v)){\r\n let ps_w = 6*Store.zoomRatio, ps_h = 6*Store.zoomRatio; //红色小三角宽高\r\n\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (start_c + offsetLeft + ps_w-1), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (start_c + offsetLeft-1), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (start_c + offsetLeft-1), \r\n (start_r + offsetTop + ps_h)\r\n );\r\n luckysheetTableContent.fillStyle = \"#487f1e\";\r\n luckysheetTableContent.fill();\r\n luckysheetTableContent.closePath();\r\n }\r\n\r\n //溢出单元格\r\n let cellOverflow_bd_r_render = true; //溢出单元格右边框是否需要绘制\r\n let cellOverflow_colInObj = cellOverflow_colIn(cellOverflowMap, r, c, dataset_col_st, dataset_col_ed);\r\n\r\n if(cell.tb == '1' && cellOverflow_colInObj.colIn){\r\n //此单元格 为 溢出单元格渲染范围最后一列,绘制溢出单元格内容\r\n if(cellOverflow_colInObj.colLast){\r\n cellOverflowRender(\r\n cellOverflow_colInObj.rowIndex,\r\n cellOverflow_colInObj.colIndex,\r\n cellOverflow_colInObj.stc,\r\n cellOverflow_colInObj.edc,\r\n luckysheetTableContent,\r\n scrollHeight,\r\n scrollWidth,offsetLeft,offsetTop,af_compute, cf_compute\r\n );\r\n }\r\n else{\r\n cellOverflow_bd_r_render = false;\r\n }\r\n }\r\n //数据验证 复选框\r\n else if(dataVerification != null && dataVerification[r + '_' + c] != null && dataVerification[r + '_' + c].type == 'checkbox'){\r\n let pos_x = start_c + offsetLeft;\r\n let pos_y = start_r + offsetTop + 1;\r\n\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.rect(pos_x, pos_y, cellWidth, cellHeight);\r\n luckysheetTableContent.clip();\r\n luckysheetTableContent.scale(Store.zoomRatio,Store.zoomRatio);\r\n \r\n let measureText = getMeasureText(value, luckysheetTableContent);\r\n let textMetrics = measureText.width + 14;\r\n let oneLineTextHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;\r\n\r\n let horizonAlignPos = (pos_x + space_width) ; //默认为1,左对齐\r\n if(horizonAlign == \"0\"){ //居中对齐\r\n horizonAlignPos = (pos_x + cellWidth / 2) - (textMetrics / 2);\r\n }\r\n else if(horizonAlign == \"2\"){ //右对齐\r\n horizonAlignPos = (pos_x + cellWidth - space_width) - textMetrics;\r\n }\r\n \r\n let verticalCellHeight = cellHeight > oneLineTextHeight ? cellHeight : oneLineTextHeight;\r\n\r\n let verticalAlignPos_text = (pos_y + verticalCellHeight - space_height) ; //文本垂直方向基准线\r\n luckysheetTableContent.textBaseline = \"bottom\";\r\n let verticalAlignPos_checkbox = verticalAlignPos_text - 13 * Store.zoomRatio;\r\n\r\n if(verticalAlign == \"0\"){ //居中对齐 \r\n verticalAlignPos_text = (pos_y + verticalCellHeight / 2);\r\n luckysheetTableContent.textBaseline = \"middle\";\r\n verticalAlignPos_checkbox = verticalAlignPos_text - 6 * Store.zoomRatio;\r\n }\r\n else if(verticalAlign == \"1\"){ //上对齐\r\n verticalAlignPos_text = (pos_y + space_height);\r\n luckysheetTableContent.textBaseline = \"top\";\r\n verticalAlignPos_checkbox = verticalAlignPos_text + 1 * Store.zoomRatio;\r\n }\r\n\r\n horizonAlignPos = horizonAlignPos / Store.zoomRatio;\r\n verticalAlignPos_text = verticalAlignPos_text / Store.zoomRatio;\r\n verticalAlignPos_checkbox = verticalAlignPos_checkbox / Store.zoomRatio;\r\n\r\n //复选框\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = \"#000\";\r\n luckysheetTableContent.strokeRect(horizonAlignPos, verticalAlignPos_checkbox, 10, 10);\r\n\r\n if(dataVerification[r + '_' + c].checked){\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.lineTo(\r\n horizonAlignPos + 1, \r\n verticalAlignPos_checkbox + 6\r\n );\r\n luckysheetTableContent.lineTo(\r\n horizonAlignPos + 4, \r\n verticalAlignPos_checkbox + 9\r\n );\r\n luckysheetTableContent.lineTo(\r\n horizonAlignPos + 9, \r\n verticalAlignPos_checkbox + 2\r\n );\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n\r\n //文本\r\n luckysheetTableContent.fillStyle = menuButton.checkstatus(Store.flowdata, r, c , \"fc\");\r\n luckysheetTableContent.fillText(value == null ? \"\" : value, horizonAlignPos + 14, verticalAlignPos_text);\r\n \r\n luckysheetTableContent.restore();\r\n }\r\n else{\r\n //若单元格有条件格式数据条\r\n if(checksCF != null && checksCF[\"dataBar\"] != null){\r\n let x = (start_c + offsetLeft + space_width);\r\n let y = (start_r + offsetTop + space_height);\r\n let w = (cellWidth - space_width * 2);\r\n let h = (cellHeight - space_height * 2);\r\n\r\n let valueType = checksCF[\"dataBar\"][\"valueType\"];\r\n let valueLen = checksCF[\"dataBar\"][\"valueLen\"];\r\n let format = checksCF[\"dataBar\"][\"format\"];\r\n\r\n if(valueType == 'minus'){\r\n //负数\r\n let minusLen = checksCF[\"dataBar\"][\"minusLen\"];\r\n \r\n if(format.length > 1){\r\n //渐变\r\n let my_gradient = luckysheetTableContent.createLinearGradient(\r\n x + w * minusLen * (1 - valueLen), \r\n y, \r\n x + w * minusLen, \r\n y\r\n );\r\n my_gradient.addColorStop(0, \"#ffffff\");\r\n my_gradient.addColorStop(1, \"#ff0000\");\r\n\r\n luckysheetTableContent.fillStyle = my_gradient;\r\n }\r\n else{\r\n //单色\r\n luckysheetTableContent.fillStyle = \"#ff0000\";\r\n }\r\n \r\n luckysheetTableContent.fillRect(\r\n x + w * minusLen * (1 - valueLen), \r\n y, \r\n w * minusLen * valueLen, \r\n h\r\n );\r\n\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n x + w * minusLen * (1 - valueLen), \r\n y\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen * (1 - valueLen), \r\n y + h\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen, \r\n y + h\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen, \r\n y\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen * (1 - valueLen), \r\n y\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = \"#ff0000\";\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n else if(valueType == 'plus'){\r\n //正数\r\n let plusLen = checksCF[\"dataBar\"][\"plusLen\"];\r\n\r\n if(plusLen == 1){\r\n if(format.length > 1){\r\n //渐变\r\n let my_gradient = luckysheetTableContent.createLinearGradient(\r\n x, \r\n y, \r\n x + w * valueLen, \r\n y\r\n );\r\n my_gradient.addColorStop(0, format[0]);\r\n my_gradient.addColorStop(1, format[1]);\r\n \r\n luckysheetTableContent.fillStyle = my_gradient;\r\n }\r\n else{\r\n //单色\r\n luckysheetTableContent.fillStyle = format[0];\r\n }\r\n \r\n luckysheetTableContent.fillRect(\r\n x, \r\n y, \r\n w * valueLen, \r\n h\r\n );\r\n\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n x, \r\n y\r\n );\r\n luckysheetTableContent.lineTo(\r\n x, \r\n y + h\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * valueLen, \r\n y + h\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * valueLen, \r\n y\r\n );\r\n luckysheetTableContent.lineTo(\r\n x, \r\n y\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = format[0];\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n else{\r\n let minusLen = checksCF[\"dataBar\"][\"minusLen\"];\r\n\r\n if(format.length > 1){\r\n //渐变\r\n let my_gradient = luckysheetTableContent.createLinearGradient(\r\n x + w * minusLen, \r\n y, \r\n x + w * minusLen + w * plusLen * valueLen, \r\n y\r\n );\r\n my_gradient.addColorStop(0, format[0]);\r\n my_gradient.addColorStop(1, format[1]);\r\n \r\n luckysheetTableContent.fillStyle = my_gradient;\r\n }\r\n else{\r\n //单色\r\n luckysheetTableContent.fillStyle = format[0];\r\n }\r\n \r\n luckysheetTableContent.fillRect(\r\n x + w * minusLen, \r\n y, \r\n w * plusLen * valueLen, \r\n h\r\n );\r\n\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n x + w * minusLen, \r\n y\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen, \r\n y + h\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen + w * plusLen * valueLen, \r\n y + h\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen + w * plusLen * valueLen, \r\n y\r\n );\r\n luckysheetTableContent.lineTo(\r\n x + w * minusLen, \r\n y\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = format[0];\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n }\r\n }\r\n\r\n let pos_x = start_c + offsetLeft;\r\n let pos_y = start_r + offsetTop + 1;\r\n\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.rect(pos_x , pos_y, cellWidth , cellHeight );\r\n luckysheetTableContent.clip();\r\n luckysheetTableContent.scale(Store.zoomRatio,Store.zoomRatio);\r\n\r\n\r\n let textInfo = getCellTextInfo(cell , luckysheetTableContent, {\r\n cellWidth:cellWidth,\r\n cellHeight:cellHeight,\r\n space_width:space_width,\r\n space_height:space_height,\r\n r:r,\r\n c:c\r\n });\r\n\r\n //若单元格有条件格式图标集\r\n if(checksCF != null && checksCF[\"icons\"] != null && textInfo.type==\"plain\"){\r\n let l = checksCF[\"icons\"][\"left\"];\r\n let t = checksCF[\"icons\"][\"top\"];\r\n \r\n let value = textInfo.values[0]\r\n let horizonAlignPos = pos_x + value.left;\r\n let verticalAlignPos = pos_y + value.top- textInfo.textHeightAll;\r\n\r\n if(verticalAlign == \"0\"){ //居中对齐 \r\n verticalAlignPos = pos_y + cellHeight/2 - textInfo.textHeightAll/2;\r\n }\r\n else if(verticalAlign == \"1\"){ //上对齐\r\n verticalAlignPos = pos_y;\r\n }\r\n else if(verticalAlign == \"2\"){ //下对齐\r\n verticalAlignPos =verticalAlignPos - textInfo.desc;\r\n }\r\n\r\n verticalAlignPos = verticalAlignPos/Store.zoomRatio;\r\n horizonAlignPos = horizonAlignPos/Store.zoomRatio;\r\n\r\n luckysheetTableContent.drawImage(\r\n luckysheet_CFiconsImg, \r\n l * 42, \r\n t * 32, \r\n 32, \r\n 32, \r\n pos_x/Store.zoomRatio , \r\n verticalAlignPos, \r\n textInfo.textHeightAll/Store.zoomRatio, \r\n textInfo.textHeightAll/Store.zoomRatio\r\n );\r\n \r\n if(horizonAlign != \"0\" && horizonAlign != \"2\"){ //左对齐时 文本渲染空出一个图标的距离\r\n horizonAlignPos = horizonAlignPos + textInfo.textHeightAll/Store.zoomRatio;\r\n }\r\n }\r\n\r\n //单元格 文本颜色\r\n luckysheetTableContent.fillStyle = menuButton.checkstatus(Store.flowdata, r, c , \"fc\");\r\n \r\n //若单元格有交替颜色 文本颜色\r\n if(checksAF != null && checksAF[0] != null){ \r\n luckysheetTableContent.fillStyle = checksAF[0];\r\n }\r\n //若单元格有条件格式 文本颜色\r\n if(checksCF != null && checksCF[\"textColor\"] != null){ \r\n luckysheetTableContent.fillStyle = checksCF[\"textColor\"];\r\n }\r\n\r\n //若单元格格式为自定义数字格式([red]) 文本颜色为红色\r\n if(cell.ct && cell.ct.fa && cell.ct.fa.indexOf('[Red]') > -1 && cell.ct.t == 'n' && cell.v < 0){\r\n luckysheetTableContent.fillStyle = '#ff0000';\r\n }\r\n\r\n cellTextRender(\r\n textInfo,\r\n luckysheetTableContent,\r\n {\r\n pos_x:pos_x,\r\n pos_y:pos_y,\r\n }\r\n );\r\n\r\n\r\n luckysheetTableContent.restore();\r\n }\r\n\r\n if(cellOverflow_bd_r_render){\r\n //右边框\r\n if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (end_c + offsetLeft - 2 + bodrder05), \r\n (start_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft - 2 + bodrder05), \r\n (end_r + offsetTop)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n }\r\n\r\n //下边框\r\n if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.moveTo(\r\n (start_c + offsetLeft - 1), \r\n (end_r + offsetTop - 2 + bodrder05)\r\n );\r\n luckysheetTableContent.lineTo(\r\n (end_c + offsetLeft - 1), \r\n (end_r + offsetTop - 2 + bodrder05)\r\n );\r\n luckysheetTableContent.lineWidth = 1;\r\n luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n luckysheetTableContent.stroke();\r\n luckysheetTableContent.closePath();\r\n }\r\n\r\n // 单元格渲染后\r\n method.createHookFunction(\"cellRenderAfter\", Store.flowdata[r][c], {\r\n r:r,\r\n c:c,\r\n \"start_r\": cellsize[1],\r\n \"start_c\":cellsize[0], \r\n \"end_r\": cellsize[3] + cellsize[1], \r\n \"end_c\": cellsize[2] + cellsize[0]\r\n }, sheetmanage.getSheetByIndex(),luckysheetTableContent)\r\n}\r\n\r\n//溢出单元格渲染\r\nlet cellOverflowRender = function(r, c, stc, edc,luckysheetTableContent,scrollHeight,scrollWidth,offsetLeft,offsetTop,af_compute, cf_compute){\r\n //溢出单元格 起止行列坐标\r\n let start_r;\r\n if (r == 0) {\r\n start_r = -scrollHeight - 1;\r\n }\r\n else {\r\n start_r = Store.visibledatarow[r - 1] - scrollHeight - 1;\r\n }\r\n\r\n let end_r = Store.visibledatarow[r] - scrollHeight;\r\n\r\n let start_c;\r\n if (stc == 0) {\r\n start_c = -scrollWidth;\r\n }\r\n else {\r\n start_c = Store.visibledatacolumn[stc - 1] - scrollWidth;\r\n }\r\n\r\n let end_c = Store.visibledatacolumn[edc] - scrollWidth;\r\n\r\n //\r\n let cell = Store.flowdata[r][c];\r\n let cellWidth = end_c - start_c - 2;\r\n let cellHeight = end_r - start_r - 2;\r\n let space_width = 2, space_height = 2; //宽高方向 间隙\r\n\r\n let pos_x = start_c + offsetLeft;\r\n let pos_y = start_r + offsetTop + 1;\r\n\r\n let fontset = luckysheetfontformat(cell);\r\n luckysheetTableContent.font = fontset;\r\n\r\n luckysheetTableContent.save();\r\n luckysheetTableContent.beginPath();\r\n luckysheetTableContent.rect(pos_x , pos_y, cellWidth , cellHeight );\r\n luckysheetTableContent.clip();\r\n luckysheetTableContent.scale(Store.zoomRatio,Store.zoomRatio);\r\n \r\n\r\n let textInfo = getCellTextInfo(cell , luckysheetTableContent, {\r\n cellWidth:cellWidth,\r\n cellHeight:cellHeight,\r\n space_width:space_width,\r\n space_height:space_height,\r\n r:r,\r\n c:c\r\n });\r\n\r\n //交替颜色\r\n let checksAF = alternateformat.checksAF(r, c, af_compute); \r\n //条件格式\r\n let checksCF = conditionformat.checksCF(r, c, cf_compute); \r\n\r\n //单元格 文本颜色\r\n luckysheetTableContent.fillStyle = menuButton.checkstatus(Store.flowdata, r, c , \"fc\");\r\n \r\n //若单元格有交替颜色 文本颜色\r\n if(checksAF != null && checksAF[0] != null){ \r\n luckysheetTableContent.fillStyle = checksAF[0];\r\n }\r\n //若单元格有条件格式 文本颜色\r\n if(checksCF != null && checksCF[\"textColor\"] != null){ \r\n luckysheetTableContent.fillStyle = checksCF[\"textColor\"];\r\n }\r\n\r\n cellTextRender(\r\n textInfo,\r\n luckysheetTableContent,\r\n {\r\n pos_x:pos_x,\r\n pos_y:pos_y,\r\n }\r\n );\r\n\r\n luckysheetTableContent.restore();\r\n\r\n}\r\n\r\n//获取表格渲染范围 溢出单元格 \r\nfunction getCellOverflowMap(canvas, col_st, col_ed, row_st, row_end){\r\n let map = {};\r\n\r\n let data = Store.flowdata;\r\n\r\n for(let r = row_st; r <= row_end; r++){\r\n if(data[r]==null){\r\n continue;\r\n }\r\n\r\n if(Store.cellOverflowMapCache[r]!=null){\r\n map[r] = Store.cellOverflowMapCache[r];\r\n continue;\r\n }\r\n\r\n let hasCellOver = false;\r\n\r\n for(let c = 0; c < data[r].length; c++){\r\n let cell = data[r][c];\r\n\r\n // if(Store.cellOverflowMapCache[r + '_' + c]!=null){\r\n // map[r + '_' + c] = Store.cellOverflowMapCache[r + '_' + c];\r\n // continue;\r\n // }\r\n\r\n if (Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][c] != null) {\r\n continue\r\n }\r\n\r\n if(cell != null && (!isRealNull(cell.v) || isInlineStringCell(cell) ) && cell.mc == null && cell.tb == '1'){\r\n\r\n //水平对齐\r\n let horizonAlign = menuButton.checkstatus(data, r, c, \"ht\");\r\n\r\n \r\n let textMetricsObj = getCellTextInfo(cell, canvas,{\r\n r:r,\r\n c:c,\r\n });\r\n let textMetrics = 0;\r\n if(textMetricsObj!=null){\r\n textMetrics = textMetricsObj.textWidthAll;\r\n }\r\n\r\n //canvas.measureText(value).width;\r\n\r\n let start_c = c - 1 < 0 ? 0 : Store.visibledatacolumn[c - 1];\r\n let end_c = Store.visibledatacolumn[c];\r\n\r\n let stc, edc;\r\n\r\n if((end_c - start_c) < textMetrics){\r\n if(horizonAlign == '0'){//居中对齐\r\n let trace_forward = cellOverflow_trace(r, c, c - 1, 'forward', horizonAlign, textMetrics);\r\n let trace_backward = cellOverflow_trace(r, c, c + 1, 'backward', horizonAlign, textMetrics);\r\n \r\n if(trace_forward.success){\r\n stc = trace_forward.c;\r\n }\r\n else{\r\n stc = trace_forward.c + 1;\r\n }\r\n\r\n if(trace_backward.success){\r\n edc = trace_backward.c;\r\n }\r\n else{\r\n edc = trace_backward.c - 1;\r\n }\r\n }\r\n else if(horizonAlign == '1'){//左对齐\r\n let trace = cellOverflow_trace(r, c, c + 1, 'backward', horizonAlign, textMetrics);\r\n stc = c;\r\n\r\n if(trace.success){\r\n edc = trace.c;\r\n }\r\n else{\r\n edc = trace.c - 1;\r\n }\r\n }\r\n else if(horizonAlign == '2'){//右对齐\r\n let trace = cellOverflow_trace(r, c, c - 1, 'forward', horizonAlign, textMetrics);\r\n edc = c;\r\n\r\n if(trace.success){\r\n stc = trace.c;\r\n }\r\n else{\r\n stc = trace.c + 1;\r\n }\r\n }\r\n }\r\n else{\r\n stc = c;\r\n edc = c;\r\n }\r\n\r\n // if(((stc >= col_st && stc <= col_ed) || (edc >= col_st && edc <= col_ed)) && stc < edc){\r\n if(((stc <= col_ed) || (edc >= col_st)) && stc < edc){\r\n let item = {\r\n r: r,\r\n stc: stc,\r\n edc: edc \r\n }\r\n\r\n if(map[r]==null){\r\n map[r] = {};\r\n }\r\n\r\n map[r][c] = item;\r\n\r\n // Store.cellOverflowMapCache[r + '_' + c] = item;\r\n\r\n hasCellOver = true;\r\n }\r\n }\r\n }\r\n\r\n if(hasCellOver){\r\n Store.cellOverflowMapCache[r] = map[r];\r\n }\r\n\r\n }\r\n\r\n return map;\r\n}\r\n\r\nfunction cellOverflow_trace(r, curC, traceC, traceDir, horizonAlign, textMetrics){\r\n let data = Store.flowdata; \r\n\r\n //追溯单元格列超出数组范围 则追溯终止\r\n if(traceDir == 'forward' && traceC < 0){\r\n return {\r\n success: false,\r\n r: r,\r\n c: traceC\r\n }; \r\n }\r\n \r\n if(traceDir == 'backward' && traceC > data[r].length - 1){\r\n return {\r\n success: false,\r\n r: r,\r\n c: traceC\r\n };\r\n }\r\n\r\n //追溯单元格是 非空单元格或合并单元格 则追溯终止\r\n let cell = data[r][traceC];\r\n if(cell != null && (!isRealNull(cell.v) || cell.mc != null)){\r\n return {\r\n success: false,\r\n r: r,\r\n c: traceC\r\n };\r\n }\r\n\r\n let start_curC = curC - 1 < 0 ? 0 : Store.visibledatacolumn[curC - 1];\r\n let end_curC = Store.visibledatacolumn[curC];\r\n\r\n let w = textMetrics - (end_curC - start_curC);\r\n\r\n if(horizonAlign == '0'){//居中对齐\r\n start_curC -= w / 2;\r\n end_curC += w / 2;\r\n }\r\n else if(horizonAlign == '1'){//左对齐\r\n end_curC += w;\r\n }\r\n else if(horizonAlign == '2'){//右对齐\r\n start_curC -= w;\r\n }\r\n\r\n let start_traceC = traceC - 1 < 0 ? 0 : Store.visibledatacolumn[traceC - 1];\r\n let end_traceC = Store.visibledatacolumn[traceC];\r\n\r\n if(traceDir == 'forward'){\r\n if(start_curC < start_traceC){\r\n return cellOverflow_trace(r, curC, traceC - 1, traceDir, horizonAlign, textMetrics);\r\n }\r\n else if(start_curC < end_traceC){\r\n return {\r\n success: true,\r\n r: r,\r\n c: traceC\r\n }\r\n }\r\n else{\r\n return {\r\n success: false,\r\n r: r,\r\n c: traceC\r\n }\r\n }\r\n }\r\n \r\n if(traceDir == 'backward'){\r\n if(end_curC > end_traceC){\r\n return cellOverflow_trace(r, curC, traceC + 1, traceDir, horizonAlign, textMetrics);\r\n }\r\n else if(end_curC > start_traceC){\r\n return {\r\n success: true,\r\n r: r,\r\n c: traceC\r\n }\r\n }\r\n else{\r\n return {\r\n success: false,\r\n r: r,\r\n c: traceC\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction cellOverflow_colIn(map, r, c, col_st, col_ed){\r\n let colIn = false, //此单元格 是否在 某个溢出单元格的渲染范围\r\n colLast = false, //此单元格 是否是 某个溢出单元格的渲染范围的最后一列\r\n rowIndex, //溢出单元格 行下标 \r\n colIndex, //溢出单元格 列下标\r\n stc,\r\n edc;\r\n\r\n for(let rkey in map){\r\n for(let ckey in map[rkey]){\r\n rowIndex = rkey;\r\n colIndex = ckey;\r\n // rowIndex = key.substr(0, key.indexOf('_'));\r\n // colIndex = key.substr(key.indexOf('_') + 1);\r\n let mapItem = map[rkey][ckey];\r\n stc = mapItem.stc;\r\n edc = mapItem.edc;\r\n\r\n if(rowIndex == r){\r\n if(c >= stc && c <= edc){\r\n colIn = true;\r\n\r\n if(c == edc || c == col_ed){\r\n colLast = true;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(colLast){\r\n break;\r\n }\r\n }\r\n\r\n return {\r\n colIn: colIn,\r\n colLast: colLast,\r\n rowIndex: rowIndex,\r\n colIndex: colIndex,\r\n stc: stc,\r\n edc: edc\r\n }\r\n}\r\n\r\nfunction cellTextRender(textInfo, ctx, option){\r\n if(textInfo==null){\r\n return\r\n }\r\n let values = textInfo.values;\r\n let pos_x = option.pos_x, pos_y = option.pos_y;\r\n if(values==null){\r\n return;\r\n }\r\n // console.log(textInfo, pos_x, pos_y, values[0].width, values[0].left, ctx);\r\n\r\n // for(let i=0;i {\r\n sheetListOption += ``;\r\n })\r\n\r\n let content = `
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
`;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-insertLink-dialog\", \r\n \"addclass\": \"luckysheet-insertLink-dialog\", \r\n \"title\": toolbarText.insertLink, \r\n \"content\": content, \r\n \"botton\": `\r\n `, \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-insertLink-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 350).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), \r\n winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), \r\n scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-insertLink-dialog\").css({ \r\n \"left\": (winw + scrollLeft - myw) / 2, \r\n \"top\": (winh + scrollTop - myh) / 3 \r\n }).show();\r\n\r\n _this.dataAllocation();\r\n },\r\n init: function (){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const hyperlinkText = _locale.insertLink;\r\n\r\n //链接类型\r\n $(document).off(\"change.linkType\").on(\"change.linkType\", \"#luckysheet-insertLink-dialog-linkType\", function(e){\r\n let value = this.value;\r\n\r\n $(\"#luckysheet-insertLink-dialog .show-box\").hide();\r\n $(\"#luckysheet-insertLink-dialog .show-box-\" + value).show();\r\n })\r\n\r\n //确认按钮\r\n $(document).off(\"click.confirm\").on(\"click.confirm\", \"#luckysheet-insertLink-dialog-confirm\", function(e){\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rowIndex = last.row_focus || last.row[0];\r\n let colIndex = last.column_focus || last.column[0];\r\n\r\n //文本\r\n let linkText = $(\"#luckysheet-insertLink-dialog-linkText\").val();\r\n\r\n let linkType = $(\"#luckysheet-insertLink-dialog-linkType\").val();\r\n let linkAddress = $(\"#luckysheet-insertLink-dialog-linkAddress\").val();\r\n let linkSheet = $(\"#luckysheet-insertLink-dialog-linkSheet\").val();\r\n let linkCell = $(\"#luckysheet-insertLink-dialog-linkCell\").val();\r\n let linkTooltip = $(\"#luckysheet-insertLink-dialog-linkTooltip\").val();\r\n\r\n if(linkType == 'external'){\r\n if(!/^http[s]?:\\/\\//.test(linkAddress)){\r\n linkAddress = 'https://' + linkAddress;\r\n }\r\n\r\n if(!/^http[s]?:\\/\\/([\\w\\-\\.]+)+[\\w-]*([\\w\\-\\.\\/\\?%&=]+)?$/ig.test(linkAddress)){\r\n tooltip.info('', hyperlinkText.tooltipInfo1);\r\n return;\r\n }\r\n }\r\n else{\r\n if(!formula.iscelldata(linkCell)){\r\n tooltip.info('', hyperlinkText.tooltipInfo2);\r\n return;\r\n }\r\n\r\n linkAddress = linkSheet + \"!\" + linkCell;\r\n }\r\n\r\n if(linkText == null || linkText.replace(/\\s/g, '') == ''){\r\n linkText = linkAddress;\r\n }\r\n\r\n let item = {\r\n linkType: linkType,\r\n linkAddress: linkAddress,\r\n linkTooltip: linkTooltip,\r\n }\r\n\r\n let historyHyperlink = $.extend(true, {}, _this.hyperlink);\r\n let currentHyperlink = $.extend(true, {}, _this.hyperlink);\r\n\r\n currentHyperlink[rowIndex + \"_\" + colIndex] = item;\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let cell = d[rowIndex][colIndex];\r\n\r\n if(cell == null){\r\n cell = {};\r\n }\r\n\r\n cell.fc = 'rgb(0, 0, 255)';\r\n cell.un = 1;\r\n cell.v = linkText;\r\n\r\n d[rowIndex][colIndex] = cell;\r\n\r\n _this.ref(\r\n historyHyperlink, \r\n currentHyperlink, \r\n Store.currentSheetIndex, \r\n d, \r\n { row: [rowIndex, rowIndex], column: [colIndex, colIndex] }\r\n );\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-insertLink-dialog\").hide();\r\n })\r\n },\r\n dataAllocation: function(){\r\n let _this = this;\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rowIndex = last.row_focus || last.row[0];\r\n let colIndex = last.column_focus || last.column[0];\r\n\r\n let hyperlink = _this.hyperlink || {};\r\n let item = hyperlink[rowIndex + \"_\" + colIndex] || {};\r\n\r\n //文本\r\n let text = getcellvalue(rowIndex, colIndex, null, 'm');\r\n $(\"#luckysheet-insertLink-dialog-linkText\").val(text);\r\n\r\n //链接类型\r\n let linkType = item.linkType || 'external';\r\n $(\"#luckysheet-insertLink-dialog-linkType\").val(linkType);\r\n\r\n $(\"#luckysheet-insertLink-dialog .show-box\").hide();\r\n $(\"#luckysheet-insertLink-dialog .show-box-\" + linkType).show();\r\n\r\n //链接地址\r\n let linkAddress = item.linkAddress || '';\r\n\r\n if(linkType == 'external'){\r\n $(\"#luckysheet-insertLink-dialog-linkAddress\").val(linkAddress);\r\n }\r\n else{\r\n if(formula.iscelldata(linkAddress)){\r\n let sheettxt = linkAddress.split(\"!\")[0];\r\n let rangetxt = linkAddress.split(\"!\")[1];\r\n\r\n $(\"#luckysheet-insertLink-dialog-linkSheet\").val(sheettxt);\r\n $(\"#luckysheet-insertLink-dialog-linkCell\").val(rangetxt);\r\n }\r\n }\r\n\r\n //提示\r\n let linkTooltip = item.linkTooltip || '';\r\n $(\"#luckysheet-insertLink-dialog-linkTooltip\").val(linkTooltip);\r\n },\r\n cellFocus: function(r, c){\r\n let _this = this;\r\n\r\n if(_this.hyperlink == null || _this.hyperlink[r + '_' + c] == null){\r\n return;\r\n }\r\n\r\n let item = _this.hyperlink[r + '_' + c];\r\n\r\n if(item.linkType == 'external'){\r\n window.open(item.linkAddress);\r\n }\r\n else{\r\n let cellrange = formula.getcellrange(item.linkAddress);\r\n let sheetIndex = cellrange.sheetIndex;\r\n let range = [{\r\n row: cellrange.row,\r\n column: cellrange.column\r\n }];\r\n\r\n if(sheetIndex != Store.currentSheetIndex){\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-sheets-item\" + sheetIndex).addClass(\"luckysheet-sheets-item-active\");\r\n\r\n sheetmanage.changeSheet(sheetIndex);\r\n }\r\n\r\n Store.luckysheet_select_save = range;\r\n selectHightlightShow(true);\r\n\r\n let row_pre = cellrange.row[0] - 1 == -1 ? 0 : Store.visibledatarow[cellrange.row[0] - 1];\r\n let col_pre = cellrange.column[0] - 1 == -1 ? 0 : Store.visibledatacolumn[cellrange.column[0] - 1];\r\n\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col_pre);\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row_pre);\r\n }\r\n },\r\n overshow: function(event){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-hyperlink-overshow\").remove();\r\n\r\n if($(event.target).closest(\"#luckysheet-cell-main\").length == 0){\r\n return;\r\n }\r\n\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let x = mouse[0] + scrollLeft;\r\n let y = mouse[1] + scrollTop;\r\n\r\n if(luckysheetFreezen.freezenverticaldata != null && mouse[0] < (luckysheetFreezen.freezenverticaldata[0] - luckysheetFreezen.freezenverticaldata[2])){\r\n return;\r\n }\r\n\r\n if(luckysheetFreezen.freezenhorizontaldata != null && mouse[1] < (luckysheetFreezen.freezenhorizontaldata[0] - luckysheetFreezen.freezenhorizontaldata[2])){\r\n return;\r\n }\r\n\r\n let row_index = rowLocation(y)[2];\r\n let col_index = colLocation(x)[2];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, row_index, col_index);\r\n if(!!margeset){\r\n row_index = margeset.row[2];\r\n col_index = margeset.column[2];\r\n }\r\n\r\n if(_this.hyperlink == null || _this.hyperlink[row_index + \"_\" + col_index] == null){\r\n return;\r\n }\r\n\r\n let item = _this.hyperlink[row_index + \"_\" + col_index];\r\n let linkTooltip = item.linkTooltip;\r\n\r\n if(linkTooltip == null || linkTooltip.replace(/\\s/g, '') == ''){\r\n linkTooltip = item.linkAddress;\r\n }\r\n\r\n let row = Store.visibledatarow[row_index], \r\n row_pre = row_index - 1 == -1 ? 0 : Store.visibledatarow[row_index - 1];\r\n let col = Store.visibledatacolumn[col_index], \r\n col_pre = col_index - 1 == -1 ? 0 : Store.visibledatacolumn[col_index - 1];\r\n\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n \r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n let html = ``;\r\n\r\n $(html).appendTo($(\"#luckysheet-cell-main\"));\r\n },\r\n ref: function(historyHyperlink, currentHyperlink, sheetIndex, d, range){\r\n let _this = this;\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let redo = {};\r\n redo[\"type\"] = \"updateHyperlink\";\r\n redo[\"sheetIndex\"] = sheetIndex;\r\n redo[\"historyHyperlink\"] = historyHyperlink;\r\n redo[\"currentHyperlink\"] = currentHyperlink;\r\n redo[\"data\"] = Store.flowdata; \r\n redo[\"curData\"] = d;\r\n redo[\"range\"] = range; \r\n Store.jfredo.push(redo); \r\n }\r\n\r\n _this.hyperlink = currentHyperlink;\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)].hyperlink = currentHyperlink;\r\n\r\n Store.flowdata = d;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)].data = Store.flowdata;\r\n\r\n //共享编辑模式\r\n if(server.allowUpdate){ \r\n server.saveParam(\"all\", sheetIndex, currentHyperlink, { \"k\": \"hyperlink\" });\r\n server.historyParam(Store.flowdata, sheetIndex, range);\r\n }\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n}\r\n\r\nexport default hyperlinkCtrl;","import rhchInit from './rhchInit';\r\nimport formula from './formula';\r\nimport editor from './editor';\r\nimport { setcellvalue } from './setdata';\r\nimport { getcellFormula } from './getdata';\r\nimport { computeRowlenArr } from './getRowlen';\r\nimport { \r\n luckysheetDrawMain, \r\n luckysheetDrawgridRowTitle, \r\n luckysheetDrawgridColumnTitle \r\n} from './draw';\r\nimport luckysheetFreezen from '../controllers/freezen';\r\nimport server from '../controllers/server';\r\nimport sheetmanage from '../controllers/sheetmanage';\r\nimport luckysheetPostil from '../controllers/postil';\r\nimport dataVerificationCtrl from '../controllers/dataVerificationCtrl';\r\nimport hyperlinkCtrl from '../controllers/hyperlinkCtrl';\r\nimport { selectHightlightShow, selectionCopyShow, collaborativeEditBox } from '../controllers/select';\r\nimport { createFilterOptions } from '../controllers/filter';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport Store from '../store';\r\n\r\nlet refreshCanvasTimeOut = null;\r\n\r\nfunction runExecFunction(range, index, data){\r\n formula.execFunctionExist = [];\r\n for(let s = 0; s < range.length; s++){\r\n for(let r = range[s].row[0]; r <= range[s].row[1]; r++){\r\n for(let c = range[s].column[0]; c <= range[s].column[1]; c++){\r\n formula.execFunctionExist.push({ \"r\": r, \"c\": c, \"i\": index });\r\n }\r\n }\r\n }\r\n formula.execFunctionExist.reverse();\r\n formula.execFunctionGroup(null, null, null, null, data);\r\n formula.execFunctionGlobalData = null;\r\n}\r\n\r\nfunction jfrefreshgrid(data, range, allParam, isRunExecFunction = true, isRefreshCanvas = true) {\r\n if(data == null){\r\n data = Store.flowdata;\r\n }\r\n\r\n if(range == null){\r\n range = Store.luckysheet_select_save;\r\n }\r\n\r\n clearTimeout(refreshCanvasTimeOut);\r\n\r\n\r\n\r\n //关联参数\r\n if(allParam == null){\r\n allParam = {};\r\n }\r\n\r\n let cfg = allParam[\"cfg\"]; //config\r\n let RowlChange = allParam[\"RowlChange\"]; //行高改变\r\n let cdformat = allParam[\"cdformat\"]; //条件格式\r\n let dataVerification = allParam[\"dataVerification\"]; //数据验证\r\n let dynamicArray = allParam[\"dynamicArray\"]; //动态数组\r\n\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let curConfig;\r\n if(cfg == null){\r\n curConfig = $.extend(true, {}, Store.config);\r\n }\r\n else{\r\n curConfig = $.extend(true, {}, cfg);\r\n }\r\n\r\n let curCdformat;\r\n if(cdformat == null){\r\n curCdformat = $.extend(true, [], file[\"luckysheet_conditionformat_save\"]);\r\n }\r\n else{\r\n curCdformat = cdformat;\r\n }\r\n\r\n let curDataVerification;\r\n if(dataVerification == null){\r\n curDataVerification = $.extend(true, {}, file[\"dataVerification\"])\r\n }\r\n else{\r\n curDataVerification = dataVerification;\r\n }\r\n\r\n let curDynamicArray;\r\n if(dynamicArray == null){\r\n curDynamicArray = $.extend(true, [], file[\"dynamicArray\"]);\r\n }\r\n else{\r\n curDynamicArray = dynamicArray;\r\n }\r\n \r\n Store.jfredo.push({ \r\n \"type\": \"datachange\", \r\n \"data\": Store.flowdata, \r\n \"curdata\": data, \r\n \"sheetIndex\": Store.currentSheetIndex, \r\n \"range\": range, \r\n \"config\": $.extend(true, {}, Store.config), \r\n \"curConfig\": curConfig,\r\n \"cdformat\": $.extend(true, [], file[\"luckysheet_conditionformat_save\"]),\r\n \"curCdformat\": curCdformat,\r\n \"RowlChange\": RowlChange,\r\n \"dataVerification\": $.extend(true, [], file[\"dataVerification\"]),\r\n \"curDataVerification\": curDataVerification,\r\n \"dynamicArray\": $.extend(true, [], file[\"dynamicArray\"]),\r\n \"curDynamicArray\": curDynamicArray,\r\n \"dataRange\": [...file.luckysheet_select_save]\r\n });\r\n }\r\n\r\n //Store.flowdata\r\n Store.flowdata = data;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n file.data = Store.flowdata;\r\n\r\n //config\r\n if(cfg != null){\r\n Store.config = cfg;\r\n file.config = Store.config;\r\n\r\n server.saveParam(\"all\", Store.currentSheetIndex, cfg, { \"k\": \"config\" });\r\n\r\n if(RowlChange != null){\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n }\r\n\r\n //条件格式\r\n if(cdformat != null){\r\n file[\"luckysheet_conditionformat_save\"] = cdformat;\r\n\r\n server.saveParam(\"all\", Store.currentSheetIndex, cdformat, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n\r\n //数据验证\r\n if(dataVerification != null){\r\n dataVerificationCtrl.dataVerification = dataVerification;\r\n file[\"dataVerification\"] = dataVerification;\r\n server.saveParam(\"all\", Store.currentSheetIndex, dataVerification, { \"k\": \"dataVerification\" });\r\n }\r\n\r\n //动态数组\r\n if(dynamicArray != null){\r\n file[\"dynamicArray\"] = dynamicArray;\r\n\r\n server.saveParam(\"all\", Store.currentSheetIndex, dynamicArray, { \"k\": \"dynamicArray\" });\r\n }\r\n\r\n //更新数据的范围\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0];\r\n let c1 = range[s].column[0];\r\n\r\n if(Store.flowdata[r1][c1] != null && Store.flowdata[r1][c1].spl != null){\r\n window.luckysheetCurrentRow = r1;\r\n window.luckysheetCurrentColumn = c1;\r\n window.luckysheetCurrentFunction = Store.flowdata[r1][c1].f;\r\n\r\n let fp = $.trim(formula.functionParserExe(Store.flowdata[r1][c1].f));\r\n let sparklines = new Function(\"return \" +fp)();\r\n Store.flowdata[r1][c1].spl = sparklines;\r\n }\r\n\r\n if(server.allowUpdate){ //共享编辑模式\r\n server.historyParam(Store.flowdata, Store.currentSheetIndex, range[s]);\r\n }\r\n // 刷新图表\r\n if(typeof(Store.chartparam.jfrefreshchartall)==\"function\"){\r\n Store.chartparam.jfrefreshchartall(Store.flowdata,range[s].row[0],range[s].row[1],range[s].column[0],range[s].column[1]);\r\n }\r\n }\r\n //单元格数据更新联动\r\n if (isRunExecFunction) {\r\n runExecFunction(range, Store.currentSheetIndex, data);\r\n }\r\n //刷新表格\r\n if(isRefreshCanvas){\r\n refreshCanvasTimeOut = setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n\r\n window.luckysheet_getcelldata_cache = null;\r\n}\r\n\r\nfunction jfrefreshgridall(colwidth, rowheight, data, cfg, range, ctrlType, ctrlValue, cdformat, isRefreshCanvas=true) {\r\n let redo = {}, isRunExecFunction=false;\r\n clearTimeout(refreshCanvasTimeOut);\r\n if (ctrlType == \"cellRowChange\") {\r\n redo[\"type\"] = \"cellRowChange\";\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = $.extend(true, {}, cfg);\r\n\r\n redo[\"range\"] = $.extend(true, [], Store.luckysheet_select_save);\r\n redo[\"currange\"] = range;\r\n\r\n redo[\"ctrlType\"] = ctrlType;\r\n redo[\"ctrlValue\"] = ctrlValue;\r\n\r\n let setfield = cfg[\"rowlen\"];\r\n\r\n if(setfield == null){\r\n setfield = {};\r\n }\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, setfield, { \"k\": \"rowlen\" });\r\n }\r\n else if (ctrlType == \"resizeC\") {\r\n redo[\"type\"] = \"resize\";\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = $.extend(true, {}, cfg);\r\n\r\n redo[\"range\"] = $.extend(true, [], Store.luckysheet_select_save);\r\n redo[\"currange\"] = range;\r\n\r\n redo[\"ctrlType\"] = ctrlType;\r\n redo[\"ctrlValue\"] = ctrlValue;\r\n\r\n let setfield = cfg[\"columnlen\"];\r\n\r\n if(setfield == null){\r\n setfield = {};\r\n }\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, setfield, { \"k\": \"columnlen\" });\r\n }\r\n else if (ctrlType.indexOf(\"extend\")>-1) {\r\n redo[\"type\"] = \"extend\";\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = $.extend(true, {}, cfg);\r\n\r\n redo[\"range\"] = $.extend(true, [], Store.luckysheet_select_save);\r\n redo[\"currange\"] = range;\r\n\r\n redo[\"ctrlType\"] = ctrlType;\r\n redo[\"ctrlValue\"] = ctrlValue;\r\n\r\n server.saveParam(\"arc\", Store.currentSheetIndex, {\"index\": ctrlValue.index, \"len\": ctrlValue.len, \"direction\": ctrlValue.direction, \"mc\": cfg.merge }, { \"rc\": ctrlValue.type });\r\n }\r\n else if (ctrlType.indexOf(\"dele\")>-1) {\r\n redo[\"type\"] = \"dele\";\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = $.extend(true, {}, cfg);\r\n\r\n redo[\"range\"] = $.extend(true, [], Store.luckysheet_select_save);\r\n redo[\"currange\"] = range;\r\n\r\n redo[\"ctrlType\"] = ctrlType;\r\n redo[\"ctrlValue\"] = ctrlValue;\r\n\r\n server.saveParam(\"drc\", Store.currentSheetIndex, {\"index\": ctrlValue.index, \"len\":ctrlValue.len, \"mc\": cfg.merge, \"borderInfo\": cfg.borderInfo }, { \"rc\": ctrlValue.type});\r\n }\r\n else {\r\n redo[\"type\"] = \"datachangeAll\";\r\n\r\n redo[\"range\"] = $.extend(true, [], Store.luckysheet_select_save);\r\n redo[\"currange\"] = range;\r\n\r\n redo[\"ctrlType\"] = ctrlType;\r\n redo[\"ctrlValue\"] = ctrlValue;\r\n\r\n isRunExecFunction = true;\r\n\r\n for(let s = 0; s < range.length; s++){\r\n server.historyParam(data, Store.currentSheetIndex, range[s]); \r\n }\r\n }\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n redo[\"data\"] = Store.flowdata;\r\n redo[\"curdata\"] = data;\r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n redo[\"cdformat\"] = $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"]);\r\n redo[\"curCdformat\"] = cdformat;\r\n\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n //Store.flowdata\r\n Store.flowdata = data;\r\n editor.webWorkerFlowDataCache(data);//worker存数据\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = Store.flowdata;\r\n\r\n //config\r\n if (cfg != null) {\r\n Store.config = cfg;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n server.saveParam(\"all\", Store.currentSheetIndex, cfg, { \"k\": \"config\" });\r\n }\r\n\r\n //条件格式\r\n if(cdformat != null){\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] = cdformat;\r\n \r\n server.saveParam(\"all\", Store.currentSheetIndex, cdformat, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n\r\n //选区\r\n Store.luckysheet_select_save = $.extend(true, [], range);\r\n if(Store.luckysheet_select_save.length > 0){\r\n //有选区时,刷新一下选区\r\n selectHightlightShow();\r\n }\r\n\r\n\r\n if(isRunExecFunction){\r\n //单元格数据更新联动\r\n runExecFunction(range, Store.currentSheetIndex, data);\r\n }\r\n\r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(rowheight, colwidth);\r\n\r\n if(isRefreshCanvas){\r\n refreshCanvasTimeOut = setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n \r\n\r\n sheetmanage.storeSheetParamALL();\r\n \r\n window.luckysheet_getcelldata_cache = null;\r\n}\r\n\r\nfunction jfrefreshrange(data, range, cdformat) {\r\n clearTimeout(refreshCanvasTimeOut);\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n Store.jfredo.push({ \r\n \"type\": \"rangechange\", \r\n \"data\": Store.flowdata, \r\n \"curdata\": data, \r\n \"range\": range, \r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"cdformat\": $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"]),\r\n \"curCdformat\": cdformat \r\n });\r\n }\r\n\r\n //flowdata\r\n Store.flowdata = data;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = Store.flowdata;\r\n\r\n //条件格式\r\n if(cdformat != null){\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] = cdformat;\r\n }\r\n\r\n //单元格数据更新联动\r\n runExecFunction(range, Store.currentSheetIndex, data);\r\n\r\n //刷新表格\r\n refreshCanvasTimeOut = setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n\r\n //发送给后台\r\n for(let s = 0; s < range.length; s++){\r\n server.historyParam(Store.flowdata, Store.currentSheetIndex, range[s]);\r\n }\r\n}\r\n\r\n//删除、增加行列 刷新表格\r\nfunction jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf, af, freezen, dataVerification, hyperlink){\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n collaborativeEditBox();\r\n //merge改变对应的单元格值改变\r\n let mcData = [];\r\n for(let m in cfg[\"merge\"]){\r\n let mc = cfg[\"merge\"][m];\r\n\r\n for(let r = mc.r; r <= mc.r + mc.rs - 1; r++){\r\n for(let c = mc.c; c <= mc.c + mc.cs - 1; c++){\r\n if(data[r][c] == null){\r\n data[r][c] = {};\r\n }\r\n\r\n if(r == mc.r && c == mc.c){\r\n data[r][c].mc = mc;\r\n }\r\n else{\r\n data[r][c].mc = { \"r\": mc.r, \"c\": mc.c };\r\n }\r\n\r\n mcData.push({ \"r\": r, \"c\": c }); \r\n }\r\n }\r\n }\r\n\r\n //公式链中公式范围改变对应单元格值的改变\r\n let funcData = [];\r\n // if(calc.length > 0){\r\n // // 取消execFunctionGroupData,改用execFunctionGlobalData\r\n // // formula.execFunctionGroupData = data;\r\n\r\n // for(let i = 0; i < calc.length; i++){\r\n // let clc = calc[i];\r\n // let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = getcellFormula(clc_r, clc_c, clc_i, data);\r\n \r\n // let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, clc_i,null, true);\r\n // clc.func = clc_result;\r\n\r\n // if(data[clc_r][clc_c].f == clc_funcStr){\r\n // setcellvalue(clc_r, clc_c, data, clc_result[1]);\r\n // // funcData存储当前结果没有用处,每次还是需要从calc公式链实时从当前数据中计算比较靠谱\r\n // // funcData.push({ \"r\": clc_r, \"c\": clc_c });\r\n // }\r\n // }\r\n // }\r\n\r\n if(Store.clearjfundo){\r\n Store.jfundo.length = 0;\r\n\r\n Store.jfredo.push({\r\n \"type\": ctrlType,\r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"data\": Store.flowdata,\r\n \"curData\": data,\r\n \"config\": $.extend(true, {}, Store.config),\r\n \"curConfig\": cfg,\r\n \"ctrlValue\": ctrlValue,\r\n \"mcData\": mcData,\r\n \"calc\": $.extend(true, [], file.calcChain),\r\n \"curCalc\": calc,\r\n \"funcData\": funcData,\r\n \"filterObj\": { \"filter_select\": $.extend(true, {}, file.filter_select), \"filter\": $.extend(true, {}, file.filter) },\r\n \"curFilterObj\": filterObj,\r\n \"cf\": $.extend(true, [], file.luckysheet_conditionformat_save),\r\n \"curCf\": cf,\r\n \"af\": $.extend(true, [], file.luckysheet_alternateformat_save),\r\n \"curAf\": af,\r\n \"freezen\": { \"freezenhorizontaldata\": luckysheetFreezen.freezenhorizontaldata, \"freezenverticaldata\": luckysheetFreezen.freezenverticaldata },\r\n \"curFreezen\": freezen,\r\n \"dataVerification\": $.extend(true, {}, file.dataVerification),\r\n \"curDataVerification\": dataVerification,\r\n \"hyperlink\": $.extend(true, {}, file.hyperlink),\r\n \"curHyperlink\": hyperlink,\r\n \"dataRange\": [...file.luckysheet_select_save]\r\n });\r\n }\r\n\r\n let index = ctrlValue.index,\r\n len = ctrlValue.len,\r\n rc = ctrlValue.rc;\r\n\r\n if(ctrlType == \"addRC\"){\r\n let direction = ctrlValue.direction,\r\n restore = ctrlValue.restore;\r\n\r\n let addData = [];\r\n if(restore){\r\n if(rc == \"r\"){\r\n let st_r;\r\n if(direction == \"lefttop\"){\r\n st_r = index;\r\n }\r\n else if(direction == \"rightbottom\"){\r\n st_r = index + 1;\r\n }\r\n let ed_r = st_r + len - 1;\r\n\r\n for(let r = st_r; r <= ed_r; r++){\r\n let row = [];\r\n for(let c = 0; c < data[0].length; c++){\r\n let cell = data[r][c];\r\n row.push(cell);\r\n }\r\n addData.push(row);\r\n }\r\n }\r\n else if(rc == \"c\"){\r\n let st_c;\r\n if(direction == \"lefttop\"){\r\n st_c = index;\r\n }\r\n else if(direction == \"rightbottom\"){\r\n st_c = index + 1;\r\n }\r\n let ed_c = st_c + len - 1;\r\n\r\n for(let r = 0; r < data.length; r++){\r\n let row = [];\r\n for(let c = st_c; c <= ed_c; c++){\r\n let cell = data[r][c];\r\n row.push(cell);\r\n }\r\n addData.push(row);\r\n }\r\n }\r\n }\r\n\r\n server.saveParam(\"arc\", Store.currentSheetIndex, {\"index\": index, \"len\": len, \"direction\": direction, \"data\": addData }, { \"rc\": rc });\r\n }\r\n else if(ctrlType == \"delRC\"){\r\n server.saveParam(\"drc\", Store.currentSheetIndex, {\"index\": index, \"len\": len }, { \"rc\": rc });\r\n }\r\n\r\n //Store.flowdata\r\n Store.flowdata = data;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n file.data = data;\r\n\r\n //config\r\n Store.config = cfg;\r\n file.config = Store.config;\r\n server.saveParam(\"all\", Store.currentSheetIndex, cfg, { \"k\": \"config\" });\r\n\r\n //mcData\r\n for(let i = 0; i < mcData.length; i++){\r\n let mcData_r = mcData[i].r,\r\n mcData_c = mcData[i].c;\r\n\r\n server.saveParam(\"v\", Store.currentSheetIndex, Store.flowdata[mcData_r][mcData_c], { \"r\": mcData_r, \"c\": mcData_c });\r\n }\r\n\r\n //公式链中公式范围改变对应单元格值的改变\r\n if(calc.length > 0){\r\n // 取消execFunctionGroupData,改用execFunctionGlobalData\r\n // formula.execFunctionGroupData = data;\r\n\r\n for(let i = 0; i < calc.length; i++){\r\n let clc = calc[i];\r\n let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = getcellFormula(clc_r, clc_c, clc_i, data);\r\n \r\n let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, clc_i,null, true);\r\n clc.func = clc_result;\r\n\r\n if(data[clc_r][clc_c].f == clc_funcStr){\r\n setcellvalue(clc_r, clc_c, data, clc_result[1]);\r\n // funcData存储当前结果没有用处,每次还是需要从calc公式链实时从当前数据中计算比较靠谱\r\n // funcData.push({ \"r\": clc_r, \"c\": clc_c });\r\n }\r\n }\r\n }\r\n\r\n //calc函数链\r\n file.calcChain = calc;\r\n server.saveParam(\"all\", Store.currentSheetIndex, calc, { \"k\": \"calcChain\" });\r\n for(let i = 0; i < funcData.length; i++){\r\n let funcData_r = funcData[i].r,\r\n funcData_c = funcData[i].c;\r\n\r\n server.saveParam(\"v\", Store.currentSheetIndex, Store.flowdata[funcData_r][funcData_c], { \"r\": funcData_r, \"c\": funcData_c });\r\n }\r\n\r\n //筛选配置\r\n if(filterObj != null){\r\n file.filter_select = filterObj.filter_select;\r\n file.filter = filterObj.filter;\r\n }\r\n else{\r\n file.filter_select = null;\r\n file.filter = null;\r\n }\r\n createFilterOptions(file.filter_select, file.filter);\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.filter_select, { \"k\": \"filter_select\" });\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.filter, { \"k\": \"filter\" });\r\n\r\n //条件格式配置\r\n file.luckysheet_conditionformat_save = cf;\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.luckysheet_conditionformat_save, { \"k\": \"luckysheet_conditionformat_save\" });\r\n\r\n //交替颜色配置\r\n file.luckysheet_alternateformat_save = af;\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.luckysheet_alternateformat_save, { \"k\": \"luckysheet_alternateformat_save\" });\r\n\r\n //冻结配置\r\n if(freezen != null){\r\n luckysheetFreezen.freezenhorizontaldata = freezen.freezenhorizontaldata;\r\n luckysheetFreezen.freezenverticaldata = freezen.freezenverticaldata;\r\n }\r\n else{\r\n luckysheetFreezen.freezenhorizontaldata = null;\r\n luckysheetFreezen.freezenverticaldata = null;\r\n }\r\n\r\n //数据验证\r\n dataVerificationCtrl.dataVerification = dataVerification;\r\n file.dataVerification = dataVerification;\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.dataVerification, { \"k\": \"dataVerification\" });\r\n\r\n //超链接\r\n hyperlinkCtrl.hyperlink = hyperlink;\r\n file.hyperlink = hyperlink;\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.hyperlink, { \"k\": \"hyperlink\" });\r\n\r\n //行高、列宽刷新\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n}\r\n\r\n//删除单元格 刷新表格\r\nfunction jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf, dataVerification, hyperlink){\r\n let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n clearTimeout(refreshCanvasTimeOut);\r\n collaborativeEditBox();\r\n //merge改变对应的单元格值改变\r\n let mcData = [];\r\n if(JSON.stringify(cfg[\"merge\"]) == \"{}\"){\r\n for(let r = 0; r < data.length; r++){\r\n for(let c = 0; c < data[0].length; c++){\r\n let cell = data[r][c];\r\n \r\n if(cell != null && cell.mc != null){\r\n delete cell.mc;\r\n mcData.push({ \"r\": r, \"c\": c });\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n for(let m in cfg[\"merge\"]){\r\n let mc = cfg[\"merge\"][m];\r\n \r\n for(let r = mc.r; r <= mc.r + mc.rs - 1; r++){\r\n for(let c = mc.c; c <= mc.c + mc.cs - 1; c++){\r\n if(data[r][c] == null){\r\n data[r][c] = {};\r\n }\r\n \r\n if(r == mc.r && c == mc.c){\r\n data[r][c].mc = mc;\r\n }\r\n else{\r\n data[r][c].mc = { \"r\": mc.r, \"c\": mc.c };\r\n }\r\n \r\n mcData.push({ \"r\": r, \"c\": c }); \r\n }\r\n }\r\n }\r\n }\r\n\r\n //公式链中公式范围改变对应单元格值的改变\r\n let funcData = [];\r\n // if(calc.length > 0){\r\n // // formula.execFunctionGroupData = data;\r\n\r\n // for(let i = 0; i < calc.length; i++){\r\n // let clc = calc[i];\r\n // let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = getcellFormula(clc_r, clc_c, clc_i, data);\r\n // let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, clc_i,null, true);\r\n // clc.func = clc_result;\r\n\r\n // if(data[clc_r][clc_c].f == clc_funcStr){\r\n // setcellvalue(clc_r, clc_c, data, clc_result[1]);\r\n // funcData.push({ \"r\": clc_r, \"c\": clc_c });\r\n // }\r\n // }\r\n // }\r\n\r\n if(Store.clearjfundo){\r\n Store.jfundo.length = 0;\r\n\r\n Store.jfredo.push({\r\n \"type\": \"deleteCell\",\r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"ctrl\": ctrl,\r\n \"data\": Store.flowdata,\r\n \"curData\": data,\r\n \"config\": $.extend(true, {}, Store.config),\r\n \"curConfig\": cfg,\r\n \"mcData\": mcData,\r\n \"calc\": $.extend(true, [], file.calcChain),\r\n \"curCalc\": calc,\r\n \"funcData\": funcData,\r\n \"filterObj\": { \"filter_select\": $.extend(true, {}, file.filter_select), \"filter\": $.extend(true, {}, file.filter) },\r\n \"curFilterObj\": filterObj,\r\n \"cf\": $.extend(true, [], file.luckysheet_conditionformat_save),\r\n \"curCf\": cf,\r\n \"dataVerification\": $.extend(true, {}, file.dataVerification),\r\n \"curDataVerification\": dataVerification,\r\n \"hyperlink\": $.extend(true, {}, file.hyperlink),\r\n \"curHyperlink\": hyperlink,\r\n \"dataRange\": [...file.luckysheet_select_save]\r\n });\r\n }\r\n\r\n //Store.flowdata\r\n Store.flowdata = data;\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n file.data = data;\r\n\r\n //共享编辑模式\r\n if(server.allowUpdate){\r\n let type = ctrl.type,\r\n str = ctrl.str,\r\n edr = ctrl.edr,\r\n stc = ctrl.stc,\r\n edc = ctrl.edc;\r\n\r\n let range;\r\n if(type == 'moveUp'){\r\n range = {\r\n \"row\": [str, data.length - 1],\r\n \"column\": [stc, edc]\r\n }\r\n }\r\n else if(type == 'moveLeft'){\r\n range = {\r\n \"row\": [str, edr],\r\n \"column\": [stc, data[0].length - 1]\r\n };\r\n }\r\n\r\n server.historyParam(Store.flowdata, Store.currentSheetIndex, range);\r\n }\r\n\r\n //config\r\n Store.config = cfg;\r\n file.config = Store.config;\r\n server.saveParam(\"all\", Store.currentSheetIndex, cfg, { \"k\": \"config\" });\r\n\r\n //mcData\r\n for(let i = 0; i < mcData.length; i++){\r\n let mcData_r = mcData[i].r,\r\n mcData_c = mcData[i].c;\r\n\r\n server.saveParam(\"v\", Store.currentSheetIndex, Store.flowdata[mcData_r][mcData_c], { \"r\": mcData_r, \"c\": mcData_c });\r\n }\r\n\r\n //公式链中公式范围改变对应单元格值的改变\r\n if(calc.length > 0){\r\n // formula.execFunctionGroupData = data;\r\n\r\n for(let i = 0; i < calc.length; i++){\r\n let clc = calc[i];\r\n let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = getcellFormula(clc_r, clc_c, clc_i, data);\r\n let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, clc_i,null, true);\r\n clc.func = clc_result;\r\n\r\n if(data[clc_r][clc_c].f == clc_funcStr){\r\n setcellvalue(clc_r, clc_c, data, clc_result[1]);\r\n // funcData.push({ \"r\": clc_r, \"c\": clc_c });\r\n }\r\n }\r\n }\r\n\r\n //calc函数链\r\n file.calcChain = calc;\r\n server.saveParam(\"all\", Store.currentSheetIndex, calc, { \"k\": \"calcChain\" });\r\n for(let i = 0; i < funcData.length; i++){\r\n let funcData_r = funcData[i].r,\r\n funcData_c = funcData[i].c;\r\n\r\n server.saveParam(\"v\", Store.currentSheetIndex, Store.flowdata[funcData_r][funcData_c], { \"r\": funcData_r, \"c\": funcData_c });\r\n }\r\n\r\n //筛选配置\r\n if(filterObj != null){\r\n file.filter_select = filterObj.filter_select;\r\n file.filter = filterObj.filter;\r\n }\r\n else{\r\n file.filter_select = null;\r\n file.filter = null;\r\n }\r\n createFilterOptions(file.filter_select, file.filter);\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.filter_select, { \"k\": \"filter_select\" });\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.filter, { \"k\": \"filter\" });\r\n\r\n //条件格式配置\r\n file.luckysheet_conditionformat_save = cf;\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.luckysheet_conditionformat_save, { \"k\": \"luckysheet_conditionformat_save\" });\r\n\r\n //数据验证\r\n dataVerificationCtrl.dataVerification = dataVerification;\r\n file.dataVerification = dataVerification;\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.dataVerification, { \"k\": \"dataVerification\" });\r\n\r\n //超链接\r\n hyperlinkCtrl.hyperlink = hyperlink;\r\n file.hyperlink = hyperlink;\r\n server.saveParam(\"all\", Store.currentSheetIndex, file.hyperlink, { \"k\": \"hyperlink\" });\r\n\r\n refreshCanvasTimeOut = setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n}\r\n\r\n//复制剪切 刷新表格\r\nfunction jfrefreshgrid_pastcut(source, target, RowlChange){\r\n //单元格数据更新联动\r\n let execF_rc = {};\r\n formula.execFunctionExist = [];\r\n clearTimeout(refreshCanvasTimeOut);\r\n for(let r = source[\"range\"].row[0]; r <= source[\"range\"].row[1]; r++){\r\n for(let c = source[\"range\"].column[0]; c <= source[\"range\"].column[1]; c++){\r\n if((r + \"_\" + c + \"_\" + source[\"sheetIndex\"]) in execF_rc){\r\n continue;\r\n }\r\n\r\n execF_rc[r + \"_\" + c + \"_\" + source[\"sheetIndex\"]] = 0;\r\n formula.execFunctionExist.push({ \"r\": r, \"c\": c, \"i\": source[\"sheetIndex\"] });\r\n }\r\n }\r\n\r\n for(let r = target[\"range\"].row[0]; r <= target[\"range\"].row[1]; r++){\r\n for(let c = target[\"range\"].column[0]; c <= target[\"range\"].column[1]; c++){\r\n if((r + \"_\" + c + \"_\" + target[\"sheetIndex\"]) in execF_rc){\r\n continue;\r\n }\r\n\r\n execF_rc[r + \"_\" + c + \"_\" + target[\"sheetIndex\"]] = 0;\r\n formula.execFunctionExist.push({ \"r\": r, \"c\": c, \"i\": target[\"sheetIndex\"] });\r\n }\r\n }\r\n\r\n\r\n\r\n if(Store.clearjfundo){\r\n Store.jfundo.length = 0;\r\n\r\n Store.jfredo.push({\r\n \"type\": \"pasteCut\",\r\n \"source\": source,\r\n \"target\": target,\r\n \"RowlChange\": RowlChange\r\n })\r\n }\r\n\r\n //config\r\n let rowHeight;\r\n if(Store.currentSheetIndex == source[\"sheetIndex\"]){\r\n Store.config = source[\"curConfig\"];\r\n rowHeight = source[\"curData\"].length;\r\n Store.luckysheetfile[getSheetIndex(target[\"sheetIndex\"])][\"config\"] = target[\"curConfig\"];\r\n }\r\n else if(Store.currentSheetIndex == target[\"sheetIndex\"]){\r\n Store.config = target[\"curConfig\"];\r\n rowHeight = target[\"curData\"].length;\r\n Store.luckysheetfile[getSheetIndex(source[\"sheetIndex\"])][\"config\"] = source[\"curConfig\"];\r\n }\r\n\r\n if(RowlChange){\r\n Store.visibledatarow = [];\r\n Store.rh_height = 0;\r\n \r\n for (let i = 0; i < rowHeight; i++) {\r\n let rowlen = Store.defaultrowlen;\r\n \r\n if (Store.config[\"rowlen\"] != null && Store.config[\"rowlen\"][i] != null) {\r\n rowlen = Store.config[\"rowlen\"][i];\r\n }\r\n\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][i] != null) {\r\n rowlen = Store.config[\"rowhidden\"][i];\r\n Store.visibledatarow.push(Store.rh_height);\r\n continue;\r\n }\r\n else {\r\n Store.rh_height += rowlen + 1;\r\n }\r\n\r\n Store.visibledatarow.push(Store.rh_height);//行的临时长度分布\r\n }\r\n Store.rh_height += 110;\r\n // sheetmanage.showSheet();\r\n\r\n if(Store.currentSheetIndex == source[\"sheetIndex\"]){\r\n let rowlenArr = computeRowlenArr(target[\"curData\"].length, target[\"curConfig\"]);\r\n Store.luckysheetfile[getSheetIndex(target[\"sheetIndex\"])][\"visibledatarow\"] = rowlenArr;\r\n }\r\n else if(Store.currentSheetIndex == target[\"sheetIndex\"]){\r\n let rowlenArr = computeRowlenArr(source[\"curData\"].length, source[\"curConfig\"]);\r\n Store.luckysheetfile[getSheetIndex(source[\"sheetIndex\"])][\"visibledatarow\"] = rowlenArr;\r\n }\r\n }\r\n\r\n //Store.flowdata\r\n if(Store.currentSheetIndex == source[\"sheetIndex\"]){\r\n Store.flowdata = source[\"curData\"];\r\n Store.luckysheetfile[getSheetIndex(target[\"sheetIndex\"])][\"data\"] = target[\"curData\"];\r\n }\r\n else if(Store.currentSheetIndex == target[\"sheetIndex\"]){\r\n Store.flowdata = target[\"curData\"];\r\n Store.luckysheetfile[getSheetIndex(source[\"sheetIndex\"])][\"data\"] = source[\"curData\"];\r\n }\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = Store.flowdata;\r\n \r\n //luckysheet_select_save\r\n if(Store.currentSheetIndex == target[\"sheetIndex\"]){\r\n Store.luckysheet_select_save = [{\"row\": target[\"range\"].row, \"column\": target[\"range\"].column}];\r\n }\r\n else{\r\n Store.luckysheet_select_save = [{\"row\": source[\"range\"].row, \"column\": source[\"range\"].column}];\r\n }\r\n if(Store.luckysheet_select_save.length > 0){\r\n //有选区时,刷新一下选区\r\n selectHightlightShow();\r\n }\r\n\r\n //条件格式\r\n Store.luckysheetfile[getSheetIndex(source[\"sheetIndex\"])].luckysheet_conditionformat_save = source[\"curCdformat\"];\r\n Store.luckysheetfile[getSheetIndex(target[\"sheetIndex\"])].luckysheet_conditionformat_save = target[\"curCdformat\"];\r\n\r\n //数据验证\r\n if(Store.currentSheetIndex == source[\"sheetIndex\"]){\r\n dataVerificationCtrl.dataVerification = source[\"curDataVerification\"];\r\n }\r\n else if(Store.currentSheetIndex == target[\"sheetIndex\"]){\r\n dataVerificationCtrl.dataVerification = target[\"curDataVerification\"]\r\n }\r\n Store.luckysheetfile[getSheetIndex(source[\"sheetIndex\"])].dataVerification = source[\"curDataVerification\"];\r\n Store.luckysheetfile[getSheetIndex(target[\"sheetIndex\"])].dataVerification = target[\"curDataVerification\"];\r\n \r\n \r\n formula.execFunctionExist.reverse();\r\n formula.execFunctionGroup(null, null, null, null, target[\"curData\"]);\r\n formula.execFunctionGlobalData = null;\r\n\r\n refreshCanvasTimeOut = setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n\r\n sheetmanage.storeSheetParamALL();\r\n\r\n //saveparam\r\n //来源表\r\n server.saveParam(\"all\", source[\"sheetIndex\"], source[\"curConfig\"], { \"k\": \"config\" });\r\n //目的表\r\n server.saveParam(\"all\", target[\"sheetIndex\"], target[\"curConfig\"], { \"k\": \"config\" });\r\n \r\n //来源表\r\n server.historyParam(source[\"curData\"], source[\"sheetIndex\"], {\"row\": source[\"range\"][\"row\"], \"column\": source[\"range\"][\"column\"]});\r\n //目的表\r\n server.historyParam(target[\"curData\"], target[\"sheetIndex\"], {\"row\": target[\"range\"][\"row\"], \"column\": target[\"range\"][\"column\"]});\r\n\r\n //来源表\r\n server.saveParam(\"all\", source[\"sheetIndex\"], source[\"curCdformat\"], { \"k\": \"luckysheet_conditionformat_save\" });\r\n //目的表\r\n server.saveParam(\"all\", target[\"sheetIndex\"], target[\"curCdformat\"], { \"k\": \"luckysheet_conditionformat_save\" });\r\n\r\n //来源表\r\n server.saveParam(\"all\", source[\"sheetIndex\"], source[\"curDataVerification\"], { \"k\": \"dataVerification\" });\r\n //目的表\r\n server.saveParam(\"all\", target[\"sheetIndex\"], target[\"curDataVerification\"], { \"k\": \"dataVerification\" });\r\n}\r\n\r\n//行高、列宽改变 刷新表格\r\nfunction jfrefreshgrid_rhcw(rowheight, colwidth, isRefreshCanvas=true){\r\n rhchInit(rowheight, colwidth);\r\n clearTimeout(refreshCanvasTimeOut);\r\n sheetmanage.storeSheetParam();\r\n\r\n //行高列宽改变时 重新计算sparklines\r\n let calcChain = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].calcChain;\r\n \r\n if(calcChain != null && calcChain.length > 0){\r\n if(Store.config[\"rowlen\"] == null){\r\n Store.config[\"rowlen\"] = {};\r\n }\r\n\r\n if(Store.config[\"columnlen\"] == null){\r\n Store.config[\"columnlen\"] = {};\r\n } \r\n\r\n for(let i = 0; i < calcChain.length; i++){\r\n let r = calcChain[i].r, c = calcChain[i].c, index = calcChain[i].index;\r\n\r\n if(index == Store.currentSheetIndex && Store.flowdata[r][c] != null && Store.flowdata[r][c].spl != null && ((r in Store.config[\"rowlen\"]) || (c in Store.config[\"columnlen\"]))){\r\n window.luckysheetCurrentRow = r;\r\n window.luckysheetCurrentColumn = c;\r\n window.luckysheetCurrentFunction = Store.flowdata[r][c].f;\r\n\r\n let fp = $.trim(formula.functionParserExe(Store.flowdata[r][c].f));\r\n let sparklines = new Function(\"return \" + fp)();\r\n Store.flowdata[r][c].spl = sparklines;\r\n\r\n server.saveParam(\"v\", Store.currentSheetIndex, Store.flowdata[r][c], { \"r\": r, \"c\": c });\r\n }\r\n }\r\n\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].data = Store.flowdata;\r\n }\r\n \r\n //批注框同步\r\n luckysheetPostil.positionSync();\r\n //选区同步\r\n selectHightlightShow();\r\n // 协同提示框同步\r\n collaborativeEditBox();\r\n //改变单元格行高,复制虚线框同步\r\n if($(\".luckysheet-selection-copy\").is(\":visible\")){\r\n selectionCopyShow();\r\n }\r\n\r\n //改变单元格行高,选区下拉icon隐藏\r\n if($(\"#luckysheet-dropCell-icon\").is(\":visible\")){\r\n $(\"#luckysheet-dropCell-icon\").remove();\r\n }\r\n\r\n //有冻结状态时,同步行高、列宽\r\n if(luckysheetFreezen.freezenhorizontaldata != null && luckysheetFreezen.freezenverticaldata != null){\r\n let row_st = luckysheetFreezen.freezenhorizontaldata[1] - 1;\r\n let col_st = luckysheetFreezen.freezenverticaldata[1] - 1;\r\n\r\n let scrollTop = luckysheetFreezen.freezenhorizontaldata[2];\r\n let scrollLeft = luckysheetFreezen.freezenverticaldata[2];\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [\r\n Store.visibledatarow[row_st], \r\n row_st + 1, \r\n scrollTop, \r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), \r\n top\r\n ];\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [\r\n Store.visibledatacolumn[col_st], \r\n col_st + 1, \r\n scrollLeft, \r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), \r\n left\r\n ];\r\n\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, freezenverticaldata, left);\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n luckysheetFreezen.createAssistCanvas();\r\n }\r\n else if(luckysheetFreezen.freezenhorizontaldata != null){\r\n let row_st = luckysheetFreezen.freezenhorizontaldata[1] - 1;\r\n let scrollTop = luckysheetFreezen.freezenhorizontaldata[2];\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [\r\n Store.visibledatarow[row_st], \r\n row_st + 1, \r\n scrollTop, \r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), \r\n top\r\n ];\r\n\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n luckysheetFreezen.createAssistCanvas();\r\n }\r\n else if(luckysheetFreezen.freezenverticaldata != null){\r\n let col_st = luckysheetFreezen.freezenverticaldata[1] - 1;\r\n let scrollLeft = luckysheetFreezen.freezenverticaldata[2];\r\n\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [\r\n Store.visibledatacolumn[col_st], \r\n col_st + 1, \r\n scrollLeft, \r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), \r\n left\r\n ];\r\n\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n luckysheetFreezen.createAssistCanvas();\r\n }\r\n else{\r\n //有筛选标志时,同步筛选按钮和筛选范围位置\r\n if($(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").length > 0){\r\n $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").each(function(i, e){\r\n let str = $(e).data(\"str\"), cindex = $(e).data(\"cindex\");\r\n\r\n let left = Store.visibledatacolumn[cindex] - 20;\r\n let top = str - 1 == -1 ? 0 : Store.visibledatarow[str - 1];\r\n\r\n $(e).css({ \"left\": left, \"top\": top });\r\n });\r\n }\r\n }\r\n\r\n if($(\"#luckysheet-filter-selected-sheet\" + Store.currentSheetIndex).length > 0){\r\n let luckysheet_filter_save = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].filter_select;\r\n\r\n let r1 = luckysheet_filter_save.row[0], \r\n r2 = luckysheet_filter_save.row[1];\r\n let c1 = luckysheet_filter_save.column[0], \r\n c2 = luckysheet_filter_save.column[1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n $(\"#luckysheet-filter-selected-sheet\" + Store.currentSheetIndex).css({\r\n \"left\": col_pre,\r\n \"width\": col - col_pre - 1,\r\n \"top\": row_pre,\r\n \"height\": row - row_pre - 1\r\n });\r\n }\r\n\r\n sheetmanage.showSheet();\r\n\r\n if(isRefreshCanvas){\r\n refreshCanvasTimeOut = setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n \r\n}\r\n\r\n//Refresh the canvas display data according to scrollHeight and scrollWidth\r\nfunction luckysheetrefreshgrid(scrollWidth, scrollHeight) {\r\n formula.groupValuesRefresh();\r\n \r\n if (scrollWidth == null) {\r\n scrollWidth = $(\"#luckysheet-cell-main\").scrollLeft();\r\n }\r\n if (scrollHeight == null) {\r\n scrollHeight = $(\"#luckysheet-cell-main\").scrollTop();\r\n }\r\n\r\n if (luckysheetFreezen.freezenverticaldata != null || luckysheetFreezen.freezenhorizontaldata != null) {\r\n let freezen_horizon_px, freezen_horizon_ed, freezen_horizon_scrollTop;\r\n let freezen_vertical_px, freezen_vertical_ed, freezen_vertical_scrollTop;\r\n let drawWidth = Store.luckysheetTableContentHW[0], drawHeight = Store.luckysheetTableContentHW[1];\r\n \r\n if (luckysheetFreezen.freezenverticaldata != null && luckysheetFreezen.freezenhorizontaldata != null) {\r\n freezen_horizon_px = luckysheetFreezen.freezenhorizontaldata[0];\r\n freezen_horizon_ed = luckysheetFreezen.freezenhorizontaldata[1];\r\n freezen_horizon_scrollTop = luckysheetFreezen.freezenhorizontaldata[2];\r\n\r\n freezen_vertical_px = luckysheetFreezen.freezenverticaldata[0];\r\n freezen_vertical_ed = luckysheetFreezen.freezenverticaldata[1];\r\n freezen_vertical_scrollTop = luckysheetFreezen.freezenverticaldata[2];\r\n\r\n //左上canvas freezen_3\r\n luckysheetDrawMain(\r\n freezen_vertical_scrollTop, \r\n freezen_horizon_scrollTop, \r\n freezen_vertical_px, \r\n freezen_horizon_px, \r\n 1, \r\n 1, \r\n null, \r\n null, \r\n \"freezen_3\"\r\n );\r\n\r\n //上右canvas freezen_4\r\n luckysheetDrawMain(\r\n scrollWidth + freezen_vertical_px - freezen_vertical_scrollTop, \r\n freezen_horizon_scrollTop, \r\n drawWidth - freezen_vertical_px + freezen_vertical_scrollTop, \r\n freezen_horizon_px, \r\n 1, \r\n 1, \r\n null, \r\n null, \r\n \"freezen_4\"\r\n );\r\n\r\n //左下canvas freezen_7\r\n luckysheetDrawMain(\r\n freezen_vertical_scrollTop, \r\n scrollHeight + freezen_horizon_px - freezen_horizon_scrollTop, \r\n freezen_vertical_px, \r\n drawHeight - freezen_horizon_px + freezen_horizon_scrollTop, \r\n 1, \r\n 1, \r\n null, \r\n null, \r\n \"freezen_7\"\r\n );\r\n\r\n //右下canvas luckysheetTableContent\r\n luckysheetDrawMain(\r\n scrollWidth + freezen_vertical_px - freezen_vertical_scrollTop, \r\n scrollHeight + freezen_horizon_px - freezen_horizon_scrollTop, \r\n drawWidth - freezen_vertical_px + freezen_vertical_scrollTop, \r\n drawHeight - freezen_horizon_px + freezen_horizon_scrollTop, \r\n freezen_vertical_px - freezen_vertical_scrollTop + Store.rowHeaderWidth, \r\n freezen_horizon_px - freezen_horizon_scrollTop + Store.columnHeaderHeight\r\n );\r\n\r\n //标题\r\n luckysheetDrawgridColumnTitle(freezen_vertical_scrollTop, freezen_vertical_px, Store.rowHeaderWidth);\r\n luckysheetDrawgridColumnTitle(\r\n scrollWidth + freezen_vertical_px - freezen_vertical_scrollTop, \r\n drawWidth - freezen_vertical_px + freezen_vertical_scrollTop, \r\n freezen_vertical_px - freezen_vertical_scrollTop + Store.rowHeaderWidth\r\n );\r\n \r\n luckysheetDrawgridRowTitle(freezen_horizon_scrollTop, freezen_horizon_px, Store.columnHeaderHeight);\r\n luckysheetDrawgridRowTitle(\r\n scrollHeight + freezen_horizon_px - freezen_horizon_scrollTop, \r\n drawHeight - freezen_horizon_px + freezen_horizon_scrollTop, \r\n freezen_horizon_px - freezen_horizon_scrollTop + Store.columnHeaderHeight\r\n );\r\n \r\n }\r\n else if (luckysheetFreezen.freezenhorizontaldata != null) {\r\n freezen_horizon_px = luckysheetFreezen.freezenhorizontaldata[0];\r\n freezen_horizon_ed = luckysheetFreezen.freezenhorizontaldata[1];\r\n freezen_horizon_scrollTop = luckysheetFreezen.freezenhorizontaldata[2];\r\n\r\n luckysheetDrawMain(\r\n scrollWidth, \r\n freezen_horizon_scrollTop, \r\n drawWidth, \r\n freezen_horizon_px, \r\n 1, \r\n 1, \r\n null, \r\n null, \r\n \"freezen_h\"\r\n );\r\n luckysheetDrawMain(\r\n scrollWidth, \r\n scrollHeight + freezen_horizon_px - freezen_horizon_scrollTop, \r\n drawWidth, \r\n drawHeight - freezen_horizon_px + freezen_horizon_scrollTop, \r\n null, \r\n freezen_horizon_px - freezen_horizon_scrollTop + Store.columnHeaderHeight\r\n );\r\n \r\n luckysheetDrawgridColumnTitle(scrollWidth, drawWidth, null);\r\n \r\n luckysheetDrawgridRowTitle(freezen_horizon_scrollTop, freezen_horizon_px, Store.columnHeaderHeight);\r\n luckysheetDrawgridRowTitle(\r\n scrollHeight + freezen_horizon_px - freezen_horizon_scrollTop, \r\n drawHeight - freezen_horizon_px + freezen_horizon_scrollTop, \r\n freezen_horizon_px - freezen_horizon_scrollTop + Store.columnHeaderHeight\r\n );\r\n \r\n }\r\n else if (luckysheetFreezen.freezenverticaldata != null) {\r\n freezen_vertical_px = luckysheetFreezen.freezenverticaldata[0];\r\n freezen_vertical_ed = luckysheetFreezen.freezenverticaldata[1];\r\n freezen_vertical_scrollTop = luckysheetFreezen.freezenverticaldata[2];\r\n \r\n luckysheetDrawMain(\r\n freezen_vertical_scrollTop, \r\n scrollHeight, \r\n freezen_vertical_px, \r\n drawHeight, \r\n 1, \r\n 1, \r\n null, \r\n null, \r\n \"freezen_v\"\r\n );\r\n luckysheetDrawMain(\r\n scrollWidth + freezen_vertical_px - freezen_vertical_scrollTop, \r\n scrollHeight, \r\n drawWidth - freezen_vertical_px + freezen_vertical_scrollTop, \r\n drawHeight, \r\n freezen_vertical_px - freezen_vertical_scrollTop + Store.rowHeaderWidth, \r\n null\r\n );\r\n \r\n luckysheetDrawgridRowTitle(scrollHeight, drawHeight, null);\r\n \r\n luckysheetDrawgridColumnTitle(freezen_vertical_scrollTop, freezen_vertical_px, Store.rowHeaderWidth);\r\n luckysheetDrawgridColumnTitle(\r\n scrollWidth + freezen_vertical_px - freezen_vertical_scrollTop, \r\n drawWidth - freezen_vertical_px + freezen_vertical_scrollTop, \r\n freezen_vertical_px - freezen_vertical_scrollTop + Store.rowHeaderWidth\r\n );\r\n \r\n }\r\n }\r\n else {\r\n if($(\"#luckysheetTableContent\").length == 0){\r\n return;\r\n }\r\n let luckysheetTableContent = $(\"#luckysheetTableContent\").get(0).getContext(\"2d\");\r\n luckysheetDrawMain(scrollWidth, scrollHeight);\r\n \r\n // luckysheetTableContent.clearRect(0, 0, 46, 20);\r\n \r\n luckysheetDrawgridColumnTitle(scrollWidth);\r\n luckysheetDrawgridRowTitle(scrollHeight);\r\n\r\n //清除canvas左上角区域 防止列标题栏序列号溢出显示\r\n \r\n luckysheetTableContent.clearRect(0, 0, (Store.rowHeaderWidth* Store.devicePixelRatio-1) , (Store.columnHeaderHeight* Store.devicePixelRatio-1) );\r\n }\r\n}\r\n\r\nexport {\r\n jfrefreshgrid,\r\n jfrefreshgridall,\r\n jfrefreshrange,\r\n jfrefreshgrid_adRC,\r\n jfrefreshgrid_deleteCell,\r\n jfrefreshgrid_pastcut,\r\n jfrefreshgrid_rhcw,\r\n luckysheetrefreshgrid,\r\n}","import pako from 'pako'\r\nimport { showloading, hideloading } from '../global/loading';\r\nimport { luckysheetrefreshgrid, jfrefreshgrid_rhcw } from '../global/refresh';\r\nimport editor from '../global/editor'\r\nimport { sheetHTML, luckyColor } from './constant';\r\nimport sheetmanage from './sheetmanage';\r\nimport menuButton from './menuButton';\r\nimport { createFilterOptions } from './filter';\r\nimport luckysheetFreezen from './freezen';\r\nimport luckysheetPostil from './postil';\r\nimport imageCtrl from './imageCtrl';\r\nimport dataVerificationCtrl from './dataVerificationCtrl';\r\nimport hyperlinkCtrl from './hyperlinkCtrl';\r\nimport { getObjType, replaceHtml, getByteLen } from '../utils/util';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport Store from '../store';\r\nimport { collaborativeEditBox } from './select'\r\nimport locale from '../locale/locale';\r\nimport dayjs from \"dayjs\";\r\nimport json from '../global/json';\r\n\r\nconst server = {\r\n gridKey: null,\r\n loadUrl: null,\r\n updateUrl: null,\r\n updateImageUrl: null,\r\n title: null,\r\n\t\tloadSheetUrl: null,\r\n\t\tretryTimer:null,\r\n allowUpdate: false, //共享编辑模式\r\n historyParam: function(data, sheetIndex, range) {\r\n \tlet _this = this;\r\n\r\n\t let r1 = range.row[0], r2 = range.row[1];\r\n\t let c1 = range.column[0], c2 = range.column[1];\r\n\r\n\t if(r1 == r2 && c1 == c2){ //单个单元格更新\r\n\t let v = data[r1][c1];\r\n\t _this.saveParam(\"v\", sheetIndex, v, { \"r\": r1, \"c\": c1 });\r\n\t }\r\n\t else{ //范围单元格更新\r\n\t let rowlen = r2 - r1 + 1;\r\n\t let collen = c2 - c1 + 1;\r\n\r\n\t let timeR = Math.floor(1000 / collen);\r\n\t let n = Math.ceil(rowlen / timeR); //分批次更新,一次最多1000个单元格\r\n\r\n\t for(let i = 0; i < n; i++){\r\n\t let str = r1 + timeR * i;\r\n\r\n\t\t\t\tlet edr;\r\n\t if(i == n - 1){\r\n\t edr = r2;\r\n\t }\r\n\t else{\r\n\t edr = r1 + timeR * (i + 1) - 1;\r\n\t }\r\n\r\n\t let v = [];\r\n\r\n\t for(let r = str; r <= edr; r++){\r\n\t let v_row = [];\r\n\r\n\t for(let c = c1; c <= c2; c++){\r\n\t\t\t\t\t\tif(data[r]==null){\r\n\t\t\t\t\t\t\tv_row.push(null);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\tv_row.push(data[r][c]);\r\n\t\t\t\t\t\t}\r\n\t }\r\n\r\n\t v.push(v_row);\r\n\t }\r\n\r\n\t _this.saveParam(\"rv\", sheetIndex, v, { \"range\": { \"row\": [str, edr], \"column\": [c1, c2] } });\r\n\r\n\t if(i == n - 1){\r\n\t _this.saveParam(\"rv_end\", sheetIndex, null);\r\n\t }\r\n\t }\r\n\t }\r\n\t},\r\n saveParam: function (type, index, value, params) {\r\n \tlet _this = this;\r\n\r\n\t if(!_this.allowUpdate){\r\n\t return;\r\n\t }\r\n\r\n\t if(value == undefined){\r\n\t value = null;\r\n\t }\r\n\r\n\t let d = {};\r\n\t d.t = type;\r\n\t d.i = index;\r\n\t d.v = value;\r\n\r\n\t\t//切换sheet页不发后台,TODO:改为发后台+后台不广播 \r\n\t\tif(type === 'shs'){\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t if (type == \"rv\") { //单元格批量更新\r\n\t d.range = params.range;\r\n\t }\r\n\t else if (type == \"v\" || type == \"fu\" || type == \"fm\") {\r\n\t d.r = params.r;\r\n\t d.c = params.c;\r\n\t }\r\n\t else if (type == \"fc\") {\r\n\t d.op = params.op;\r\n\t d.pos = params.pos;\r\n\t }\r\n\t else if (type == \"drc\" || type == \"arc\" || type == \"h\" || type == \"wh\") {\r\n\t d.rc = params.rc;\r\n\t }\r\n\t else if (type == \"c\") {\r\n\t d.cid = params.cid;\r\n\t d.op = params.op;\r\n\t }\r\n\t else if (type == \"f\") {\r\n\t d.op = params.op;\r\n\t d.pos = params.pos;\r\n\t }\r\n\t else if (type == \"s\") {\r\n\r\n\t }\r\n\t else if (type == \"sh\") {\r\n\t d.op = params.op;\r\n\t if(params.cur != null){\r\n\t d.cur = params.cur;\r\n\t }\r\n\t }\r\n\t else if (type == \"cg\") {\r\n\t d.k = params.k;\r\n\t }\r\n\t else if (type == \"all\") {\r\n\t d.k = params.k;\r\n\t // d.s = params.s;\r\n\t }\r\n\r\n\t let msg = pako.gzip(encodeURIComponent(JSON.stringify(d)), { to: \"string\" });\r\n\r\n\t\tif(_this.websocket!=null){\r\n\t\t\t_this.websocket.send(msg);\r\n\t\t}\r\n\r\n\t},\r\n websocket: null,\r\n wxErrorCount: 0,\r\n openWebSocket: function(){\r\n let _this = this;\r\n\r\n if('WebSocket' in window){\r\n\t\t\tlet wxUrl = _this.updateUrl + \"?t=111&g=\" + encodeURIComponent(_this.gridKey);\r\n\t\t\tif(_this.updateUrl.indexOf('?') > -1){\r\n\t\t\t\twxUrl = _this.updateUrl + \"&t=111&g=\" + encodeURIComponent(_this.gridKey);\r\n\t\t\t}\r\n\r\n\t _this.websocket = new WebSocket(wxUrl);\r\n\r\n\t //连接建立时触发\r\n\t _this.websocket.onopen = function() {\r\n\t \tconsole.info(locale().websocket.success);\r\n\t \thideloading();\r\n\t\t\t\t_this.wxErrorCount = 0;\r\n\t\t\t\t\r\n\t //防止websocket长时间不发送消息导致断连\r\n\t\t\t\t_this.retryTimer = setInterval(function(){\r\n\t _this.websocket.send(\"rub\");\r\n\t }, 60000);\r\n\t }\r\n\r\n\t //客户端接收服务端数据时触发\r\n\t _this.websocket.onmessage = function(result){\r\n\t\t\t\tStore.result = result\r\n\t\t\t\tlet data = new Function(\"return \" + result.data)();\r\n\t\t\t\tconsole.info(data);\r\n\t\t\t\tlet type = data.type;\r\n\t\t\t\tlet {message,id} = data;\r\n\t\t\t\t// 用户退出时,关闭协同编辑时其提示框\r\n\t\t\t\tif(message === '用户退出') {\r\n\t\t\t\t\t$(\"#luckysheet-multipleRange-show-\" + id).hide();\r\n\t\t\t\t\tStore.cooperativeEdit.changeCollaborationSize = Store.cooperativeEdit.changeCollaborationSize.filter(value => {\r\n\t\t\t\t\t\treturn value.id != id\r\n\t\t\t\t\t})\r\n\t\t\t\t\tStore.cooperativeEdit.checkoutData = Store.cooperativeEdit.checkoutData.filter(value => {\r\n\t\t\t\t\t\treturn value.id != id\r\n\t\t\t\t\t})\r\n\t\t\t\t}\r\n\t if(type == 1){ //send 成功或失败\r\n\r\n\t }\r\n\t else if(type == 2){ //更新数据\r\n\t let item = JSON.parse(data.data);\r\n\t\t\t\t\t_this.wsUpdateMsg(item);\r\n\t\t\t\t\tlet chang_data = JSON.parse(data.data)\r\n\t\t\t\t\tif(chang_data.k == 'columnlen') {\r\n\t\t\t\t\t\tcollaborativeEditBox(chang_data.v,null)\r\n\t\t\t\t\t} else if(chang_data.k == 'rowlen') {\r\n\t\t\t\t\t\tcollaborativeEditBox(null,chang_data.v)\r\n\t\t\t\t\t}\r\n\t }\r\n\t else if(type == 3){ //多人操作不同选区(\"t\": \"mv\")(用不同颜色显示其他人所操作的选区)\r\n\t let id = data.id;\r\n\t let username = data.username;\r\n\t let item = JSON.parse(data.data);\r\n\t let type = item.t,\r\n\t index = item.i,\r\n\t value = item.v;\r\n\t\t\t\t\tif(Store.cooperativeEdit.changeCollaborationSize.length === 0) {\r\n\t\t\t\t\t\tStore.cooperativeEdit.changeCollaborationSize.push({id:id,v:item.v[0],i:index})\r\n\t\t\t\t\t}\t \r\n\t\t\t\t\tlet flag = Store.cooperativeEdit.changeCollaborationSize.some(value1 => {\r\n\t\t\t\t\t\treturn value1.id == id\r\n\t\t\t\t\t})\r\n\t\t\t\t\tif(flag) {\r\n\t\t\t\t\t\tStore.cooperativeEdit.changeCollaborationSize.forEach(val => {\r\n\t\t\t\t\t\t\tif(val.id == id) {\r\n\t\t\t\t\t\t\t\tval.v = item.v[0]\r\n\t\t\t\t\t\t\t\tval.i = index\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}) \r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tStore.cooperativeEdit.changeCollaborationSize.push({id:id,v:item.v[0],i:index})\r\n\t\t\t\t\t}\t\t\r\n\t if(getObjType(value) != \"array\" && getObjType(value) !== \"object\"){\r\n\t value = JSON.parse(value);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlet r = 0\r\n\t\t\t\t\tlet c = 0\r\n\t\t\t\t\tif(index == Store.currentSheetIndex){//发送消息者在当前页面\r\n\r\n\t\t\t\t\t\tif(getObjType(value) === \"object\" && value.op === 'enterEdit'){\r\n\t\t\t\t\t\t\tr = value.range[value.range.length - 1].row[0];\r\n\t\t\t\t\t\t\tc = value.range[value.range.length - 1].column[0];\r\n\t\t\t\t\t\t\t_this.multipleRangeShow(id, username, r, c, value.op);\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t}else {\r\n\r\n\t\t\t\t\t\t\tr = value[value.length - 1].row[0];\r\n\t\t\t\t\t\t\tc = value[value.length - 1].column[0];\r\n\t\r\n\t\t\t\t\t\t\t_this.multipleRangeShow(id, username, r, c);\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tif(getObjType(value) === \"object\" && value.op === 'enterEdit'){\r\n\t\t\t\t\t\t\tr = value.range[value.range.length - 1].row[0];\r\n\t\t\t\t\t\t\tc = value.range[value.range.length - 1].column[0];\r\n\t\t\t\t\t\t}else {\r\n\t\t\t\t\t\t\tr = value[value.length - 1].row[0];\r\n\t\t\t\t\t\t\tc = value[value.length - 1].column[0];\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif(Store.cooperativeEdit.checkoutData.length === 0) {\r\n\t\t\t\t\t\tif(value.op) {\r\n\t\t\t\t\t\t\tStore.cooperativeEdit.checkoutData.push({id,username,r,c,op:value.op,index})\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tStore.cooperativeEdit.checkoutData.push({id,username,r,c,index})\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlet checkoutFlag = Store.cooperativeEdit.checkoutData.some(item => {\r\n\t\t\t\t\t\treturn item.id == id\r\n\t\t\t\t\t})\r\n\t\t\t\t\tif(checkoutFlag) {\r\n\t\t\t\t\t\tStore.cooperativeEdit.checkoutData.forEach(item => {\r\n\t\t\t\t\t\t\tif(item.id == id) {\r\n\t\t\t\t\t\t\t\titem.username = username\r\n\t\t\t\t\t\t\t\titem.r = r\r\n\t\t\t\t\t\t\t\titem.c = c\r\n\t\t\t\t\t\t\t\titem.index = index\r\n\t\t\t\t\t\t\t\tif (value.op === 'enterEdit') {\r\n\t\t\t\t\t\t\t\t\titem.op = value.op\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tif(value.op === 'enterEdit') {\r\n\t\t\t\t\t\t\tStore.cooperativeEdit.checkoutData.push({id,username,r,c,op:value.op,index})\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tStore.cooperativeEdit.checkoutData.push({id,username,r,c,index})\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t//其他客户端切换页面时\r\n\t\t\t\t\tStore.cooperativeEdit.checkoutData.forEach(item => {\r\n\t\t\t\t\t\tif(item.index != Store.currentSheetIndex) {\r\n\t\t\t\t\t\t\t$(\"#luckysheet-multipleRange-show-\" + item.id).hide();\r\n\t\t\t\t\t\t\titem.op == ''\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t})\r\n\r\n\t\t\t\t\tif($(\"#luckysheet-multipleRange-show-\" + id)[0]) {\r\n\t\t\t\t\t\tlet change_bottom = $(\"#luckysheet-multipleRange-show-\" + id)[0].offsetHeight - 1\r\n\t\t\t\t\t\t$(\"#luckysheet-multipleRange-show-\" + id + \">.username\").css({\"bottom\":change_bottom + 'px'})\r\n\t\t\t\t\t}\r\n\t }\r\n\t else if(type == 4){ //批量指令更新\r\n\t\t\t\t\t// let items = JSON.parse(data.data);\r\n\r\n\t\t\t\t\t// After editing by multiple people, data.data may appear as an empty string\r\n\t\t\t\t\tlet items = data.data === \"\" ? data.data : JSON.parse(data.data);\r\n\r\n\t for(let i = 0; i < items.length; i++){\r\n\t _this.wsUpdateMsg(item[i]);\r\n\t }\r\n\t }\r\n\t }\r\n\r\n\t //通信发生错误时触发\r\n\t _this.websocket.onerror = function(){\r\n\t _this.wxErrorCount++;\r\n\r\n\t if(_this.wxErrorCount > 3){\r\n\t showloading(locale().websocket.refresh);\r\n\t }\r\n\t else{\r\n\t showloading(locale().websocket.wait);\r\n\t _this.openWebSocket();\r\n\t }\r\n\t }\r\n\r\n\t //连接关闭时触发\r\n\t _this.websocket.onclose = function(e){\r\n\t\t\t\tconsole.info(locale().websocket.close);\r\n\t\t\t\tif(e.code === 1000){\r\n\t\t\t\t\tclearInterval(_this.retryTimer)\r\n\t\t\t\t\t_this.retryTimer = null\r\n\t\t\t\t}else{\r\n\t\t\t\t\talert(locale().websocket.contact);\r\n\t\t\t\t}\r\n\t }\r\n\t }\r\n\t else{\r\n\t alert(locale().websocket.support);\r\n\t }\r\n },\r\n wsUpdateMsg: function(item) {\r\n\t let type = item.t,\r\n\t index = item.i,\r\n\t value = item.v;\r\n\r\n\t let file = Store.luckysheetfile[getSheetIndex(index)];\r\n\r\n\t if([\"v\",\"rv\",\"cg\",\"all\",\"fc\",\"drc\",\"arc\",\"f\",\"fsc\",\"fsr\",\"sh\",\"c\"].includes(type) && file == null){\r\n\t return;\r\n\t }\r\n\r\n\t if(type == \"v\"){ //单个单元格数据更新\r\n\t if(file.data == null || file.data.length == 0){\r\n\t return;\r\n\t }\r\n\r\n\t let r = item.r, c = item.c;\r\n\t file.data[r][c] = value;\r\n\r\n\t if(index == Store.currentSheetIndex){//更新数据为当前表格数据\r\n\t\t\t\tStore.flowdata = file.data;\r\n\t\t\t\teditor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n\t //如果更新的单元格有批注\r\n\t if(value != null && value.ps != null){\r\n\t luckysheetPostil.buildPs(r, c, value.ps);\r\n\t }\r\n\t else{\r\n\t luckysheetPostil.buildPs(r, c, null);\r\n\t }\r\n\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t }\r\n\t\telse if(type == \"rv\"){ //范围单元格数据更新\r\n\t\t\tif(Object.keys(item.range).length > 0) {\r\n\t\t\t\tStore.cooperativeEdit.merge_range = item.range\r\n\t\t\t\tStore.cooperativeEdit.merge_range.v = item.v\r\n\t\t\t\tcollaborativeEditBox();\r\n\t\t\t}\r\n\t if(file.data == null || file.data.length == 0){\r\n\t return;\r\n\t }\r\n\r\n\t let r1 = item.range.row[0], r2 = item.range.row[1];\r\n\t let c1 = item.range.column[0], c2 = item.range.column[1];\r\n\r\n\t for(let r = r1; r <= r2; r++){\r\n\t for(let c = c1; c <= c2; c++){\r\n\t file.data[r][c] = value[r - r1][c - c1];\r\n\t }\r\n\t }\r\n\r\n\t if(index == Store.currentSheetIndex){//更新数据为当前表格数据\r\n\t\t\t\tStore.flowdata = file.data;\r\n\t\t\t\teditor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\t\t\t\t\r\n\t //如果更新的单元格有批注\r\n\t for(let r = r1; r <= r2; r++){\r\n\t for(let c = c1; c <= c2; c++){\r\n\t if(value[r - r1][c - c1] != null && value[r - r1][c - c1].ps != null){\r\n\t luckysheetPostil.buildPs(r, c, value[r - r1][c - c1].ps);\r\n\t }\r\n\t else{\r\n\t luckysheetPostil.buildPs(r, c, null);\r\n\t }\r\n\t }\r\n\t }\r\n\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t\t\t}\r\n\t }\r\n\t else if(type == \"cg\"){ //config更新(rowhidden,rowlen,columnlen,merge,borderInfo)\r\n\t let k = item.k;\r\n\r\n\t if(k == \"borderInfo\"){\r\n\t\t\t\tfile[\"config\"][\"borderInfo\"] = value;\r\n\t }\r\n\t else{\r\n\t if(!(k in file[\"config\"])){\r\n\t file[\"config\"][k] = {};\r\n\t }\r\n\r\n\t for(let key in value){\r\n\t file[\"config\"][k][key] = value[key];\r\n\t }\r\n\t }\r\n\r\n\t if(index == Store.currentSheetIndex){//更新数据为当前表格数据\r\n\t Store.config = file[\"config\"];\r\n\r\n\t if(k == \"rowlen\" || k == \"columnlen\" || k == \"rowhidden\"){\r\n\t jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n\t }\r\n\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t }\r\n\t else if(type == \"all\"){ //通用保存更新\r\n\t let k = item.k;\r\n\t file[k] = value;\r\n\r\n\t if(k == \"name\"){ //工作表名\r\n\t $(\"#luckysheet-sheet-container-c #luckysheet-sheets-item\" + index).find(\"span.luckysheet-sheets-item-name\").html(value);\r\n\t }\r\n\t else if(k == \"color\"){ //工作表颜色\r\n\t let currentSheetItem = $(\"#luckysheet-sheet-container-c #luckysheet-sheets-item\" + index);\r\n\t currentSheetItem.find(\".luckysheet-sheets-item-color\").remove();\r\n\r\n\t if(value != null || value != \"\"){\r\n\t currentSheetItem.append('
');\r\n\t }\r\n\t }\r\n\t else if(k == \"pivotTable\"){ //PivotTable\r\n\t // luckysheet.pivotTable.changePivotTable(index);\r\n\t }\r\n\t\t\telse if(k == \"frozen\"){ //freezen row and column\r\n\r\n\t\t\t\t// tranform frozen\r\n\t\t\t\tluckysheetFreezen.frozenTofreezen();\r\n\r\n\t if(index == Store.currentSheetIndex){\r\n\t\t\t\t\tconst _locale = locale();\r\n\t\t\t\t\tconst locale_freezen = _locale.freezen;\r\n\t if(file[\"freezen\"].horizontal == null){\r\n\t $(\"#luckysheet-freezen-btn-horizontal\").html(' '+locale_freezen.freezenRow);\r\n\t luckysheetFreezen.freezenhorizontaldata = null;\r\n\t $(\"#luckysheet-freezebar-horizontal\").hide();\r\n\t }\r\n\t else{\r\n\t luckysheetFreezen.createFreezenHorizontal(file[\"freezen\"].horizontal.freezenhorizontaldata, file[\"freezen\"].horizontal.top);\r\n\t }\r\n\r\n\t if(file[\"freezen\"].vertical == null){\r\n\t $(\"#luckysheet-freezen-btn-vertical\").html(' '+locale_freezen.freezenColumn);\r\n\t luckysheetFreezen.freezenverticaldata = null;\r\n\t $(\"#luckysheet-freezebar-vertical\").hide();\r\n\t }\r\n\t else{\r\n\t luckysheetFreezen.createFreezenVertical(file[\"freezen\"].vertical.freezenverticaldata, file[\"freezen\"].vertical.left);\r\n\t }\r\n\r\n\t luckysheetFreezen.createAssistCanvas();\r\n\t }\r\n\t }\r\n\t else if(k == \"filter_select\"){ //筛选范围\r\n\t if(index == Store.currentSheetIndex){\r\n\t createFilterOptions(value);\r\n\t }\r\n\t }\r\n\t else if(k == \"filter\"){ //筛选保存\r\n\t if(index == Store.currentSheetIndex){\r\n\t createFilterOptions(file.filter_select, value);\r\n\t }\r\n\t }\r\n\t else if(k == \"luckysheet_conditionformat_save\"){ //条件格式\r\n\t if(index == Store.currentSheetIndex){\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t }\r\n\t else if(k == \"luckysheet_alternateformat_save\"){ //交替颜色\r\n\t if(index == Store.currentSheetIndex){\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t }\r\n\t else if(k == \"config\"){ //config\r\n\t if(index == Store.currentSheetIndex){\r\n\t Store.config = value;\r\n\t jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n\t }\r\n\t }\r\n\t else if(k == \"dynamicArray\"){ //动态数组\r\n\t if(index == Store.currentSheetIndex){\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t\t\t}\r\n\t\t\telse if(k == \"images\"){ //图片\r\n\t\t\t\tif(index == Store.currentSheetIndex){\r\n\t\t\t\t\timageCtrl.images = value;\r\n\t\t\t\t\timageCtrl.allImagesShow();\r\n\t\t\t\t\timageCtrl.init();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(k == \"dataVerification\"){ //数据验证\r\n\t\t\t\tif(index == Store.currentSheetIndex){\r\n\t\t\t\t\tdataVerificationCtrl.dataVerification = value;\r\n \t\t\tdataVerificationCtrl.init();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if(k == \"hyperlink\"){ //链接\r\n\t\t\t\tif(index == Store.currentSheetIndex){\r\n\t\t\t\t\thyperlinkCtrl.hyperlink = value;\r\n \t\t\thyperlinkCtrl.init();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t }\r\n\t else if(type == \"fc\"){ //函数链calc\r\n\t let op = item.op, pos = item.pos;\r\n\r\n\t if(getObjType(value) != \"object\"){\r\n\t\t\t\tvalue = new Function(\"return \" + value)();\r\n\t }\r\n\r\n\t let r = value.r, c = value.c;\r\n\r\n\t let calcChain = file[\"calcChain\"] == null ? [] : file[\"calcChain\"];\r\n\r\n\t if(op == \"add\"){\r\n\t calcChain.push(value);\r\n\t }\r\n\t else if(op == \"del\"){\r\n\t for(let a = 0; a < calcChain.length; a++){\r\n\t if(r == calcChain[a].r && c == calcChain[a].c && index == calcChain[a].index){\r\n\t calcChain.splice(a, 1);\r\n\t }\r\n\t }\r\n\t }\r\n\t // else if(op == \"update\"){\r\n\t // for(let a = 0; a < calcChain.length; a++){\r\n\t // if(r == calcChain[a].r && c == calcChain[a].c && index == calcChain[a].index){\r\n\t // calcChain[a].func = func;\r\n\t // }\r\n\t // }\r\n\t // }\r\n\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t else if(type == \"drc\"){ //删除行列\r\n\t if(file.data == null || file.data.length == 0){\r\n\t return;\r\n\t }\r\n\r\n\t let rc = item.rc,\r\n\t \tst_i = value.index,\r\n\t \tlen = value.len,\r\n\t \tmc = value.mc,\r\n\t \tborderInfo = value.borderInfo;\r\n\t let data = file.data;\r\n\r\n\t if(rc == \"r\"){\r\n\t file[\"row\"] -= len;\r\n\r\n\t data.splice(st_i, len);\r\n\r\n\t //空白行模板\r\n\t let row = [];\r\n\t for (let c = 0; c < data[0].length; c++) {\r\n\t row.push(null);\r\n\t }\r\n\r\n\t //删除多少行,增加多少行空白行\r\n\t for (let r = 0; r < len; r++) {\r\n\t data.push(row);\r\n\t }\r\n\t }\r\n\t else{\r\n\t file[\"column\"] -= len;\r\n\r\n\t //空白列模板\r\n\t let addcol = [];\r\n\t for (let r = 0; r < len; r++) {\r\n\t addcol.push(null);\r\n\t }\r\n\r\n\t for(let i = 0; i < data.length; i++){\r\n\t data[i].splice(st_i, len);\r\n\r\n\t data[i] = data[i].concat(addcol);\r\n\t }\r\n\t }\r\n\r\n\t for(let x in mc){\r\n\t let r = mc[x].r, c = mc[x].c;\r\n\t data[r][c].mc = mc[x];\r\n\t }\r\n\r\n\t file[\"config\"].merge = mc;\r\n\t file[\"config\"].borderInfo = borderInfo;\r\n\r\n\t if(index == Store.currentSheetIndex){\r\n\t\t\t\tStore.flowdata = data;\r\n\t\t\t\teditor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n\t Store.config[\"merge\"] = mc;\r\n\t Store.config[\"borderInfo\"] = borderInfo;\r\n\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t }\r\n\t else if(type == \"arc\"){ //增加行列\r\n\t if(file.data == null || file.data.length == 0){\r\n\t return;\r\n\t }\r\n\r\n\t let rc = item.rc,\r\n\t \tst_i = value.index,\r\n\t \tlen = value.len,\r\n\t\t\t\taddData = value.data,\r\n\t\t\t\tdirection = value.direction,\r\n\t \tmc = value.mc,\r\n\t \tborderInfo = value.borderInfo;\r\n\t let data = $.extend(true, [], file.data);\r\n\r\n\t if(rc == \"r\"){\r\n\t\t\t\tfile[\"row\"] += len;\r\n\t\t\t\t\r\n\t\t\t\t//空行模板\r\n\t\t\t\tlet row = [];\r\n\t\t\t\tfor(let c = 0; c < data[0].length; c++){\r\n\t\t\t\t\trow.push(null);\r\n\t\t\t\t}\r\n\r\n\t let arr = [];\r\n\t for(let i = 0; i < len; i++){\r\n\t\t\t\t\tif(addData[i] == null){\r\n\t\t\t\t\t\tarr.push(JSON.stringify(row));\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\tarr.push(JSON.stringify(addData[i]));\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif(direction == \"lefttop\"){\r\n\t\t\t\t\tif(st_i == 0){\r\n\t\t\t\t\t\tnew Function(\"data\",\"return \" + 'data.unshift(' + arr.join(\",\") + ')')(data);\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\tnew Function(\"data\",\"return \" + 'data.splice(' + st_i + ', 0, ' + arr.join(\",\") + ')')(data);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse{ \r\n\t\t\t\t\tnew Function(\"data\",\"return \" + 'data.splice(' + (st_i + 1) + ', 0, ' + arr.join(\",\") + ')')(data); \r\n\t\t\t\t}\r\n\t }\r\n\t else{\r\n\t file[\"column\"] += len;\r\n\r\n\t for(let i = 0; i < data.length; i++){\r\n\t data[i].splice(st_i, 0, addData[i]);\r\n\t }\r\n\t }\r\n\r\n\t for(let x in mc){\r\n\t let r = mc[x].r, c = mc[x].c;\r\n\t data[r][c].mc = mc[x];\r\n\t }\r\n\r\n\t\t\tfile.data = data;\r\n\t file[\"config\"].merge = mc;\r\n\t file[\"config\"].borderInfo = borderInfo;\r\n\r\n\t if(index == Store.currentSheetIndex){\r\n\t\t\t\tStore.flowdata = data;\r\n\t\t\t\teditor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n\t Store.config[\"merge\"] = mc;\r\n\t Store.config[\"borderInfo\"] = borderInfo;\r\n\r\n\t setTimeout(function () {\r\n\t luckysheetrefreshgrid();\r\n\t }, 1);\r\n\t }\r\n\t }\r\n\t else if(type == \"f\"){ //筛选\r\n\t let op = item.op, pos = item.pos;\r\n\r\n\t let filter = file.filter;\r\n\r\n\t if(filter == null){\r\n\t filter = {};\r\n\t }\r\n\r\n\t if(op == \"upOrAdd\"){\r\n\t filter[pos] = value;\r\n\t }\r\n\t else if(op == \"del\"){\r\n\t delete filter[pos];\r\n\t }\r\n\r\n\t if(index == Store.currentSheetIndex){\r\n\t createFilterOptions(file.filter_select, filter);\r\n\t }\r\n\t }\r\n\t else if(type == \"fsc\"){ //清除筛选\r\n\t file.filter = null;\r\n\t file.filter_select = null;\r\n\r\n\t if(index == Store.currentSheetIndex){\r\n\t $('#luckysheet-filter-selected-sheet' + Store.currentSheetIndex + ', #luckysheet-filter-options-sheet' + Store.currentSheetIndex).remove();\r\n\t $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n\t }\r\n\t }\r\n\t else if(type == \"fsr\"){ //恢复筛选\r\n\t file.filter = value.filter;\r\n\t file.filter_select = value.filter_select;\r\n\r\n\t if(index == Store.currentSheetIndex){\r\n\t createFilterOptions(file.filter_select, file.filter);\r\n\t }\r\n\t }\r\n\t else if(type == \"sha\"){ //新建sheet\r\n\t Store.luckysheetfile.push(value);\r\n\r\n\t let colorset = '';\r\n\t if(value.color != null){\r\n\t colorset = '
';\r\n\t }\r\n\r\n\t $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, { \"index\": value.index, \"active\": \"\", \"name\": value.name, \"style\": \"\", \"colorset\": colorset }));\r\n\t $(\"#luckysheet-cell-main\").append('
');\r\n\t }\r\n\t else if(type == \"shc\"){ //复制sheet\r\n\t let copyindex = value.copyindex, name = value.name;\r\n\r\n\t let copyarrindex = getSheetIndex(copyindex);\r\n\t let copyjson = $.extend(true, {}, Store.luckysheetfile[copyarrindex]);\r\n\r\n\t copyjson.index = index;\r\n\t copyjson.name = name;\r\n\r\n\t Store.luckysheetfile.splice(copyarrindex + 1, 0, copyjson);\r\n\r\n\t let copyobject = $(\"#luckysheet-sheets-item\" + copyindex);\r\n\t $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, { \"index\": copyjson.index, \"active\": \"\", \"name\": copyjson.name, \"style\": \"\", \"colorset\": \"\" }));\r\n\t $(\"#luckysheet-sheets-item\" + copyjson.index).insertAfter(copyobject);\r\n\t $(\"#luckysheet-cell-main\").append('
');\r\n\t }\r\n\t else if(type == \"shd\"){ //删除sheet\r\n\t for(let i = 0; i < Store.luckysheetfile.length; i++){\r\n\t if(Store.luckysheetfile[i].index == value.deleIndex){\r\n\t \r\n\t\t\t\t\t// 如果删除的是当前sheet,则切换到前一个sheet页\r\n\t\t\t\t\tif(Store.currentSheetIndex === value.deleIndex){\r\n\t\t\t\t\t\tconst index = value.deleIndex;\r\n\r\n\t\t\t\t\t\tStore.luckysheetfile[sheetmanage.getSheetIndex(index)].hide = 1;\r\n \r\n\t\t\t\t\t\tlet luckysheetcurrentSheetitem = $(\"#luckysheet-sheets-item\" + index);\r\n\t\t\t\t\t\tluckysheetcurrentSheetitem.hide();\r\n\r\n\t\t\t\t\t\t$(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tlet indicator = luckysheetcurrentSheetitem.nextAll(\":visible\");\r\n\t\t\t\t\t\tif (luckysheetcurrentSheetitem.nextAll(\":visible\").length > 0) {\r\n\t\t\t\t\t\t\tindicator = indicator.eq(0).data(\"index\");\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\tindicator = luckysheetcurrentSheetitem.prevAll(\":visible\").eq(0).data(\"index\");\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t$(\"#luckysheet-sheets-item\" + indicator).addClass(\"luckysheet-sheets-item-active\");\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\tsheetmanage.changeSheetExec(indicator);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tserver.sheetDeleSave.push(Store.luckysheetfile[i]);\r\n\r\n\t\t\t\t\tStore.luckysheetfile.splice(i, 1);\r\n\r\n\t break;\r\n\t }\r\n\t }\r\n\r\n\t $(\"#luckysheet-sheets-item\" + value.deleIndex).remove();\r\n\t\t\t$(\"#luckysheet-datavisual-selection-set-\" + value.deleIndex).remove();\r\n\r\n\t }\r\n\t else if(type == \"shr\"){ //sheet位置\r\n\t for(let x in value){\r\n\t Store.luckysheetfile[getSheetIndex(x)].order = value[x];\r\n\t }\r\n\t }\r\n\t else if(type == \"shre\"){ //删除sheet恢复操作\r\n\t for(let i = 0; i < server.sheetDeleSave.length; i++){\r\n\t if(server.sheetDeleSave[i].index == value.reIndex){\r\n\t let datav = server.sheetDeleSave[i];\r\n\r\n\t Store.luckysheetfile.push(datav);\r\n\r\n\t let colorset = '';\r\n\t if(value.color != null){\r\n\t colorset = '
';\r\n\t }\r\n\r\n\t $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, { \"index\": datav.index, \"active\": \"\", \"name\": datav.name, \"style\": \"\", \"colorset\": colorset }));\r\n\t $(\"#luckysheet-cell-main\").append('
');\r\n\t break;\r\n\t }\r\n\t }\r\n\t }\r\n\t else if(type == \"sh\"){ //隐藏sheet\r\n\t let op = item.op, cur = item.cur;\r\n\r\n\t if(op == \"hide\"){\r\n\t file.hide = 1;\r\n\t $(\"#luckysheet-sheets-item\" + index).hide();\r\n\r\n\t if(index == Store.currentSheetIndex){\r\n\t $(\"#luckysheet-sheets-item\" + cur).addClass(\"luckysheet-sheets-item-active\");\r\n\t sheetmanage.changeSheetExec(cur);\r\n\t }\r\n\t }\r\n\t else if(op == \"show\"){\r\n\t file.hide = 0;\r\n\t $(\"#luckysheet-sheets-item\" + index).show();\r\n\t }\r\n\t }\r\n\t else if(type == \"c\"){ //图表操作 TODO\r\n\t let op = item.op, cid = item.cid;\r\n\r\n\t if(op == \"add\"){ //插入\r\n\t file.chart.push(value);\r\n\r\n\t luckysheet.insertChartTosheet(value.sheetIndex, value.dataSheetIndex, value.option, value.chartType, value.selfOption, value.defaultOption, value.row, value.column, value.chart_selection_color, value.chart_id, value.chart_selection_id, value.chartStyle, value.rangeConfigCheck, value.rangeRowCheck, value.rangeColCheck, value.chartMarkConfig, value.chartTitleConfig, value.winWidth, value.winHeight, value.scrollLeft1, value.scrollTop1, value.chartTheme, value.myWidth, value.myHeight, value.myLeft, value.myTop, value.myindexrank1, true);\r\n\t }\r\n\t else if(op == \"xy\" || op == \"wh\" || op == \"update\"){ //移动 缩放 更新\r\n\t for(let i = 0; i < file.chart.length; i++){\r\n\t let chartjson = file.chart[i];\r\n\r\n\t if(chartjson.chart_id == cid){\r\n\t for(let item in chartjson){\r\n\t for(let vitem in value){\r\n\t if(item == vitem){\r\n\t chartjson[item] = value[vitem];\r\n\t }\r\n\t }\r\n\t }\r\n\r\n\t sheetmanage.saveChart(chartjson);\r\n\r\n\t return;\r\n\t }\r\n\t }\r\n\t }\r\n\t else if(op == \"del\"){ //删除\r\n\t for(let i = 0; i < file.chart.length; i++){\r\n\t let chartjson = file.chart[i];\r\n\r\n\t if(chartjson.chart_id == cid){\r\n\t file.chart.splice(i, 1);\r\n\r\n\t $(\"#\" + cid).remove();\r\n\t sheetmanage.delChart($(\"#\" + cid).attr(\"chart_id\"), $(\"#\" + cid).attr(\"sheetIndex\"));\r\n\r\n\t return;\r\n\t }\r\n\t }\r\n\t }\r\n\t }\r\n\t else if(type == \"na\"){ //表格名称\r\n\t $(\"#luckysheet_info_detail_input\").val(value).css(\"width\", getByteLen(value) * 10);\r\n\t }\r\n\t},\r\n multipleIndex: 0,\r\n multipleRangeShow: function(id, name, r, c, value) {\r\n \tlet _this = this;\r\n\r\n\t let row = Store.visibledatarow[r],\r\n\t row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1],\r\n\t col = Store.visibledatacolumn[c],\r\n\t col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n\t let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n\t if(!!margeset){\r\n\t row = margeset.row[1];\r\n\t row_pre = margeset.row[0];\r\n\r\n\t col = margeset.column[1];\r\n\t col_pre = margeset.column[0];\r\n\t\t}\r\n\t\t\r\n\t\t// 超出16个字符就显示...\r\n\t\tif(getByteLen(name) > 16){\r\n\t\t\tname = getByteLen(name,16) + \"...\";\r\n\t\t}\r\n\t\t\r\n\t\t// 如果正在编辑,就显示“正在输入”\r\n\t\tif(value === 'enterEdit'){\r\n\t\t\tname += \" \" + locale().edit.typing;\r\n\t\t}\r\n\r\n\t if($(\"#luckysheet-multipleRange-show-\" + id).length > 0){\r\n\t\t\t$(\"#luckysheet-multipleRange-show-\" + id).css({ \"position\": \"absolute\", \"left\": col_pre - 1, \"width\": col - col_pre - 1, \"top\": row_pre - 1, \"height\": row - row_pre - 1 });\r\n\t\t\t\r\n\t\t\t$(\"#luckysheet-multipleRange-show-\" + id + \" .username\").text(name);\r\n\t\t\t$(\"#luckysheet-multipleRange-show-\" + id + \" .username\").show();\r\n\r\n\t\t\tif(Store.cooperativeEdit.usernameTimeout['user' + id] != null){\r\n\t\t\t\tclearTimeout(Store.cooperativeEdit.usernameTimeout['user' + id])\r\n\t\t\t}\r\n\t\t\tStore.cooperativeEdit.usernameTimeout['user' + id] = setTimeout(()=>{\r\n\t\t\t\tclearTimeout(Store.cooperativeEdit.usernameTimeout['user' + id]);\r\n\t\t\t\tStore.cooperativeEdit.usernameTimeout['user' + id] = null;\r\n\t\t\t},10 * 1000)\r\n\r\n\r\n\r\n\t }\r\n\t else{\r\n\t // let itemHtml = '
'+\r\n\t // '
'+\r\n\t\t\t// '
';\r\n\r\n\t\t\tlet itemHtml = `
\r\n\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t${name}\r\n\t\t\t\t\t\t\t\t
\r\n\r\n\t\t\t\t\t\t\t\t
\r\n\t\t\t\t\t\t\t\t
\r\n\r\n\t\t\t\t\t\t\t
`;\r\n\t\t\t\t\t\t\t// 正在输入\r\n\r\n\t $(itemHtml).appendTo($(\"#luckysheet-cell-main #luckysheet-multipleRange-show\"));\r\n\r\n\t\t\t_this.multipleIndex++;\r\n\t\t\t\r\n\t\t\t// 设定允许用户名消失的定时器,10秒后用户名可隐藏\r\n\t\t\t// 10秒之类,用户操作界面不会隐藏用户名;10秒之后如果用户操作了界面,则隐藏用户名,没操作就不隐藏\r\n\t\t\tif(Store.cooperativeEdit.usernameTimeout['user' + id] != null){\r\n\t\t\t\tclearTimeout(Store.cooperativeEdit.usernameTimeout['user' + id])\r\n\t\t\t}\r\n\t\t\tStore.cooperativeEdit.usernameTimeout['user' + id] = setTimeout(()=>{\r\n\t\t\t\tclearTimeout(Store.cooperativeEdit.usernameTimeout['user' + id]);\r\n\t\t\t\tStore.cooperativeEdit.usernameTimeout['user' + id] = null;\r\n\t\t\t},10 * 1000)\r\n\t }\r\n\t},\r\n sheetDeleSave: [], //共享编辑模式下 删除的sheet保存下来,方便恢复时取值\r\n submitInterval: 1000,\r\n imagesubmitInterval: 5000,\r\n submitdatalimit: 50,\r\n submitcompresslimit: 1000,\r\n checksubmit: function(data){\r\n let _this = this;\r\n //clearTimeout(_this.requestTimeOut);\r\n\r\n _this.submitTimeout();\r\n\r\n clearTimeout(_this.imageRequestTimeout);\r\n _this.imageRequestTimeout = setTimeout(function(){\r\n _this.imageRequest();\r\n }, _this.imagesubmitInterval);\r\n },\r\n submitTimeout: function(){\r\n let _this = this;\r\n clearTimeout(_this.requestTimeOut);\r\n\r\n //console.log(_this.requestlast, dayjs(), (_this.requestlast!=null && _this.requestlast.add(10, 'seconds').isBefore(dayjs()) ) );\r\n if(!_this.requestLock && (_this.requestlast!=null && _this.requestlast.clone().add(1, 'seconds').isBefore(dayjs()) ) ){\r\n _this.request();\r\n }\r\n\r\n // if(!_this.imageRequestLock && (_this.imageRequestLast==null || _this.imageRequestLast.clone().add(30, 'seconds').isBefore(dayjs()) ) ){\r\n\r\n // }\r\n\r\n _this.requestTimeOut = setTimeout(function(){\r\n _this.submitTimeout();\r\n }, _this.submitInterval);\r\n },\r\n requestLock: false,\r\n requestlast: null,\r\n firstchange: true,\r\n requestTimeOut: null,\r\n request: function () {\r\n let _this = this;\r\n let key = this.gridKey;\r\n let cahce_key = key + \"__qkcache\";\r\n\r\n _this.cachelocaldata(function(cahce_key, params){\r\n if(params.length==0){\r\n return;\r\n }\r\n\r\n params = encodeURIComponent(JSON.stringify(params));\r\n let compressBeginLen = params.length;\r\n let iscommpress = false;\r\n // if (compressBeginLen > _this.submitcompresslimit) {\r\n // params = pako.gzip(params, { to: \"string\" });\r\n // iscommpress = true;\r\n // }\r\n _this.requestLock = true;\r\n //console.log(params);\r\n // console.log(\"request\");\r\n if(_this.updateUrl != \"\"){\r\n $.post(_this.updateUrl, { compress: iscommpress, gridKey: _this.gridKey, data: params }, function (data) {\r\n\t\t\t\t\tlet re = new Function(\"return \" + data)();\r\n if(re.status){\r\n $(\"#luckysheet_info_detail_update\").html(\"最近存档时间:\"+ dayjs().format(\"M-D H:m:s\"));\r\n $(\"#luckysheet_info_detail_save\").html(\"同步成功\");\r\n _this.clearcachelocaldata();\r\n }\r\n else{\r\n $(\"#luckysheet_info_detail_save\").html(\"同步失败\");\r\n _this.restorecachelocaldata();\r\n }\r\n _this.requestlast = dayjs();\r\n _this.requestLock = false;\r\n });\r\n }\r\n });\r\n },\r\n imageRequestLast: null,\r\n imageRequestLock: false,\r\n imageRequestTimeout: null,\r\n imageRequest: function(){\r\n let _this = this;\r\n\r\n html2canvas($(\"#\" + container).find(\".luckysheet-grid-window\").get(0), {\r\n onrendered: function(canvas) {\r\n //let imgcut = $(\"#luckysheet-cell-main\").find(\".luckysheet-grid-window\");\r\n //document.body.appendChild(canvas);\r\n let old = $(canvas).appendTo(\"body\");\r\n old.hide();\r\n let newwidth = old.width();\r\n let newheight = old.height();\r\n let imageData = old.get(0).getContext(\"2d\").getImageData(0, 0, newwidth, newheight);\r\n\r\n let cutW = newwidth, cutH = newheight;\r\n if(cutW*0.54 > cutH){\r\n cutW = cutH / 0.54;\r\n }\r\n else{\r\n cutH = cutW * 0.54;\r\n }\r\n let newCanvas = $(\"\").attr(\"width\", cutW).attr(\"height\", cutH)[0];\r\n\r\n newCanvas.getContext(\"2d\").putImageData(imageData, 0, 0);\r\n\r\n old.attr(\"width\", 350);\r\n old.attr(\"height\", 189);\r\n old.get(0).getContext(\"2d\").drawImage(newCanvas, 0, 0, 350, 189);\r\n let base64 = old.get(0).toDataURL('image/jpeg', 0.9);\r\n\r\n //console.log(base64);\r\n //console.log(\"压缩:\", pako.gzip(base64, { to: \"string\" }));\r\n //console.log(\"imageRequest\");\r\n let curindex = luckysheet.sheetmanage.getCurSheetnoset();\r\n _this.imageRequestLock =true;\r\n // let data1 = pako.gzip(encodeURIComponent(JSON.stringify({\"t\":\"thumb\", \"img\": base64, \"curindex\":curindex })), { to: \"string\" });\r\n let data1 = encodeURIComponent(JSON.stringify({\"t\":\"thumb\", \"img\": base64, \"curindex\":curindex }));\r\n old.remove();\r\n //console.log(\"缩略图\", _this.imageRequestLast,base64);\r\n if(_this.updateImageUrl != \"\"){\r\n // $.post(_this.updateImageUrl, { compress: true, gridKey: _this.gridKey, data:data1 }, function (data) {\r\n $.post(_this.updateImageUrl, { compress: false, gridKey: _this.gridKey, data:data1 }, function (data) {\r\n\t\t\t\t\tlet re = new Function(\"return \" + data)();\r\n if(re.status){\r\n imageRequestLast = dayjs();\r\n }\r\n else{\r\n $(\"#luckysheet_info_detail_save\").html(\"网络不稳定\");\r\n }\r\n _this.imageRequestLock =true;\r\n });\r\n }\r\n\r\n }\r\n });\r\n },\r\n localdata: [],\r\n matchOpt: function(v, d){\r\n for(let vitem in v){\r\n if(vitem == \"t\" && v[\"t\"] in {\"drc\":1, \"arc\":1,\"sha\":1,\"shc\":1,\"shd\":1 } ){\r\n return false;\r\n }\r\n\r\n if(vitem==\"v\"){\r\n continue;\r\n }\r\n\r\n if(!(vitem in d)){\r\n return false;\r\n }\r\n\r\n if(d[vitem] != v[vitem]){\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n deleteRepeatOpt: function(data, value){\r\n //let d = $.extend(true, [], data); //原来\r\n let d = data;\r\n let _this = this;\r\n\r\n if(value instanceof Array){\r\n for(let i = 0; i < value.length; i++){\r\n let vitem = value[i];\r\n\r\n for(let a = 0; a < d.length; a++){\r\n let ditem = data[i]; //let ditem = data[a];?\r\n\r\n if(_this.matchOpt(vitem, ditem)){\r\n delete d[a];\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n for(let a = 0; a < d.length; a++){\r\n let ditem = d[a];\r\n\r\n if(_this.matchOpt(value, ditem)){\r\n delete d[a];\r\n }\r\n }\r\n }\r\n\r\n let ret = [];\r\n for(let i = 0; i < d.length; i++){\r\n if(d[i] != null){\r\n ret.push(d[i]);\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n setlocaldata: function (value, func) {\r\n let key = this.gridKey;\r\n //store.push(key, data);\r\n let _this = this;\r\n _this.getlocaldata(function(data){\r\n if(data==null){\r\n data = [];\r\n }\r\n\r\n //此处不去重,在request同步后台时统一循环一次去重\r\n //let data = _this.deleteRepeatOpt(data, value);\r\n\r\n if(value instanceof Array){\r\n data = data.concat(value);\r\n }\r\n else{\r\n data.push(value);\r\n }\r\n\r\n _this.localdata = data;\r\n func(_this.localdata);\r\n\r\n //console.log(value);\r\n // localforage.setItem(key, data).then(function () {\r\n // console.log(data);\r\n // func(data);\r\n // }).catch(function (err) {\r\n\r\n // });\r\n });\r\n },\r\n getlocaldata: function (func) {\r\n let key = this.gridKey;\r\n //return store.get(key);\r\n func(this.localdata);\r\n // localforage.getItem(key).then(function(readValue) {\r\n // func(readValue);\r\n // });\r\n },\r\n clearlocaldata: function (func) {\r\n let key = this.gridKey;\r\n //store.remove(key);\r\n this.localdata = [];\r\n func();\r\n // localforage.removeItem(key, function(err,value) {\r\n // func();\r\n // });\r\n },\r\n cachelocaldata: function (func) {\r\n let key = this.gridKey;\r\n let _this = this;\r\n let cahce_key = key + \"__qkcache\";\r\n //store.remove(key);\r\n //console.log(key, cahce_key);\r\n\r\n\r\n //处理localdata去重\r\n let updatedata = _this.localdata;\r\n let uLen = updatedata.length;\r\n if(uLen > 1){\r\n let prevData = [];\r\n prevData[0] = updatedata[0];\r\n for(let i = 1; i < uLen; i++){\r\n let value = updatedata[i];\r\n let flag = true;\r\n for(let a=0;a {\r\n if(value.index == Store.currentSheetIndex) {\r\n if(value.op === 'enterEdit') {\r\n server.multipleRangeShow(value.id, value.username, value.r, value.c, value.op);\r\n } else {\r\n server.multipleRangeShow(value.id, value.username, value.r, value.c);\r\n }\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default server;\r\n","import { modelHTML, luckysheetchartpointconfigHTML, luckysheetToolHTML } from '../controllers/constant';\r\nimport browser from './browser';\r\nimport { replaceHtml } from '../utils/util';\r\nimport locale from '../locale/locale';\r\nimport server from '../controllers/server';\r\n\r\nconst tooltip = {\r\n info: function (title, content) {\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-info\").remove();\r\n\r\n let _locale = locale();\r\n let locale_button = _locale.button;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-info\", \r\n \"addclass\": \"\", \r\n \"title\": title, \r\n \"content\": content, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-info\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 300).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-info\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n },\r\n confirm: function (title, content, func1, func2, name1, name2) {\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-confirm\").remove();\r\n\r\n const _locale = locale();\r\n const locale_button = _locale.button;\r\n \r\n if(name1 == null){\r\n name1 = locale_button.confirm;\r\n }\r\n if(name2 == null){\r\n name2 = locale_button.cancel;\r\n }\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-confirm\", \r\n \"addclass\": \"\", \r\n \"style\": \"z-index:100003\", \r\n \"title\": title, \r\n \"content\": content, \r\n \"botton\": '' \r\n }));\r\n let $t = $(\"#luckysheet-confirm\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 300).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-confirm\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n $t.find(\".luckysheet-model-conform-btn\").click(function () {\r\n if (typeof func1 == 'function') {\r\n func1();\r\n }\r\n server.keepHighLightBox();\r\n $(\"#luckysheet-confirm\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide(); \r\n });\r\n $t.find(\".luckysheet-model-cancel-btn\").click(function () {\r\n if (typeof func2 == 'function') {\r\n func2();\r\n }\r\n $(\"#luckysheet-confirm\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n });\r\n },\r\n screenshot: function (title, content, imgurl) {\r\n\r\n const _locale = locale();\r\n const locale_screenshot = _locale.screenshot;\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-confirm\").remove();\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-confirm\", \r\n \"addclass\": \"\", \r\n \"style\": \"z-index:100003\", \r\n \"title\": title, \r\n \"content\": content, \r\n \"botton\": '
  '+ locale_screenshot.downLoadBtn +'    ' \r\n }));\r\n let $t = $(\"#luckysheet-confirm\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 300).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-confirm\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n $t.find(\".luckysheet-model-conform-btn\").click(function () {\r\n if(browser.isIE() == \"1\"){\r\n alert(locale_screenshot.browserNotTip);\r\n }\r\n else{\r\n if (!!window.ActiveXObject || \"ActiveXObject\" in window){\r\n if ($(\"#IframeReportImg\").length === 0){\r\n $('').appendTo(\"body\");\r\n }\r\n if ($('#IframeReportImg').attr(\"src\") != imgurl) {\r\n $('#IframeReportImg').attr(\"src\",imgurl);\r\n } else {\r\n if ($('#IframeReportImg').src != \"about:blank\") {\r\n window.frames[\"IframeReportImg\"].document.execCommand(\"SaveAs\");\r\n }\r\n }\r\n } \r\n }\r\n });\r\n $t.find(\".luckysheet-model-cancel-btn\").click(function () {\r\n $(\"#luckysheet-confirm\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n });\r\n\r\n $('#luckysheet-confirm .luckysheet-model-copy-btn').click(function(){\r\n let dt = new clipboard.DT();\r\n dt.setData(\"text/html\", \"\");\r\n if(browser.isIE() == \"1\"){\r\n alert(locale_screenshot.rightclickTip);\r\n }\r\n else{\r\n clipboard.write(dt);\r\n alert(locale_screenshot.successTip); \r\n }\r\n });\r\n },\r\n chartPointConfig: function (id, savefunc1, closefunc2) {\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": id, \r\n \"addclass\": \"luckysheet-chart-point-config-c\", \r\n \"title\": \"数据点批量设置\", \r\n \"content\": luckysheetchartpointconfigHTML, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003;height:80%;width:80%;top:10%;left:10%;\" \r\n }));\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n let winw = $(window).width(), winh = $(window).height();\r\n $(\"#\" + id).find(\".luckysheet-chart-point-config\").css(\"height\", winh - 160);\r\n $(\"#\" + id).css({ \r\n \"height\": winh - 90, \r\n \"width\": winw - 100, \r\n \"left\": 7, \r\n \"top\": 14 \r\n }).show().find(\".luckysheet-model-save-btn\").click(function () {\r\n if (typeof savefunc1 == 'function') {\r\n savefunc1();\r\n }\r\n\r\n $(\"#\" + id).hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n });\r\n\r\n $(\"#\" + id).find(\".luckysheet-model-save-btn\").click(function () {\r\n if (typeof closefunc2 == 'function') {\r\n closefunc2();\r\n }\r\n\r\n $(\"#\" + id).hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n });\r\n },\r\n sheetConfig: function () {\r\n\r\n },\r\n hoverTipshowState: false,\r\n hoverTipshowTimeOut: null,\r\n createHoverTip: function (obj, to) {\r\n let _this = this;\r\n\r\n $(obj).on(\"mouseover\", to, function (e) {\r\n if (_this.hoverTipshowState) {\r\n return;\r\n }\r\n\r\n clearTimeout(_this.hoverTipshowTimeOut);\r\n _this.hoverTipshowTimeOut = setTimeout(function(){\r\n let $t = $(e.currentTarget), \r\n toffset = $t.offset(), \r\n $toolup = $(\"#luckysheet-tooltip-up\");\r\n \r\n let tips = $t.data(\"tips\");\r\n if (tips == null || tips.length == 0) {\r\n tips = $t.prev().data(\"tips\");\r\n\r\n if (tips == null || tips.length == 0) {\r\n return;\r\n }\r\n }\r\n\r\n if ($toolup.length == 0) {\r\n $(\"body\").append(luckysheetToolHTML);\r\n $toolup = $(\"#luckysheet-tooltip-up\");\r\n }\r\n\r\n $toolup.removeClass(\"jfk-tooltip-hide\").find(\"div.jfk-tooltip-contentId\").html(tips);\r\n let toolwidth = $toolup.outerWidth();\r\n $toolup.find(\"div.jfk-tooltip-arrow\").css(\"left\", (toolwidth) / 2);\r\n\r\n let toolleft = toffset.left + ($t.outerWidth() - toolwidth) / 2;\r\n if(toolleft < 2){\r\n toolleft = 2;\r\n $toolup.find(\"div.jfk-tooltip-arrow\").css(\"left\", $t.outerWidth() / 2);\r\n }\r\n\r\n $toolup.css({ \"top\": toffset.top + $t.outerHeight() + 1, \"left\": toolleft });\r\n }, 300);\r\n\r\n }).on(\"mouseout\", to, function (e) {\r\n _this.hoverTipshowState = false;\r\n clearTimeout(_this.hoverTipshowTimeOut);\r\n $(\"#luckysheet-tooltip-up\").addClass(\"jfk-tooltip-hide\");\r\n }).on(\"click\", to, function (e) {\r\n _this.hoverTipshowState = true;\r\n clearTimeout(_this.hoverTipshowTimeOut);\r\n $(\"#luckysheet-tooltip-up\").addClass(\"jfk-tooltip-hide\");\r\n });\r\n },\r\n popover: function(content, position, close, style, btntxt, exitsFuc){\r\n let _locale = locale();\r\n let locale_button = _locale.button;\r\n let locale_paint = _locale.paint;\r\n\r\n if(btntxt == null){\r\n btntxt = locale_button.close;\r\n }\r\n\r\n let htmldiv = '
'+locale_paint.start+'
'+ btntxt +'
';\r\n $(\"#luckysheetpopover\").remove();\r\n $(\"body\").append(htmldiv);\r\n $(\"#luckysheetpopover .luckysheetpopover-content\").html(content);\r\n\r\n let w = $(\"#luckysheetpopover\").outerWidth(),\r\n h = $(\"#luckysheetpopover\").outerHeight();\r\n let pcss = {};\r\n\r\n if(position == 'topLeft'){\r\n pcss.top = \"20px\";\r\n pcss.left = \"20px\";\r\n }\r\n else if(position == 'topCenter'){\r\n pcss.top = \"20px\";\r\n pcss.left = \"50%\";\r\n pcss[\"margin-left\"] = -w/2;\r\n }\r\n else if(position == 'topRight'){\r\n pcss.top = \"20px\";\r\n pcss.right = \"20px\";\r\n }\r\n else if(position == 'midLeft'){\r\n pcss.top = \"50%\";\r\n pcss[\"margin-top\"] = -h/2;\r\n pcss.left = \"20px\";\r\n }\r\n else if(position == 'center'){\r\n pcss.top = \"50%\";\r\n pcss[\"margin-top\"] = -h/2;\r\n pcss.left = \"50%\";\r\n pcss[\"margin-left\"] = -w/2;\r\n }\r\n else if(position == 'midRight'){\r\n pcss.top = \"50%\";\r\n pcss[\"margin-top\"] = -h/2;\r\n pcss.right = \"20px\";\r\n }\r\n else if(position == 'bottomLeft'){\r\n pcss.bottom = \"20px\";\r\n pcss.left = \"20px\";\r\n }\r\n else if(position == 'bottomCenter'){\r\n pcss.bottom = \"20px\";\r\n pcss.left = \"50%\";\r\n pcss[\"margin-left\"] = -w/2;\r\n }\r\n else if(position == 'bottomRight'){\r\n pcss.bottom = \"20px\";\r\n pcss.right = \"20px\";\r\n }\r\n else{\r\n pcss.top = \"20px\";\r\n pcss.left = \"50%\";\r\n pcss[\"margin-left\"] = -w/2;\r\n }\r\n\r\n if(style == \"white\"){\r\n pcss.background = \"rgba(255, 255, 255, 0.65)\";\r\n pcss.color = \"#000\";\r\n $(\"#luckysheetpopover .luckysheetpopover-btn\").css({\"border\": \"1px solid #000\"});\r\n }\r\n\r\n setTimeout(function(){\r\n $(\"#luckysheetpopover .luckysheetpopover-content\").css({\"margin-left\": -$(\"#luckysheetpopover .luckysheetpopover-btn\").outerWidth()/2});\r\n }, 1);\r\n $(\"#luckysheetpopover\").css(pcss).fadeIn();\r\n $(\"#luckysheetpopover .luckysheetpopover-btn\").click(function(){\r\n if(typeof(exitsFuc) == \"function\"){\r\n exitsFuc();\r\n }\r\n });\r\n\r\n if(close != null && typeof(close) == \"number\"){\r\n setTimeout(function(){\r\n $(\"#luckysheetpopover\").fadeOut().remove();\r\n if(typeof(exitsFuc) == \"function\"){\r\n exitsFuc();\r\n }\r\n }, close);\r\n }\r\n }\r\n}\r\n\r\nexport default tooltip;","import { getSheetIndex, getRangetxt } from '../methods/get';\r\nimport { replaceHtml, getObjType, chatatABC } from '../utils/util';\r\nimport formula from '../global/formula';\r\nimport { isRealNull, isEditMode } from '../global/validate';\r\nimport tooltip from '../global/tooltip';\r\nimport { luckysheetrefreshgrid } from '../global/refresh';\r\nimport { getcellvalue } from '../global/getdata';\r\nimport { genarate } from '../global/format';\r\nimport { modelHTML, luckysheet_CFiconsImg } from './constant';\r\nimport server from './server';\r\nimport { selectionCopyShow } from './select';\r\nimport sheetmanage from './sheetmanage';\r\nimport locale from '../locale/locale';\r\nimport {checkProtectionFormatCells} from './protection';\r\nimport Store from '../store';\r\nimport dayjs from 'dayjs'\r\n\r\n//条件格式\r\nconst conditionformat = {\r\n fileClone: [],\r\n editorRule: null, //{\"sheetIndex\": sheetIndex,\"itemIndex\": itemIndex,\"data\": luckysheetfile[sheetIndex].luckysheet_conditionformat_save[itemIndex]}\r\n ruleTypeHtml: function(){\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n return `
\r\n
\r\n \r\n ${conditionformat_Text.ruleTypeItem1}\r\n
\r\n
\r\n \r\n ${conditionformat_Text.ruleTypeItem2}\r\n
\r\n
\r\n \r\n ${conditionformat_Text.ruleTypeItem3}\r\n
\r\n
\r\n \r\n ${conditionformat_Text.ruleTypeItem4}\r\n
\r\n
\r\n \r\n ${conditionformat_Text.ruleTypeItem5}\r\n
\r\n
\r\n \r\n ${conditionformat_Text.ruleTypeItem6}\r\n
\r\n
`;\r\n },\r\n textCellColorHtml: function(){\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n return `
\r\n
\r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n \r\n
\r\n
`;\r\n },\r\n selectRange: [],\r\n selectStatus: false,\r\n dataBarList: [\r\n { \"format\": [\"#638ec6\", \"#ffffff\"] }, //蓝-白渐变 数据条\r\n { \"format\": [\"#63c384\", \"#ffffff\"] }, //绿-白渐变 数据条\r\n { \"format\": [\"#ff555a\", \"#ffffff\"] }, //红-白渐变 数据条\r\n { \"format\": [\"#ffb628\", \"#ffffff\"] }, //橙-白渐变 数据条\r\n { \"format\": [\"#008aef\", \"#ffffff\"] }, //浅蓝-白渐变 数据条\r\n { \"format\": [\"#d6007b\", \"#ffffff\"] }, //紫-白渐变 数据条\r\n\r\n { \"format\": [\"#638ec6\"] }, //蓝色 数据条\r\n { \"format\": [\"#63c384\"] }, //绿色 数据条\r\n { \"format\": [\"#ff555a\"] }, //红色 数据条\r\n { \"format\": [\"#ffb628\"] }, //橙色 数据条\r\n { \"format\": [\"#008aef\"] }, //浅蓝色 数据条\r\n { \"format\": [\"#d6007b\"] } //紫色 数据条\r\n ],\r\n colorGradationList: [\r\n { \"format\": [\"rgb(99, 190, 123)\", \"rgb(255, 235, 132)\", \"rgb(248, 105, 107)\"] }, //绿-黄-红色阶\r\n { \"format\": [\"rgb(248, 105, 107)\", \"rgb(255, 235, 132)\", \"rgb(99, 190, 123)\"] }, //红-黄-绿色阶\r\n\r\n { \"format\": [\"rgb(99, 190, 123)\", \"rgb(252, 252, 255)\", \"rgb(248, 105, 107)\"] }, //绿-白-红色阶\r\n { \"format\": [\"rgb(248, 105, 107)\", \"rgb(252, 252, 255)\", \"rgb(99, 190, 123)\"] }, //红-白-绿色阶\r\n\r\n { \"format\": [\"rgb(90, 138, 198)\", \"rgb(252, 252, 255)\", \"rgb(248, 105, 107)\"] }, //蓝-白-红色阶\r\n { \"format\": [\"rgb(248, 105, 107)\", \"rgb(252, 252, 255)\", \"rgb(90, 138, 198)\"] }, //红-白-蓝色阶\r\n\r\n { \"format\": [\"rgb(252, 252, 255)\", \"rgb(248, 105, 107)\"] }, //白-红色阶\r\n { \"format\": [\"rgb(248, 105, 107)\", \"rgb(252, 252, 255)\"] }, //红-白色阶\r\n\r\n { \"format\": [\"rgb(99, 190, 123)\", \"rgb(252, 252, 255)\"] }, //绿-白色阶\r\n { \"format\": [\"rgb(252, 252, 255)\", \"rgb(99, 190, 123)\"] }, //白-绿色阶\r\n\r\n { \"format\": [\"rgb(99, 190, 123)\", \"rgb(255, 235, 132)\"] }, //绿-黄色阶\r\n { \"format\": [\"rgb(255, 235, 132)\", \"rgb(99, 190, 123)\"] } //黄-绿色阶\r\n ],\r\n init: function(){\r\n let _this = this;\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n // 管理规则\r\n $(document).off(\"change.CFchooseSheet\").on(\"change.CFchooseSheet\", \"#luckysheet-administerRule-dialog .chooseSheet\", function(){\r\n let index = $(\"#luckysheet-administerRule-dialog .chooseSheet option:selected\").val();\r\n _this.getConditionRuleList(index);\r\n });\r\n $(document).off(\"click.CFadministerRuleItem\").on(\"click.CFadministerRuleItem\", \"#luckysheet-administerRule-dialog .ruleList .listBox .item\", function(){\r\n $(this).addClass(\"on\").siblings().removeClass(\"on\");\r\n });\r\n\r\n $(document).off(\"click.CFadministerRuleConfirm\").on(\"click.CFadministerRuleConfirm\", \"#luckysheet-administerRule-dialog-confirm\", function(){\r\n if(!checkProtectionFormatCells(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n //保存之前的规则\r\n let fileH = $.extend(true, [], Store.luckysheetfile);\r\n let historyRules = _this.getHistoryRules(fileH);\r\n\r\n //保存当前的规则\r\n let fileClone = $.extend(true, [], _this.fileClone);\r\n for(let c = 0; c < fileClone.length; c++){\r\n let sheetIndex = fileClone[c][\"index\"];\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"] = fileClone[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"];\r\n }\r\n\r\n let fileC = $.extend(true, [], Store.luckysheetfile);\r\n let currentRules = _this.getCurrentRules(fileC);\r\n\r\n //刷新一次表格\r\n _this.ref(historyRules, currentRules);\r\n\r\n //隐藏一些dom\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-administerRule-dialog\").hide();\r\n\r\n //发送给后台\r\n if(server.allowUpdate){\r\n let files = $.extend(true, [], Store.luckysheetfile);\r\n for(let i = 0; i < files.length; i++){\r\n server.saveParam(\"all\", files[i][\"index\"], files[i][\"luckysheet_conditionformat_save\"], { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n }\r\n });\r\n\r\n $(document).off(\"click.CFadministerRuleClose\").on(\"click.CFadministerRuleClose\", \"#luckysheet-administerRule-dialog-close\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-administerRule-dialog\").hide();\r\n _this.fileClone = [];\r\n });\r\n $(document).off(\"click.CFadministerRuleFa\").on(\"click.CFadministerRuleFa\", \"#luckysheet-administerRule-dialog .item .fa-table\", function(){\r\n $(this).parents(\"#luckysheet-administerRule-dialog\").hide();\r\n\r\n let sheetIndex = $(\"#luckysheet-administerRule-dialog .chooseSheet select option:selected\").val();\r\n if(sheetIndex != Store.currentSheetIndex){\r\n sheetmanage.changeSheetExec(sheetIndex);\r\n }\r\n\r\n let txt = $(this).siblings(\"input\").val().trim();\r\n let dataItem = $(this).parents(\".item\").attr(\"data-item\");\r\n\r\n _this.multiRangeDialog(dataItem, txt);\r\n\r\n _this.selectRange = [];\r\n\r\n let range = _this.getRangeByTxt(txt);\r\n if(range.length > 0){\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n let row = Store.visibledatarow[r2],\r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2],\r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n _this.selectRange.push({\r\n \"left\": col_pre,\r\n \"width\": col - col_pre - 1,\r\n \"top\": row_pre,\r\n \"height\": row - row_pre - 1,\r\n \"left_move\": col_pre,\r\n \"width_move\": col - col_pre - 1,\r\n \"top_move\": row_pre,\r\n \"height_move\": row - row_pre - 1,\r\n \"row\": [r1, r2],\r\n \"column\": [c1, c2],\r\n \"row_focus\": r1,\r\n \"column_focus\": c1\r\n });\r\n }\r\n }\r\n\r\n selectionCopyShow(_this.selectRange);\r\n });\r\n $(document).off(\"click.CFmultiRangeConfirm\").on(\"click.CFmultiRangeConfirm\", \"#luckysheet-multiRange-dialog-confirm\", function(){\r\n $(this).parents(\"#luckysheet-multiRange-dialog\").hide();\r\n\r\n let dataItem = $(this).attr(\"data-item\");\r\n let v = $(this).parents(\"#luckysheet-multiRange-dialog\").find(\"input\").val();\r\n $(\"#luckysheet-administerRule-dialog .item[data-item=\"+dataItem+\"] input\").val(v);\r\n\r\n let sheetIndex = $(\"#luckysheet-administerRule-dialog .chooseSheet option:selected\").val();\r\n _this.fileClone[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"][dataItem].cellrange = _this.getRangeByTxt(v);\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-administerRule-dialog\").show();\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n $(document).off(\"click.CFmultiRangeClose\").on(\"click.CFmultiRangeClose\", \"#luckysheet-multiRange-dialog-close\", function(){\r\n $(this).parents(\"#luckysheet-multiRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-administerRule-dialog\").show();\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n\r\n // 新建规则\r\n $(document).off(\"click.CFnewConditionRule\").on(\"click.CFnewConditionRule\", \"#newConditionRule\", function(){\r\n let sheetIndex = $(\"#luckysheet-administerRule-dialog .chooseSheet option:selected\").val();\r\n if(!checkProtectionFormatCells(sheetIndex)){\r\n return;\r\n }\r\n\r\n if(Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(conditionformat_Text.pleaseSelectRange);\r\n }\r\n else{\r\n tooltip.info(conditionformat_Text.pleaseSelectRange, \"\");\r\n }\r\n return;\r\n }\r\n\r\n _this.newConditionRuleDialog(1);\r\n });\r\n $(document).off(\"click.CFnewConditionRuleConfirm\").on(\"click.CFnewConditionRuleConfirm\", \"#luckysheet-newConditionRule-dialog-confirm\", function(){\r\n\r\n if(!checkProtectionFormatCells(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n let index = $(\"#luckysheet-newConditionRule-dialog .ruleTypeItem.on\").index();\r\n let type1 = $(\"#luckysheet-newConditionRule-dialog #type1 option:selected\").val();\r\n let type2 = $(\"#luckysheet-newConditionRule-dialog .\" + type1 + \"Box #type2 option:selected\").val();\r\n\r\n let format, rule;\r\n if(index == 0){\r\n if(type1 == \"dataBar\"){ //数据条\r\n let color = $(this).parents(\"#luckysheet-newConditionRule-dialog\").find(\".dataBarBox .luckysheet-conditionformat-config-color\").spectrum(\"get\").toHexString();\r\n\r\n if(type2 == \"gradient\"){ //渐变填充\r\n format = [color, \"#ffffff\"];\r\n }\r\n else if(type2 == \"solid\"){ //实心填充\r\n format = [color];\r\n }\r\n\r\n rule = {\r\n \"type\": \"dataBar\",\r\n \"cellrange\": $.extend(true, [], Store.luckysheet_select_save),\r\n \"format\": format\r\n };\r\n }\r\n else if(type1 == \"colorGradation\"){ //色阶\r\n let maxcolor = $(this).parents(\"#luckysheet-newConditionRule-dialog\").find(\".colorGradationBox .maxVal .luckysheet-conditionformat-config-color\").spectrum(\"get\").toRgbString();\r\n let midcolor = $(this).parents(\"#luckysheet-newConditionRule-dialog\").find(\".colorGradationBox .midVal .luckysheet-conditionformat-config-color\").spectrum(\"get\").toRgbString();\r\n let mincolor = $(this).parents(\"#luckysheet-newConditionRule-dialog\").find(\".colorGradationBox .minVal .luckysheet-conditionformat-config-color\").spectrum(\"get\").toRgbString();\r\n\r\n if(type2 == \"threeColor\"){ //三色\r\n format = [maxcolor, midcolor, mincolor];\r\n }\r\n else if(type2 == \"twoColor\"){ //双色\r\n format = [maxcolor, mincolor];\r\n }\r\n\r\n rule = {\r\n \"type\": \"colorGradation\",\r\n \"cellrange\": $.extend(true, [], Store.luckysheet_select_save),\r\n \"format\": format\r\n };\r\n }\r\n else if(type1 == \"icons\"){ //图标集\r\n let len = $(this).parents(\"#luckysheet-newConditionRule-dialog\").find(\".iconsBox .model\").attr(\"data-len\");\r\n let leftMin = $(this).parents(\"#luckysheet-newConditionRule-dialog\").find(\".iconsBox .model\").attr(\"data-leftmin\");\r\n let top = $(this).parents(\"#luckysheet-newConditionRule-dialog\").find(\".iconsBox .model\").attr(\"data-top\");\r\n\r\n format = {\r\n \"len\": len,\r\n \"leftMin\": leftMin,\r\n \"top\": top\r\n };\r\n\r\n rule = {\r\n \"type\": \"icons\",\r\n \"cellrange\": $.extend(true, [], Store.luckysheet_select_save),\r\n \"format\": format\r\n };\r\n }\r\n }\r\n else{\r\n let conditionName = \"\", conditionRange = [], conditionValue = [];\r\n\r\n if(index == 1){\r\n if(type1 == \"number\"){ //单元格值\r\n conditionName = type2;\r\n\r\n if(type2 == \"betweenness\"){\r\n let v1 = $(\"#luckysheet-newConditionRule-dialog #conditionVal input\").val().trim();\r\n let v2 = $(\"#luckysheet-newConditionRule-dialog #conditionVal2 input\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr1 = _this.getRangeByTxt(v1);\r\n if(rangeArr1.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr1.length == 1){\r\n let r1 = rangeArr1[0].row[0], r2 = rangeArr1[0].row[1];\r\n let c1 = rangeArr1[0].column[0], c2 = rangeArr1[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v1 = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr1[0].row, \"column\": rangeArr1[0].column });\r\n conditionValue.push(v1);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr1.length == 0){\r\n if(isNaN(v1) || v1 == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v1);\r\n }\r\n }\r\n\r\n let rangeArr2 = _this.getRangeByTxt(v2);\r\n if(rangeArr2.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr2.length == 1){\r\n let r1 = rangeArr2[0].row[0], r2 = rangeArr2[0].row[1];\r\n let c1 = rangeArr2[0].column[0], c2 = rangeArr2[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v2 = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr2[0].row, \"column\": rangeArr2[0].column });\r\n conditionValue.push(v2);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr2.length == 0){\r\n if(isNaN(v2) || v2 == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v2);\r\n }\r\n }\r\n }\r\n else{\r\n //条件值\r\n let v = $(\"#luckysheet-newConditionRule-dialog #conditionVal input\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr = _this.getRangeByTxt(v);\r\n if(rangeArr.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr.length == 1){\r\n let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];\r\n let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr[0].row, \"column\": rangeArr[0].column });\r\n conditionValue.push(v);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr.length == 0){\r\n if(isNaN(v) || v == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v);\r\n }\r\n }\r\n }\r\n }\r\n else if(type1 == \"text\"){ //特定文本\r\n conditionName = \"textContains\";\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-newConditionRule-dialog #conditionVal input\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr = _this.getRangeByTxt(v);\r\n if(rangeArr.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr.length == 1){\r\n let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];\r\n let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr[0].row, \"column\": rangeArr[0].column });\r\n conditionValue.push(v);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr.length == 0){\r\n if(v == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v);\r\n }\r\n }\r\n }\r\n else if(type1 == \"date\"){ //发生日期\r\n conditionName = \"occurrenceDate\";\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-newConditionRule-dialog #daterange-btn\").val();\r\n\r\n if(v == \"\" || v == null){\r\n _this.infoDialog(conditionformat_Text.pleaseSelectADate, \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(v);\r\n }\r\n }\r\n else if(index == 2){ //排名靠前靠后\r\n //条件名称\r\n if(type1 == \"top\"){\r\n if($(\"#luckysheet-newConditionRule-dialog #isPercent\").is(\":selected\")){\r\n conditionName = \"top10%\";\r\n }\r\n else{\r\n conditionName = \"top10\";\r\n }\r\n }\r\n else if(type1 == \"last\"){\r\n if($(\"#luckysheet-newConditionRule-dialog #isPercent\").is(\":selected\")){\r\n conditionName = \"last10%\";\r\n }\r\n else{\r\n conditionName = \"last10\";\r\n }\r\n }\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-newConditionRule-dialog #conditionVal input\").val().trim();\r\n\r\n if(parseInt(v) != v || parseInt(v) < 1 || parseInt(v) > 1000){\r\n _this.infoDialog(conditionformat_Text.pleaseEnterInteger, \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(parseInt(v));\r\n }\r\n else if(index == 3){ //平均值\r\n if(type1 == \"AboveAverage\"){\r\n conditionName = \"AboveAverage\";\r\n conditionValue.push(\"AboveAverage\");\r\n }\r\n else if(type1 == \"SubAverage\"){\r\n conditionName = \"SubAverage\";\r\n conditionValue.push(\"SubAverage\");\r\n }\r\n }\r\n else if(index == 4){ //重复值\r\n conditionName = \"duplicateValue\";\r\n conditionValue.push(type1);\r\n }\r\n else if(index == 5){ //公式\r\n conditionName = \"formula\";\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-newConditionRule-dialog #formulaConditionVal input\").val().trim(); \r\n\r\n if(v == \"\"){\r\n _this.infoDialog(\"Condition value cannot be empty!\", \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(v);\r\n }\r\n\r\n //格式颜色\r\n let textcolor;\r\n if($(\"#luckysheet-newConditionRule-dialog #checkTextColor\").is(\":checked\")){\r\n textcolor = $(\"#luckysheet-newConditionRule-dialog #textcolorshow\").spectrum(\"get\").toHexString();\r\n }\r\n else{\r\n textcolor = null;\r\n }\r\n\r\n let cellcolor;\r\n if($(\"#luckysheet-newConditionRule-dialog #checkCellColor\").is(\":checked\")){\r\n cellcolor = $(\"#luckysheet-newConditionRule-dialog #cellcolorshow\").spectrum(\"get\").toHexString();\r\n }\r\n else{\r\n cellcolor = null;\r\n }\r\n\r\n format = {\r\n \"textColor\": textcolor,\r\n \"cellColor\": cellcolor\r\n };\r\n\r\n rule = {\r\n \"type\": \"default\",\r\n \"cellrange\": $.extend(true, [], Store.luckysheet_select_save),\r\n \"format\": format,\r\n \"conditionName\": conditionName,\r\n \"conditionRange\": conditionRange,\r\n \"conditionValue\": conditionValue\r\n };\r\n }\r\n\r\n $(\"#luckysheet-newConditionRule-dialog\").hide();\r\n\r\n //新建规则的入口\r\n let source = $(this).attr(\"data-source\");\r\n\r\n if(source == 0){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n\r\n //保存之前的规则\r\n let fileH = $.extend(true, [], Store.luckysheetfile);\r\n let historyRules = _this.getHistoryRules(fileH);\r\n\r\n //保存当前的规则\r\n let ruleArr = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] == undefined ? [] : Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"];\r\n ruleArr.push(rule);\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] = ruleArr;\r\n\r\n let fileC = $.extend(true, [], Store.luckysheetfile);\r\n let currentRules = _this.getCurrentRules(fileC);\r\n\r\n //刷新一次表格\r\n _this.ref(historyRules, currentRules);\r\n\r\n //发送给后台\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, ruleArr, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n }\r\n else if(source == 1){\r\n //临时存储新规则\r\n let ruleArr = !!_this.fileClone[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] ? _this.fileClone[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] : [];\r\n ruleArr.push(rule);\r\n _this.fileClone[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] = ruleArr;\r\n\r\n //新建规则隐藏,管理规则显示\r\n _this.administerRuleDialog();\r\n }\r\n });\r\n $(document).off(\"click.CFnewConditionRuleClose\").on(\"click.CFnewConditionRuleClose\", \"#luckysheet-newConditionRule-dialog-close\", function(){\r\n //新建规则的入口\r\n let source = $(this).attr(\"data-source\");\r\n if(source == 0){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n }\r\n if(source == 1){\r\n $(\"#luckysheet-administerRule-dialog\").show();\r\n }\r\n\r\n //新建规则隐藏\r\n $(\"#luckysheet-newConditionRule-dialog\").hide();\r\n\r\n //隐藏虚线框\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n });\r\n\r\n // 编辑规则\r\n $(document).off(\"click.CFeditorConditionRule\").on(\"click.CFeditorConditionRule\", \"#editorConditionRule\", function(){\r\n\r\n let sheetIndex = $(\"#luckysheet-administerRule-dialog .chooseSheet option:selected\").val();\r\n\r\n if(!checkProtectionFormatCells(sheetIndex)){\r\n return;\r\n }\r\n\r\n\r\n let itemIndex = $(\"#luckysheet-administerRule-dialog .ruleList .listBox .item.on\").attr(\"data-item\");\r\n let rule = {\r\n \"sheetIndex\": sheetIndex,\r\n \"itemIndex\": itemIndex,\r\n \"data\": _this.fileClone[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"][itemIndex]\r\n };\r\n _this.editorRule = rule;\r\n _this.editorConditionRuleDialog();\r\n });\r\n $(document).off(\"click.CFeditorConditionRuleConfirm\").on(\"click.CFeditorConditionRuleConfirm\", \"#luckysheet-editorConditionRule-dialog-confirm\",function(){\r\n let index = $(\"#luckysheet-editorConditionRule-dialog .ruleTypeItem.on\").index();\r\n let type1 = $(\"#luckysheet-editorConditionRule-dialog #type1 option:selected\").val();\r\n let type2 = $(\"#luckysheet-editorConditionRule-dialog .\" + type1 + \"Box #type2 option:selected\").val();\r\n\r\n let cellrange = _this.editorRule[\"data\"].cellrange;\r\n\r\n let format, rule;\r\n if(index == 0){\r\n if(type1 == \"dataBar\"){ //数据条\r\n let color = $(this).parents(\"#luckysheet-editorConditionRule-dialog\").find(\".dataBarBox .luckysheet-conditionformat-config-color\").spectrum(\"get\").toHexString();\r\n\r\n if(type2 == \"gradient\"){ //渐变填充\r\n format = [color, \"#ffffff\"];\r\n }\r\n else if(type2 == \"solid\"){ //实心填充\r\n format = [color];\r\n }\r\n\r\n rule = {\r\n \"type\": \"dataBar\",\r\n \"cellrange\": cellrange,\r\n \"format\": format\r\n };\r\n }\r\n else if(type1 == \"colorGradation\"){ //色阶\r\n let maxcolor = $(this).parents(\"#luckysheet-editorConditionRule-dialog\").find(\".colorGradationBox .maxVal .luckysheet-conditionformat-config-color\").spectrum(\"get\").toRgbString();\r\n let midcolor = $(this).parents(\"#luckysheet-editorConditionRule-dialog\").find(\".colorGradationBox .midVal .luckysheet-conditionformat-config-color\").spectrum(\"get\").toRgbString();\r\n let mincolor = $(this).parents(\"#luckysheet-editorConditionRule-dialog\").find(\".colorGradationBox .minVal .luckysheet-conditionformat-config-color\").spectrum(\"get\").toRgbString();\r\n\r\n if(type2 == \"threeColor\"){ //三色\r\n format = [maxcolor, midcolor, mincolor];\r\n }\r\n else if(type2 == \"twoColor\"){ //双色\r\n format = [maxcolor, mincolor];\r\n }\r\n\r\n rule = {\r\n \"type\": \"colorGradation\",\r\n \"cellrange\": cellrange,\r\n \"format\": format\r\n };\r\n }\r\n else if(type1 == \"icons\"){ //图标集\r\n let len = $(this).parents(\"#luckysheet-editorConditionRule-dialog\").find(\".iconsBox .model\").attr(\"data-len\");\r\n let leftMin = $(this).parents(\"#luckysheet-editorConditionRule-dialog\").find(\".iconsBox .model\").attr(\"data-leftmin\");\r\n let top = $(this).parents(\"#luckysheet-editorConditionRule-dialog\").find(\".iconsBox .model\").attr(\"data-top\");\r\n\r\n format = {\r\n \"len\": len,\r\n \"leftMin\": leftMin,\r\n \"top\": top\r\n };\r\n\r\n rule = {\r\n \"type\": \"icons\",\r\n \"cellrange\": cellrange,\r\n \"format\": format\r\n };\r\n }\r\n }\r\n else{\r\n let conditionName = \"\", conditionRange = [], conditionValue = [];\r\n\r\n if(index == 1){\r\n if(type1 == \"number\"){ //单元格值\r\n conditionName = type2;\r\n\r\n if(type2 == \"betweenness\"){\r\n let v1 = $(\"#luckysheet-editorConditionRule-dialog #conditionVal input\").val().trim();\r\n let v2 = $(\"#luckysheet-editorConditionRule-dialog #conditionVal2 input\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr1 = _this.getRangeByTxt(v1);\r\n if(rangeArr1.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr1.length == 1){\r\n let r1 = rangeArr1[0].row[0], r2 = rangeArr1[0].row[1];\r\n let c1 = rangeArr1[0].column[0], c2 = rangeArr1[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v1 = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr1[0].row, \"column\": rangeArr1[0].column });\r\n conditionValue.push(v1);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr1.length == 0){\r\n if(isNaN(v1) || v1 == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v1);\r\n }\r\n }\r\n\r\n let rangeArr2 = _this.getRangeByTxt(v2);\r\n if(rangeArr2.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr2.length == 1){\r\n let r1 = rangeArr2[0].row[0], r2 = rangeArr2[0].row[1];\r\n let c1 = rangeArr2[0].column[0], c2 = rangeArr2[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v2 = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr2[0].row, \"column\": rangeArr2[0].column });\r\n conditionValue.push(v2);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr2.length == 0){\r\n if(isNaN(v2) || v2 == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v2);\r\n }\r\n }\r\n }\r\n else{\r\n //条件值\r\n let v = $(\"#luckysheet-editorConditionRule-dialog #conditionVal input\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr = _this.getRangeByTxt(v);\r\n if(rangeArr.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr.length == 1){\r\n let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];\r\n let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr[0].row, \"column\": rangeArr[0].column });\r\n conditionValue.push(v);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr.length == 0){\r\n if(isNaN(v) || v == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v);\r\n }\r\n }\r\n }\r\n }\r\n else if(type1 == \"text\"){ //特定文本\r\n conditionName = \"textContains\";\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-editorConditionRule-dialog #conditionVal input\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr = _this.getRangeByTxt(v);\r\n if(rangeArr.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr.length == 1){\r\n let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];\r\n let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr[0].row, \"column\": rangeArr[0].column });\r\n conditionValue.push(v);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr.length == 0){\r\n if(isNaN(v) || v == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v);\r\n }\r\n }\r\n }\r\n else if(type1 == \"date\"){ //发生日期\r\n conditionName = \"occurrenceDate\";\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-editorConditionRule-dialog #daterange-btn\").val();\r\n\r\n if(v == \"\" || v == null){\r\n _this.infoDialog(conditionformat_Text.pleaseSelectADate, \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(v);\r\n }\r\n }\r\n else if(index == 2){ //排名靠前靠后\r\n //条件名称\r\n if(type1 == \"top\"){\r\n if($(\"#luckysheet-editorConditionRule-dialog #isPercent\").is(\":selected\")){\r\n conditionName = \"top10%\";\r\n }\r\n else{\r\n conditionName = \"top10\";\r\n }\r\n }\r\n else if(type1 == \"last\"){\r\n if($(\"#luckysheet-editorConditionRule-dialog #isPercent\").is(\":selected\")){\r\n conditionName = \"last10%\";\r\n }\r\n else{\r\n conditionName = \"last10\";\r\n }\r\n }\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-editorConditionRule-dialog #conditionVal input\").val().trim();\r\n\r\n if(parseInt(v) != v || parseInt(v) < 1 || parseInt(v) > 1000){\r\n _this.infoDialog(conditionformat_Text.pleaseEnterInteger, \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(v);\r\n }\r\n else if(index == 3){ //平均值\r\n if(type1 == \"AboveAverage\"){\r\n conditionName = \"AboveAverage\";\r\n conditionValue.push(\"AboveAverage\");\r\n }\r\n else if(type1 == \"SubAverage\"){\r\n conditionName = \"SubAverage\";\r\n conditionValue.push(\"SubAverage\");\r\n }\r\n }\r\n else if(index == 4){ //重复值\r\n conditionName = \"duplicateValue\";\r\n conditionValue.push(type1);\r\n }\r\n else if(index == 5){ //公式\r\n conditionName = \"formula\";\r\n\r\n //条件值\r\n let v = $(\"#luckysheet-editorConditionRule-dialog #formulaConditionVal input\").val().trim(); \r\n console.log(v)\r\n if(v == \"\"){\r\n _this.infoDialog(\"Condition value cannot be empty!\", \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(v);\r\n }\r\n\r\n //格式颜色\r\n let textcolor;\r\n if($(\"#luckysheet-editorConditionRule-dialog #checkTextColor\").is(\":checked\")){\r\n textcolor = $(\"#luckysheet-editorConditionRule-dialog #textcolorshow\").spectrum(\"get\").toHexString();\r\n }\r\n else{\r\n textcolor = null;\r\n }\r\n\r\n let cellcolor;\r\n if($(\"#luckysheet-editorConditionRule-dialog #checkCellColor\").is(\":checked\")){\r\n cellcolor = $(\"#luckysheet-editorConditionRule-dialog #cellcolorshow\").spectrum(\"get\").toHexString();\r\n }\r\n else{\r\n cellcolor = null;\r\n }\r\n\r\n format = {\r\n \"textColor\": textcolor,\r\n \"cellColor\": cellcolor\r\n };\r\n\r\n rule = {\r\n \"type\": \"default\",\r\n \"cellrange\": cellrange,\r\n \"format\": format,\r\n \"conditionName\": conditionName,\r\n \"conditionRange\": conditionRange,\r\n \"conditionValue\": conditionValue\r\n };\r\n }\r\n\r\n //修改编辑的规则\r\n let sheetIndex = _this.editorRule[\"sheetIndex\"];\r\n let itemIndex = _this.editorRule[\"itemIndex\"];\r\n _this.fileClone[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"][itemIndex] = rule;\r\n\r\n //编辑规则隐藏,管理规则显示\r\n $(\"#luckysheet-editorConditionRule-dialog\").hide();\r\n _this.administerRuleDialog();\r\n });\r\n $(document).off(\"click.CFeditorConditionRuleClose\").on(\"click.CFeditorConditionRuleClose\", \"#luckysheet-editorConditionRule-dialog-close\",function(){\r\n //编辑规则隐藏,管理规则显示\r\n $(\"#luckysheet-editorConditionRule-dialog\").hide();\r\n $(\"#luckysheet-administerRule-dialog\").show();\r\n //隐藏虚线框\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n });\r\n\r\n // 新建规则、编辑规则 类型切换\r\n $(document).off(\"click.CFnewEditorRuleItem\").on(\"click.CFnewEditorRuleItem\", \".luckysheet-newEditorRule-dialog .ruleTypeItem\", function(){\r\n $(this).addClass(\"on\").siblings().removeClass(\"on\");\r\n\r\n let index = $(this).index();\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\".ruleExplainBox\").html(_this.getRuleExplain(index));\r\n\r\n _this.colorSelectInit();\r\n });\r\n $(document).off(\"change.CFnewEditorRuleType1\").on(\"change.CFnewEditorRuleType1\", \".luckysheet-newEditorRule-dialog #type1\", function(){\r\n let optionVal = $(this).find(\"option:selected\").val();\r\n\r\n if(optionVal == \"dataBar\" || optionVal == \"colorGradation\" || optionVal == \"icons\" || optionVal == \"number\" || optionVal == \"text\" || optionVal == \"date\"){\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\".\" + optionVal + \"Box\").show().siblings().hide();\r\n }\r\n\r\n if(optionVal == \"date\"){\r\n _this.daterangeInit($(this).parents(\".luckysheet-newEditorRule-dialog\").attr(\"id\"));\r\n }\r\n });\r\n $(document).off(\"change.CFnewEditorRuleType2\").on(\"change.CFnewEditorRuleType2\", \".luckysheet-newEditorRule-dialog #type2\", function(){\r\n let type1 = $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\"#type1 option:selected\").val();\r\n\r\n if(type1 == \"colorGradation\"){\r\n let type2 = $(this).find(\"option:selected\").val();\r\n\r\n if(type2 == \"threeColor\"){\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\".midVal\").show();\r\n }\r\n else{\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\".midVal\").hide();\r\n }\r\n }\r\n else if(type1 == \"number\"){\r\n let type2 = $(this).find(\"option:selected\").val();\r\n\r\n if(type2 == \"betweenness\"){\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\".txt\").show();\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\"#conditionVal2\").show();\r\n }\r\n else{\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\".txt\").hide();\r\n $(this).parents(\".luckysheet-newEditorRule-dialog\").find(\"#conditionVal2\").hide();\r\n }\r\n }\r\n });\r\n $(document).off(\"click.CFiconsShowbox\").on(\"click.CFiconsShowbox\", \".luckysheet-newEditorRule-dialog .iconsBox .showbox\", function(){\r\n $(this).parents(\".iconsBox\").find(\"ul\").toggle();\r\n });\r\n $(document).off(\"click.CFiconsLi\").on(\"click.CFiconsLi\", \".luckysheet-newEditorRule-dialog .iconsBox li\", function(){\r\n let len = $(this).find(\"div\").attr(\"data-len\");\r\n let leftmin = $(this).find(\"div\").attr(\"data-leftmin\");\r\n let top = $(this).find(\"div\").attr(\"data-top\");\r\n let title = $(this).find(\"div\").attr(\"title\");\r\n let position = $(this).find(\"div\").css(\"background-position\");\r\n\r\n $(this).parents(\".iconsBox\").find(\".showbox .model\").css(\"background-position\", position);\r\n $(this).parents(\".iconsBox\").find(\".showbox .model\").attr(\"data-len\", len);\r\n $(this).parents(\".iconsBox\").find(\".showbox .model\").attr(\"data-leftmin\", leftmin);\r\n $(this).parents(\".iconsBox\").find(\".showbox .model\").attr(\"data-top\", top);\r\n $(this).parents(\".iconsBox\").find(\".showbox .model\").attr(\"title\", title);\r\n\r\n $(this).parents(\"ul\").hide();\r\n });\r\n\r\n // 删除规则\r\n $(document).off(\"click.CFdeleteConditionRule\").on(\"click.CFdeleteConditionRule\", \"#deleteConditionRule\", function(){\r\n let sheetIndex = $(\"#luckysheet-administerRule-dialog .chooseSheet option:selected\").val();\r\n\r\n if(!checkProtectionFormatCells(sheetIndex)){\r\n return;\r\n }\r\n\r\n let itemIndex = $(\"#luckysheet-administerRule-dialog .ruleList .listBox .item.on\").attr(\"data-item\");\r\n _this.fileClone[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"].splice(itemIndex, 1);\r\n _this.administerRuleDialog();\r\n });\r\n\r\n // 规则子菜单弹出层 点击确定修改样式\r\n $(document).off(\"click.CFdefault\").on(\"click.CFdefault\", \"#luckysheet-conditionformat-dialog-confirm\", function(){\r\n\r\n if(!checkProtectionFormatCells(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n //条件名称\r\n let conditionName = $(\"#luckysheet-conditionformat-dialog .box\").attr(\"data-itemvalue\");\r\n\r\n //条件单元格\r\n let conditionRange = [];\r\n\r\n //条件值\r\n let conditionValue = [];\r\n if(conditionName == \"greaterThan\" || conditionName == \"lessThan\" || conditionName == \"equal\" || conditionName == \"textContains\"){\r\n let v = $(\"#luckysheet-conditionformat-dialog #conditionVal\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr = _this.getRangeByTxt(v);\r\n if(rangeArr.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr.length == 1){\r\n let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];\r\n let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr[0].row, \"column\": rangeArr[0].column });\r\n conditionValue.push(v);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr.length == 0){\r\n if(isNaN(v) || v == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v);\r\n }\r\n }\r\n }\r\n else if(conditionName == \"betweenness\"){//介于\r\n let v1 = $(\"#luckysheet-conditionformat-dialog #conditionVal\").val().trim();\r\n let v2 = $(\"#luckysheet-conditionformat-dialog #conditionVal2\").val().trim();\r\n\r\n //条件值是否是选区\r\n let rangeArr1 = _this.getRangeByTxt(v1);\r\n if(rangeArr1.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr1.length == 1){\r\n let r1 = rangeArr1[0].row[0], r2 = rangeArr1[0].row[1];\r\n let c1 = rangeArr1[0].column[0], c2 = rangeArr1[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v1 = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr1[0].row, \"column\": rangeArr1[0].column });\r\n conditionValue.push(v1);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr1.length == 0){\r\n if(isNaN(v1) || v1 == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v1);\r\n }\r\n }\r\n\r\n let rangeArr2 = _this.getRangeByTxt(v2);\r\n if(rangeArr2.length > 1){\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr2.length == 1){\r\n let r1 = rangeArr2[0].row[0], r2 = rangeArr2[0].row[1];\r\n let c1 = rangeArr2[0].column[0], c2 = rangeArr2[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v2 = getcellvalue(r1, c1, Store.flowdata);\r\n\r\n conditionRange.push({ \"row\": rangeArr2[0].row, \"column\": rangeArr2[0].column });\r\n conditionValue.push(v2);\r\n }\r\n else{\r\n _this.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr2.length == 0){\r\n if(isNaN(v2) || v2 == \"\"){\r\n _this.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue.push(v2);\r\n }\r\n }\r\n }\r\n else if(conditionName == \"occurrenceDate\"){//日期\r\n let v = $(\"#luckysheet-conditionformat-dialog #daterange-btn\").val();\r\n\r\n if(v == \"\" || v == null){\r\n _this.infoDialog(conditionformat_Text.pleaseSelectADate, \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(v);\r\n }\r\n else if(conditionName == \"duplicateValue\"){//重复值\r\n conditionValue.push($(\"#luckysheet-conditionformat-dialog #conditionVal option:selected\").val());\r\n }\r\n else if(conditionName == \"top10\" || conditionName == \"top10%\" || conditionName == \"last10\" || conditionName == \"last10%\"){\r\n let v = $(\"#luckysheet-conditionformat-dialog #conditionVal\").val().trim();\r\n\r\n if(parseInt(v) != v || parseInt(v) < 1 || parseInt(v) > 1000){\r\n _this.infoDialog(conditionformat_Text.pleaseEnterInteger, \"\");\r\n return;\r\n }\r\n\r\n conditionValue.push(v);\r\n }\r\n else if(conditionName == \"AboveAverage\"){ //高于平均值\r\n conditionValue.push(\"AboveAverage\");\r\n }\r\n else if(conditionName == \"SubAverage\"){ //低于平均值\r\n conditionValue.push(\"SubAverage\");\r\n }\r\n\r\n //格式颜色\r\n let textcolor;\r\n if($(\"#checkTextColor\").is(\":checked\")){\r\n textcolor = $(\"#textcolorshow\").spectrum(\"get\").toHexString();\r\n }\r\n else{\r\n textcolor = null;\r\n }\r\n\r\n let cellcolor;\r\n if($(\"#checkCellColor\").is(\":checked\")){\r\n cellcolor = $(\"#cellcolorshow\").spectrum(\"get\").toHexString();\r\n }\r\n else{\r\n cellcolor = null;\r\n }\r\n\r\n //保存之前的规则\r\n let fileH = $.extend(true, [], Store.luckysheetfile);\r\n let historyRules = _this.getHistoryRules(fileH);\r\n\r\n //保存当前的规则\r\n let rule = {\r\n \"type\": \"default\",\r\n \"cellrange\": $.extend(true, [], Store.luckysheet_select_save),\r\n \"format\": {\r\n \"textColor\": textcolor,\r\n \"cellColor\": cellcolor\r\n },\r\n \"conditionName\": conditionName,\r\n \"conditionRange\": conditionRange,\r\n \"conditionValue\": conditionValue\r\n };\r\n let ruleArr = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] == undefined ? [] : Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"];\r\n ruleArr.push(rule);\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"] = ruleArr;\r\n\r\n let fileC = $.extend(true, [], Store.luckysheetfile);\r\n let currentRules = _this.getCurrentRules(fileC);\r\n\r\n //刷新一次表格\r\n _this.ref(historyRules, currentRules);\r\n\r\n //隐藏一些dom\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-conditionformat-dialog\").hide();\r\n\r\n //发送给后台\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, ruleArr, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n });\r\n\r\n // 图标集弹出层 选择\r\n $(document).off(\"click.CFicons\").on(\"click.CFicons\", \"#luckysheet-CFicons-dialog .item\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-CFicons-dialog\").hide();\r\n\r\n if(Store.luckysheet_select_save.length > 0){\r\n let cellrange = $.extend(true, [], Store.luckysheet_select_save);\r\n let format = {\r\n \"len\": $(this).attr(\"data-len\"),\r\n \"leftMin\": $(this).attr(\"data-leftMin\"),\r\n \"top\": $(this).attr(\"data-top\")\r\n }\r\n\r\n _this.updateItem(\"icons\", cellrange, format);\r\n }\r\n });\r\n\r\n // 选择单元格\r\n $(document).on(\"click\", \".range .fa-table\", function(){\r\n let id = $(this).parents(\".luckysheet-modal-dialog\").attr(\"id\");\r\n $(\"#\" + id).hide();\r\n //入口\r\n let source;\r\n \r\n if(id == \"luckysheet-conditionformat-dialog\"){\r\n let $id = $(this).siblings(\"input\").attr(\"id\");\r\n \r\n if($id == \"conditionVal\"){\r\n source = \"0_1\";\r\n }\r\n else{\r\n source = \"0_2\";\r\n }\r\n }\r\n else if(id == \"luckysheet-newConditionRule-dialog\"){\r\n let $id = $(this).parents(\".range\").attr(\"id\");\r\n\r\n if($id == \"formulaConditionVal\"){\r\n source = \"1_0\";\r\n }\r\n else if($id == \"conditionVal\"){\r\n source = \"1_1\";\r\n }\r\n else{\r\n source = \"1_2\";\r\n }\r\n }\r\n else if(id == \"luckysheet-editorConditionRule-dialog\"){\r\n let $id = $(this).parents(\".range\").attr(\"id\");\r\n\r\n if($id == \"formulaConditionVal\"){\r\n source = \"2_0\";\r\n }\r\n else if($id == \"conditionVal\"){\r\n source = \"2_1\";\r\n }\r\n else{\r\n source = \"2_2\";\r\n }\r\n }\r\n //input值\r\n let v = $(this).siblings(\"input\").val();\r\n\r\n _this.singleRangeDialog(source, v);\r\n selectionCopyShow(_this.getRangeByTxt(v));\r\n });\r\n $(document).on(\"click\", \"#luckysheet-singleRange-dialog-confirm\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(this).parents(\"#luckysheet-singleRange-dialog\").hide();\r\n\r\n let source = $(this).attr(\"data-source\");\r\n let v = $(this).parents(\"#luckysheet-singleRange-dialog\").find(\"input\").val();\r\n\r\n if(source == \"0_1\"){\r\n $(\"#luckysheet-conditionformat-dialog\").show();\r\n $(\"#luckysheet-conditionformat-dialog #conditionVal\").val(v);\r\n }\r\n else if(source == \"0_2\"){\r\n $(\"#luckysheet-conditionformat-dialog\").show();\r\n $(\"#luckysheet-conditionformat-dialog #conditionVal2\").val(v);\r\n }\r\n else if(source == \"1_0\"){\r\n $(\"#luckysheet-newConditionRule-dialog\").show();\r\n $(\"#luckysheet-newConditionRule-dialog #formulaConditionVal input\").val(v);\r\n }\r\n else if(source == \"1_1\"){\r\n $(\"#luckysheet-newConditionRule-dialog\").show();\r\n $(\"#luckysheet-newConditionRule-dialog #conditionVal input\").val(v);\r\n }\r\n else if(source == \"1_2\"){\r\n $(\"#luckysheet-newConditionRule-dialog\").show();\r\n $(\"#luckysheet-newConditionRule-dialog #conditionVal2 input\").val(v);\r\n }\r\n else if(source == \"2_0\"){\r\n $(\"#luckysheet-editorConditionRule-dialog\").show();\r\n $(\"#luckysheet-editorConditionRule-dialog #formulaConditionVal input\").val(v);\r\n }\r\n else if(source == \"2_1\"){\r\n $(\"#luckysheet-editorConditionRule-dialog\").show();\r\n $(\"#luckysheet-editorConditionRule-dialog #conditionVal input\").val(v);\r\n }\r\n else if(source == \"2_2\"){\r\n $(\"#luckysheet-editorConditionRule-dialog\").show();\r\n $(\"#luckysheet-editorConditionRule-dialog #conditionVal2 input\").val(v);\r\n }\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n $(document).on(\"click\", \"#luckysheet-singleRange-dialog-close\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(this).parents(\"#luckysheet-singleRange-dialog\").hide();\r\n\r\n let source = $(this).attr(\"data-source\");\r\n if(source == \"0_1\" || source == \"0_2\"){\r\n $(\"#luckysheet-conditionformat-dialog\").show();\r\n }\r\n else if(source == \"1_0\" || source == \"1_1\" || source == \"1_2\"){\r\n $(\"#luckysheet-newConditionRule-dialog\").show();\r\n }\r\n else if(source == \"2_0\" || source == \"2_1\" || source == \"2_2\"){\r\n $(\"#luckysheet-editorConditionRule-dialog\").show();\r\n }\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n });\r\n\r\n // 弹出层右上角关闭按钮\r\n $(document).on(\"click\", \".luckysheet-modal-dialog-title-close\", function(){\r\n let id = $(this).parents(\".luckysheet-modal-dialog\").attr(\"id\");\r\n\r\n //新建规则弹出层\r\n if(id == \"luckysheet-newConditionRule-dialog\"){\r\n let source = $(\"#\" + id).find(\"#luckysheet-newConditionRule-dialog-close\").attr(\"data-source\");\r\n //新建规则入口\r\n if(source == 1){\r\n $(\"#luckysheet-administerRule-dialog\").show();\r\n }\r\n }\r\n\r\n //编辑规则弹出层\r\n if(id == \"luckysheet-editorConditionRule-dialog\"){\r\n $(\"#luckysheet-administerRule-dialog\").show();\r\n }\r\n\r\n //选择单元格弹出层\r\n if(id == \"luckysheet-singleRange-dialog\"){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n\r\n let source = $(this).parents(\"#luckysheet-singleRange-dialog\").find(\"#luckysheet-singleRange-dialog-confirm\").attr(\"data-source\");\r\n if(source == \"0_1\" || source == \"0_2\"){\r\n $(\"#luckysheet-conditionformat-dialog\").show();\r\n }\r\n else if(source == \"1_1\" || source == \"1_2\"){\r\n $(\"#luckysheet-newConditionRule-dialog\").show();\r\n }\r\n else if(source == \"2_1\" || source == \"2_2\"){\r\n $(\"#luckysheet-editorConditionRule-dialog\").show();\r\n }\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n }\r\n\r\n //选择应用范围弹出层\r\n if(id == \"luckysheet-multiRange-dialog\"){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n\r\n $(\"#luckysheet-administerRule-dialog\").show();\r\n\r\n let range = [];\r\n selectionCopyShow(range);\r\n }\r\n\r\n //提示框\r\n if(id == \"luckysheet-conditionformat-info-dialog\"){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n }\r\n });\r\n\r\n //提示框\r\n $(document).on(\"click\", \"#luckysheet-conditionformat-info-dialog-close\", function(){\r\n $(this).parents(\"#luckysheet-conditionformat-info-dialog\").hide();\r\n });\r\n },\r\n singleRangeDialog: function(source, value){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-singleRange-dialog\").remove();\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-singleRange-dialog\",\r\n \"addclass\": \"luckysheet-singleRange-dialog\",\r\n \"title\": conditionformat_Text.selectCell,\r\n \"content\": ``,\r\n \"botton\": `\r\n `,\r\n \"style\": \"z-index:100003\"\r\n }));\r\n let $t = $(\"#luckysheet-singleRange-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-singleRange-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n },\r\n multiRangeDialog: function(dataItem, value){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-multiRange-dialog\").remove();\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-multiRange-dialog\",\r\n \"addclass\": \"luckysheet-multiRange-dialog\",\r\n \"title\": conditionformat_Text.selectRange,\r\n \"content\": ``,\r\n \"botton\": `\r\n `,\r\n \"style\": \"z-index:100003\"\r\n }));\r\n let $t = $(\"#luckysheet-multiRange-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-multiRange-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n\r\n selectionCopyShow(_this.getRangeByTxt(value));\r\n },\r\n getTxtByRange: function(range){\r\n if(range.length > 0){\r\n let txt = [];\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n txt.push(getRangetxt(Store.currentSheetIndex, { \"row\": [r1, r2], \"column\": [c1, c2] }, Store.currentSheetIndex));\r\n }\r\n\r\n return txt.join(\",\");\r\n }\r\n },\r\n getRangeByTxt: function(txt){\r\n let range = [];\r\n\r\n txt = txt.toString();\r\n\r\n if(txt.indexOf(\",\") != -1){\r\n let arr = txt.split(\",\");\r\n for(let i = 0; i < arr.length; i++){\r\n if(formula.iscelldata(arr[i])){\r\n range.push(formula.getcellrange(arr[i]));\r\n }\r\n else{\r\n range = [];\r\n break;\r\n }\r\n }\r\n }\r\n else{\r\n if(formula.iscelldata(txt)){\r\n range.push(formula.getcellrange(txt));\r\n }\r\n }\r\n return range;\r\n },\r\n colorSelectInit: function(){\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n $(\".luckysheet-conditionformat-config-color\").spectrum({\r\n showPalette: true,\r\n showPaletteOnly:true,\r\n preferredFormat: \"hex\",\r\n clickoutFiresChange: false,\r\n showInitial: true,\r\n showInput: true,\r\n // flat: true,\r\n hideAfterPaletteSelect: true,\r\n showSelectionPalette: true,\r\n // showButtons: false,//隐藏选择取消按钮\r\n maxPaletteSize: 8,\r\n maxSelectionSize: 8,\r\n // color: currenColor,\r\n cancelText: conditionformat_Text.cancel,\r\n chooseText: conditionformat_Text.confirmColor,\r\n togglePaletteMoreText: \"自定义\",\r\n togglePaletteLessText: \"收起\",\r\n togglePaletteOnly: true,\r\n clearText: conditionformat_Text.clearColorSelect,\r\n noColorSelectedText: \"没有颜色被选择\",\r\n localStorageKey: \"spectrum.textcolor\" + server.gridKey,\r\n palette: [[\"#000\",\"#444\",\"#666\",\"#999\",\"#ccc\",\"#eee\",\"#f3f3f3\",\"#fff\"],\r\n [\"#f00\",\"#f90\",\"#ff0\",\"#0f0\",\"#0ff\",\"#00f\",\"#90f\",\"#f0f\"],\r\n [\"#f4cccc\",\"#fce5cd\",\"#fff2cc\",\"#d9ead3\",\"#d0e0e3\",\"#cfe2f3\",\"#d9d2e9\",\"#ead1dc\"],\r\n [\"#ea9999\",\"#f9cb9c\",\"#ffe599\",\"#b6d7a8\",\"#a2c4c9\",\"#9fc5e8\",\"#b4a7d6\",\"#d5a6bd\"],\r\n [\"#e06666\",\"#f6b26b\",\"#ffd966\",\"#93c47d\",\"#76a5af\",\"#6fa8dc\",\"#8e7cc3\",\"#c27ba0\"],\r\n [\"#c00\",\"#e69138\",\"#f1c232\",\"#6aa84f\",\"#45818e\",\"#3d85c6\",\"#674ea7\",\"#a64d79\"],\r\n [\"#900\",\"#b45f06\",\"#bf9000\",\"#38761d\",\"#134f5c\",\"#0b5394\",\"#351c75\",\"#741b47\"],\r\n [\"#600\",\"#783f04\",\"#7f6000\",\"#274e13\",\"#0c343d\",\"#073763\",\"#20124d\",\"#4c1130\"]],\r\n change: function(color){\r\n if (color != null) {\r\n color = color.toHexString();\r\n }\r\n }\r\n });\r\n },\r\n conditionformatDialog: function(title, content){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-conditionformat-dialog\").remove();\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-conditionformat-dialog\",\r\n \"addclass\": \"luckysheet-conditionformat-dialog\",\r\n \"title\": title,\r\n \"content\": content,\r\n \"botton\": `\r\n `,\r\n \"style\": \"z-index:9999\"\r\n }));\r\n let $t = $(\"#luckysheet-conditionformat-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-conditionformat-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n\r\n _this.init();\r\n _this.colorSelectInit();\r\n\r\n if(title == locale().conditionformat.conditionformat_occurrenceDate){\r\n _this.daterangeInit(\"luckysheet-conditionformat-dialog\");\r\n }\r\n },\r\n CFiconsDialog: function(){ \r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-CFicons-dialog\").remove();\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n let content = `
\r\n
${conditionformat_Text.pleaseSelectIcon}
\r\n
${conditionformat_Text.direction}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
${conditionformat_Text.shape}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
${conditionformat_Text.mark}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
${conditionformat_Text.grade}
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
`;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-CFicons-dialog\",\r\n \"addclass\": \"luckysheet-CFicons-dialog\",\r\n \"title\": conditionformat_Text.icons,\r\n \"content\": content,\r\n \"botton\": ``,\r\n \"style\": \"z-index:100003\"\r\n }));\r\n let $t = $(\"#luckysheet-CFicons-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 400)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-CFicons-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n },\r\n administerRuleDialog: function(){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-administerRule-dialog\").remove();\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n //工作表\r\n let opHtml = '';\r\n for(let j = 0; j < Store.luckysheetfile.length; j++){\r\n if(Store.luckysheetfile[j].status == \"1\"){\r\n opHtml += ``;\r\n }\r\n else{\r\n opHtml += ``;\r\n }\r\n }\r\n\r\n let content = `
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n ${conditionformat_Text.rule}\r\n ${conditionformat_Text.format}\r\n ${conditionformat_Text.applyRange}\r\n
\r\n
\r\n
\r\n
`;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-administerRule-dialog\",\r\n \"addclass\": \"luckysheet-administerRule-dialog\",\r\n \"title\": conditionformat_Text.conditionformatManageRules,\r\n \"content\": content,\r\n \"botton\": `\r\n `,\r\n \"style\": \"z-index:100003\"\r\n }));\r\n let $t = $(\"#luckysheet-administerRule-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 400)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-administerRule-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n\r\n //当前工作表的规则列表\r\n let index = $(\"#luckysheet-administerRule-dialog .chooseSheet option:selected\").val();\r\n this.getConditionRuleList(index);\r\n },\r\n getConditionRuleList: function(index){\r\n\r\n let _this = this;\r\n\r\n $(\"#luckysheet-administerRule-dialog .ruleList .listBox\").empty();\r\n\r\n let ruleArr = _this.fileClone[getSheetIndex(index)].luckysheet_conditionformat_save; //条件格式规则集合\r\n if(ruleArr != null && ruleArr.length > 0){\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n for(let i = 0; i < ruleArr.length; i++){\r\n let type = ruleArr[i][\"type\"]; //规则类型\r\n let format = ruleArr[i][\"format\"]; //规则样式\r\n let cellrange = ruleArr[i][\"cellrange\"]; //规则应用范围\r\n\r\n let ruleName; //规则名称\r\n let formatHtml = ''; //样式dom\r\n if(type == \"dataBar\"){\r\n ruleName = conditionformat_Text.dataBar;\r\n\r\n formatHtml = '';\r\n }\r\n else if(type == \"colorGradation\"){\r\n ruleName = conditionformat_Text.colorGradation;\r\n\r\n formatHtml = '';\r\n }\r\n else if(type == \"icons\"){\r\n ruleName = conditionformat_Text.icons;\r\n\r\n formatHtml = '';\r\n }\r\n else{\r\n ruleName = _this.getConditionRuleName(ruleArr[i].conditionName, ruleArr[i].conditionRange, ruleArr[i].conditionValue);\r\n\r\n if(format[\"textColor\"] != null){\r\n formatHtml += '';\r\n }\r\n\r\n if(format[\"cellColor\"] != null){\r\n formatHtml += '';\r\n }\r\n }\r\n\r\n //应用范围dom\r\n let rangeTxtArr = [];\r\n for(let s = 0; s < cellrange.length; s++){\r\n let r1 = cellrange[s].row[0], r2 = cellrange[s].row[1];\r\n let c1 = cellrange[s].column[0], c2 = cellrange[s].column[1];\r\n\r\n rangeTxtArr.push(chatatABC(c1) + (r1 + 1) + \":\" + chatatABC(c2) + (r2 + 1));\r\n }\r\n\r\n //条件格式规则列表dom\r\n let itemHtml = '
' +\r\n '
' + ruleName + '
' +\r\n '
' + formatHtml + '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
';\r\n\r\n $(\"#luckysheet-administerRule-dialog .ruleList .listBox\").prepend(itemHtml);\r\n }\r\n\r\n $(\"#luckysheet-administerRule-dialog .ruleList .listBox .item canvas\").each(function(i){\r\n let x = $(this).closest(\".item\").attr(\"data-item\");\r\n\r\n let type = ruleArr[x][\"type\"];\r\n let format = ruleArr[x][\"format\"];\r\n\r\n let can = $(this).get(0).getContext(\"2d\");\r\n if(type == \"dataBar\"){\r\n if(format.length == 2){\r\n let my_gradient = can.createLinearGradient(0, 0, 46, 0);\r\n my_gradient.addColorStop(0, format[0]);\r\n my_gradient.addColorStop(1, format[1]);\r\n can.fillStyle = my_gradient;\r\n can.fillRect(0, 0, 46, 18);\r\n\r\n can.beginPath();\r\n can.moveTo(0, 0);\r\n can.lineTo(0, 18);\r\n can.lineTo(46, 18);\r\n can.lineTo(46, 0);\r\n can.lineTo(0, 0);\r\n can.lineWidth = Store.devicePixelRatio;\r\n can.strokeStyle = format[0];\r\n can.stroke();\r\n can.closePath();\r\n }\r\n else if(format.length == 1){\r\n can.fillStyle = format[0];\r\n can.fillRect(0, 0, 46, 18);\r\n\r\n can.beginPath();\r\n can.moveTo(0, 0);\r\n can.lineTo(0, 18);\r\n can.lineTo(46, 18);\r\n can.lineTo(46, 0);\r\n can.lineTo(0, 0);\r\n can.lineWidth = Store.devicePixelRatio;\r\n can.strokeStyle = format[0];\r\n can.stroke();\r\n can.closePath();\r\n }\r\n }\r\n else if(type == \"colorGradation\"){\r\n let my_gradient = can.createLinearGradient(0, 0, 46, 0);\r\n\r\n if(format.length == 3){\r\n my_gradient.addColorStop(0, format[0]);\r\n my_gradient.addColorStop(0.5, format[1]);\r\n my_gradient.addColorStop(1, format[2]);\r\n }\r\n else if(format.length == 2){\r\n my_gradient.addColorStop(0, format[0]);\r\n my_gradient.addColorStop(1, format[1]);\r\n }\r\n\r\n can.fillStyle = my_gradient;\r\n can.fillRect(0, 0, 46, 18);\r\n }\r\n else if(type == \"icons\"){\r\n let len = format[\"len\"];\r\n let l = format[\"leftMin\"];\r\n let t = format[\"top\"];\r\n\r\n let w1 = 32 * len + 10 * (len - 1);\r\n let h1 = 32;\r\n let w2 = 46;\r\n let h2 = 46 * 32 / w1;\r\n\r\n if(l == \"0\"){\r\n can.drawImage(luckysheet_CFiconsImg, 0, t * 32, w1, h1, 0, (18 - h2) / 2, w2, h2);\r\n }\r\n else if(l == \"5\"){\r\n can.drawImage(luckysheet_CFiconsImg, 210, t * 32, w1, h1, 0, (18 - h2) / 2, w2, h2);\r\n }\r\n }\r\n })\r\n\r\n $(\"#luckysheet-administerRule-dialog .ruleList .listBox .item\").eq(0).addClass(\"on\");\r\n }\r\n },\r\n getConditionRuleName: function(conditionName, conditionRange, conditionValue){\r\n //v 有条件单元格取条件单元格,若无取条件值\r\n let v\r\n if(conditionRange[0]!=null){\r\n v = chatatABC(conditionRange[0][\"column\"][0]) + (conditionRange[0][\"row\"][0] + 1);\r\n }\r\n else{\r\n v = conditionValue[0];\r\n }\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n //返回条件格式规则名称\r\n if(conditionName == \"greaterThan\"){\r\n return conditionformat_Text.cellValue + \" > \" + v;\r\n }\r\n else if(conditionName == \"lessThan\"){\r\n return conditionformat_Text.cellValue + \" < \" + v;\r\n }\r\n else if(conditionName == \"betweenness\"){\r\n let v2;\r\n if(conditionRange[1] != null){\r\n v2 = chatatABC(conditionRange[1][\"column\"][0]) + (conditionRange[1][\"row\"][0] + 1);\r\n }\r\n else{\r\n v2 = conditionValue[1];\r\n }\r\n return conditionformat_Text.cellValue + \" \" + conditionformat_Text.between + \" \" + v + \" \" + conditionformat_Text.in + \" \" + v2 + \" \" + conditionformat_Text.between2;\r\n }\r\n else if(conditionName == \"equal\"){\r\n return conditionformat_Text.cellValue + \" = \" + v;\r\n }\r\n else if(conditionName == \"textContains\"){\r\n return conditionformat_Text.cellValue + conditionformat_Text.contain + \" =\" + v;\r\n }\r\n else if(conditionName == \"occurrenceDate\"){\r\n return conditionValue;\r\n }\r\n else if(conditionName == \"duplicateValue\"){\r\n if(conditionValue == \"0\"){\r\n return conditionformat_Text.duplicateValue;\r\n }\r\n if(conditionValue == \"1\"){\r\n return conditionformat_Text.uniqueValue;\r\n }\r\n }\r\n else if(conditionName == \"top10\"){\r\n return conditionformat_Text.top + \" \" + v + \" \" + conditionformat_Text.oneself;\r\n }\r\n else if(conditionName == \"top10%\"){\r\n return conditionformat_Text.top + \" \" + v + \"% \" + conditionformat_Text.oneself;\r\n }\r\n else if(conditionName == \"last10\"){\r\n return conditionformat_Text.last + \" \" + v + \" \" + conditionformat_Text.oneself;\r\n }\r\n else if(conditionName == \"last10%\"){\r\n return conditionformat_Text.last + \" \" + v + \"% \" + conditionformat_Text.oneself;\r\n }\r\n else if(conditionName == \"AboveAverage\"){\r\n return conditionformat_Text.aboveAverage;\r\n }\r\n else if(conditionName == \"SubAverage\"){\r\n return conditionformat_Text.belowAverage;\r\n }\r\n else if(conditionName == \"formula\"){\r\n if(v.slice(0, 1) != '='){\r\n v = '=' + v;\r\n }\r\n\r\n return conditionformat_Text.formula + ': ' + v;\r\n }\r\n },\r\n newConditionRuleDialog: function(source){\r\n let _this = this;\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n //规则说明\r\n let ruleExplainHtml = _this.getRuleExplain(0);\r\n\r\n //弹出层\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-administerRule-dialog\").hide();\r\n $(\"#luckysheet-newConditionRule-dialog\").remove();\r\n\r\n let content = '
' +\r\n '
' + conditionformat_Text.chooseRuleType + ':
' +\r\n _this.ruleTypeHtml() +\r\n '
' + conditionformat_Text.editRuleDescription + ':
' +\r\n '
' +\r\n ruleExplainHtml +\r\n '
' +\r\n '
';\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-newConditionRule-dialog\",\r\n \"addclass\": \"luckysheet-newEditorRule-dialog\",\r\n \"title\": conditionformat_Text.newFormatRule,\r\n \"content\": content,\r\n \"botton\": `\r\n `,\r\n \"style\": \"z-index:100003\"\r\n }));\r\n let $t = $(\"#luckysheet-newConditionRule-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 400)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-newConditionRule-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n\r\n //index的规则类型focus\r\n $(\"#luckysheet-newConditionRule-dialog .ruleTypeBox .ruleTypeItem:eq(0)\").addClass(\"on\").siblings().removeClass(\"on\");\r\n\r\n _this.colorSelectInit();\r\n },\r\n editorConditionRuleDialog: function(){\r\n let _this = this;\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n let rule = _this.editorRule.data;\r\n\r\n if(rule == null){\r\n return;\r\n }\r\n\r\n let ruleType = rule[\"type\"],\r\n ruleFormat = rule[\"format\"],\r\n conditionName = rule[\"conditionName\"];\r\n\r\n let index, type1;\r\n if(ruleType == \"dataBar\" || ruleType == \"colorGradation\" || ruleType == \"icons\"){\r\n index = 0;\r\n type1 = ruleType;\r\n }\r\n else{\r\n if(conditionName == \"greaterThan\" || conditionName == \"lessThan\" || conditionName == \"betweenness\" || conditionName == \"equal\" || conditionName == \"textContains\" || conditionName == \"occurrenceDate\"){\r\n index = 1;\r\n\r\n if(conditionName == \"greaterThan\" || conditionName == \"lessThan\" || conditionName == \"betweenness\" || conditionName == \"equal\"){\r\n type1 = \"number\";\r\n }\r\n else if(conditionName == \"textContains\"){\r\n type1 = \"text\";\r\n }\r\n else if(conditionName == \"occurrenceDate\"){\r\n type1 = \"date\";\r\n }\r\n }\r\n else if(conditionName == \"top10\" || conditionName == \"top10%\" || conditionName == \"last10\" || conditionName == \"last10%\"){\r\n index = 2;\r\n\r\n if(conditionName == \"top10\" || conditionName == \"top10%\"){\r\n type1 = \"top\";\r\n }\r\n else if(conditionName == \"last10\" || conditionName == \"last10%\"){\r\n type1 = \"last\";\r\n }\r\n }\r\n else if(conditionName == \"AboveAverage\" || conditionName == \"SubAverage\"){\r\n index = 3;\r\n type1 = conditionName;\r\n }\r\n else if(conditionName == \"duplicateValue\"){\r\n index = 4;\r\n type1 = rule[\"conditionValue\"];\r\n }\r\n else if(conditionName == \"formula\"){\r\n index = 5;\r\n }\r\n }\r\n\r\n //规则说明\r\n let ruleExplainHtml = _this.getRuleExplain(index);\r\n\r\n //弹出层\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-administerRule-dialog\").hide();\r\n $(\"#luckysheet-editorConditionRule-dialog\").remove();\r\n\r\n let content = '
' +\r\n '
'+ conditionformat_Text.chooseRuleType +':
' +\r\n _this.ruleTypeHtml() +\r\n '
'+ conditionformat_Text.editRuleDescription +':
' +\r\n '
' +\r\n ruleExplainHtml +\r\n '
' +\r\n '
';\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-editorConditionRule-dialog\",\r\n \"addclass\": \"luckysheet-newEditorRule-dialog\",\r\n \"title\": conditionformat_Text.editFormatRule,\r\n \"content\": content,\r\n \"botton\": `\r\n `,\r\n \"style\": \"z-index:100003\"\r\n }));\r\n let $t = $(\"#luckysheet-editorConditionRule-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 400)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-editorConditionRule-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n\r\n _this.colorSelectInit();\r\n\r\n //规则类型focus\r\n $(\"#luckysheet-editorConditionRule-dialog .ruleTypeBox .ruleTypeItem:eq(\" + index + \")\").addClass(\"on\").siblings().removeClass(\"on\");\r\n\r\n //type1\r\n $(\"#luckysheet-editorConditionRule-dialog #type1\").val(type1);\r\n if(type1 == \"dataBar\" || type1 == \"colorGradation\" || type1 == \"icons\" || type1 == \"number\" || type1 == \"text\" || type1 == \"date\"){\r\n $(\"#luckysheet-editorConditionRule-dialog .\" + type1 + \"Box\").show();\r\n $(\"#luckysheet-editorConditionRule-dialog .\" + type1 + \"Box\").siblings().hide();\r\n }\r\n\r\n if(type1 == \"date\"){\r\n _this.daterangeInit(\"luckysheet-editorConditionRule-dialog\");\r\n }\r\n\r\n //type2 format value\r\n if(ruleType == \"dataBar\" || ruleType == \"colorGradation\" || ruleType == \"icons\"){\r\n if(type1 == \"dataBar\"){\r\n if(ruleFormat.length == 2){\r\n $(\"#luckysheet-editorConditionRule-dialog .dataBarBox #type2\").val(\"gradient\");\r\n }\r\n else if(ruleFormat.length == 1){\r\n $(\"#luckysheet-editorConditionRule-dialog .dataBarBox #type2\").val(\"solid\");\r\n }\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .dataBarBox .luckysheet-conditionformat-config-color\").spectrum(\"set\", ruleFormat[0]);\r\n }\r\n else if(type1 == \"colorGradation\"){\r\n if(ruleFormat.length == 3){\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox #type2\").val(\"threeColor\");\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox .midVal\").show();\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox .maxVal .luckysheet-conditionformat-config-color\").spectrum(\"set\", ruleFormat[0]);\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox .midVal .luckysheet-conditionformat-config-color\").spectrum(\"set\", ruleFormat[1]);\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox .minVal .luckysheet-conditionformat-config-color\").spectrum(\"set\", ruleFormat[2]);\r\n }\r\n else if(ruleFormat.length == 2){\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox #type2\").val(\"twoColor\");\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox .midVal\").hide();\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox .maxVal .luckysheet-conditionformat-config-color\").spectrum(\"set\", ruleFormat[0]);\r\n $(\"#luckysheet-editorConditionRule-dialog .colorGradationBox .minVal .luckysheet-conditionformat-config-color\").spectrum(\"set\", ruleFormat[1]);\r\n }\r\n }\r\n else if(type1 == \"icons\"){\r\n let len = ruleFormat[\"len\"];\r\n let l = ruleFormat[\"leftMin\"];\r\n let t = ruleFormat[\"top\"];\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .iconsBox li\").each(function(i, e){\r\n if($(e).find(\"div\").attr(\"data-len\") == len && $(e).find(\"div\").attr(\"data-leftmin\") == l && $(e).find(\"div\").attr(\"data-top\") == t){\r\n $(\"#luckysheet-editorConditionRule-dialog .iconsBox .showbox .model\").css(\"background-position\", $(e).find(\"div\").css(\"background-position\"));\r\n $(\"#luckysheet-editorConditionRule-dialog .iconsBox .showbox .model\").attr(\"data-len\", $(e).find(\"div\").attr(\"data-len\"));\r\n $(\"#luckysheet-editorConditionRule-dialog .iconsBox .showbox .model\").attr(\"data-leftmin\", $(e).find(\"div\").attr(\"data-leftmin\"));\r\n $(\"#luckysheet-editorConditionRule-dialog .iconsBox .showbox .model\").attr(\"data-top\", $(e).find(\"div\").attr(\"data-leftmin\"));\r\n $(\"#luckysheet-editorConditionRule-dialog .iconsBox .showbox .model\").attr(\"title\", $(e).find(\"div\").attr(\"title\"));\r\n\r\n return true;\r\n }\r\n });\r\n }\r\n }\r\n else{\r\n if(type1 == \"number\"){\r\n $(\"#luckysheet-editorConditionRule-dialog .numberBox #type2\").val(conditionName);\r\n\r\n let val1;\r\n if(rule.conditionRange[0] != null){\r\n val1 = getRangetxt(Store.currentSheetIndex, { \"row\": rule.conditionRange[0][\"row\"], \"column\": rule.conditionRange[0][\"column\"] }, Store.currentSheetIndex);\r\n }\r\n else{\r\n val1 = rule.conditionValue[0];\r\n }\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .numberBox #conditionVal input\").val(val1);\r\n\r\n if(conditionName == \"betweenness\"){\r\n $(\"#luckysheet-editorConditionRule-dialog .numberBox .txt\").show();\r\n $(\"#luckysheet-editorConditionRule-dialog .numberBox #conditionVal2\").show();\r\n\r\n let val2;\r\n if(rule.conditionRange[1] != null){\r\n val2 = getRangetxt(Store.currentSheetIndex, { \"row\": rule.conditionRange[1][\"row\"], \"column\": rule.conditionRange[1][\"column\"] }, Store.currentSheetIndex);\r\n }\r\n else{\r\n val2 = rule.conditionValue[1];\r\n }\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .numberBox #conditionVal2 input\").val(val2);\r\n }\r\n else{\r\n $(\"#luckysheet-editorConditionRule-dialog .numberBox .txt\").hide();\r\n $(\"#luckysheet-editorConditionRule-dialog .numberBox #conditionVal2\").hide();\r\n }\r\n }\r\n else if(type1 == \"text\"){\r\n let val1;\r\n if(rule.conditionRange[0] != null){\r\n val1 = getRangetxt(Store.currentSheetIndex, { \"row\": rule.conditionRange[0][\"row\"], \"column\": rule.conditionRange[0][\"column\"] }, Store.currentSheetIndex);\r\n }\r\n else{\r\n val1 = rule.conditionValue[0];\r\n }\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog .textBox #conditionVal input\").val(val1);\r\n }\r\n else if(type1 == \"date\"){\r\n _this.daterangeInit(\"luckysheet-editorConditionRule-dialog\");\r\n\r\n let val1 = rule.conditionValue[0];\r\n $(\"#luckysheet-editorConditionRule-dialog .dateBox #daterange-btn\").val(val1);\r\n }\r\n else if(type1 == \"top\" || type1 == \"last\"){\r\n let val1 = rule.conditionValue[0];\r\n\r\n if(conditionName == \"top10%\" || conditionName == \"last10%\"){\r\n $(\"#luckysheet-editorConditionRule-dialog #isPercent\").attr(\"checked\", \"checked\");\r\n }\r\n }\r\n else{\r\n if(conditionName == \"formula\"){\r\n let val1 = rule.conditionValue[0];\r\n $(\"#luckysheet-editorConditionRule-dialog #formulaConditionVal input\").val(val1);\r\n }\r\n }\r\n\r\n $(\"#luckysheet-editorConditionRule-dialog #textcolorshow\").spectrum(\"set\", ruleFormat.textColor);\r\n $(\"#luckysheet-editorConditionRule-dialog #cellcolorshow\").spectrum(\"set\", ruleFormat.cellColor);\r\n }\r\n },\r\n infoDialog: function(title, content){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-conditionformat-info-dialog\").remove();\r\n $(\"body\").append(replaceHtml(modelHTML, {\r\n \"id\": \"luckysheet-conditionformat-info-dialog\",\r\n \"addclass\": \"\",\r\n \"title\": title,\r\n \"content\": content,\r\n \"botton\": ``,\r\n \"style\": \"z-index:100003\"\r\n }));\r\n let $t = $(\"#luckysheet-conditionformat-info-dialog\")\r\n .find(\".luckysheet-modal-dialog-content\")\r\n .css(\"min-width\", 300)\r\n .end(),\r\n myh = $t.outerHeight(),\r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-conditionformat-info-dialog\").css({\r\n \"left\": (winw + scrollLeft - myw) / 2,\r\n \"top\": (winh + scrollTop - myh) / 3\r\n }).show();\r\n },\r\n getRuleExplain: function(index){\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n let textCellColorHtml = this.textCellColorHtml();\r\n\r\n let ruleExplainHtml;\r\n switch(index){\r\n case 0: //基于各自值设置所有单元格的格式\r\n ruleExplainHtml = `
${conditionformat_Text.ruleTypeItem1}:
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n \r\n
\r\n
`;\r\n break;\r\n case 1: //只为包含以下内容的单元格设置格式\r\n ruleExplainHtml = `
${conditionformat_Text.ruleTypeItem2_title}:
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n ${conditionformat_Text.in}\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
${conditionformat_Text.setFormat}:
${textCellColorHtml}`;\r\n break;\r\n case 2: //仅对排名靠前或靠后的数值设置格式\r\n ruleExplainHtml = `
${conditionformat_Text.ruleTypeItem3_title}:
\r\n
\r\n \r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n
${conditionformat_Text.setFormat}:
${textCellColorHtml}`;\r\n break;\r\n case 3: //仅对高于或低于平均值的数值设置格式\r\n ruleExplainHtml = `
${conditionformat_Text.ruleTypeItem4_title}:
\r\n
\r\n \r\n ${conditionformat_Text.selectRange_average}\r\n
\r\n
${conditionformat_Text.setFormat}:
${textCellColorHtml}`;\r\n break;\r\n case 4: //仅对唯一值或重复值设置格式\r\n ruleExplainHtml = `
${conditionformat_Text.all}:
\r\n
\r\n \r\n ${conditionformat_Text.selectRange_value}\r\n
\r\n
${conditionformat_Text.setFormat}:
${textCellColorHtml}`;\r\n break;\r\n case 5: //使用公式确定要设置格式的单元格\r\n ruleExplainHtml = `
${conditionformat_Text.ruleTypeItem2_title}:
\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
${conditionformat_Text.setFormat}:
${textCellColorHtml}`;\r\n break;\r\n }\r\n\r\n return ruleExplainHtml;\r\n },\r\n daterangeInit: function(id){\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n //日期选择插件\r\n $('.ranges_1 ul').remove();\r\n $('#' + id).find(\"#daterange-btn\").flatpickr({\r\n mode: \"range\",\r\n onChange: function (data, label) {\r\n const [start, end] = data\r\n //label:通过它来知道用户选择的是什么,传给后台进行相应的展示\r\n let format1 = [\r\n conditionformat_Text.yesterday,\r\n conditionformat_Text.today\r\n ];\r\n\r\n let format2 = [\r\n conditionformat_Text.lastWeek,\r\n conditionformat_Text.thisWeek,\r\n conditionformat_Text.lastMonth,\r\n conditionformat_Text.thisMonth,\r\n conditionformat_Text.lastYear,\r\n conditionformat_Text.thisYear,\r\n conditionformat_Text.last7days,\r\n conditionformat_Text.last30days\r\n ]\r\n\r\n if (label == conditionformat_Text.all) {\r\n $('#daterange-btn').val('');\r\n } else if (format1.indexOf(label) > -1) {\r\n $('#daterange-btn').val(dayjs(start).format('YYYY/MM/DD'));\r\n } else if (format2.indexOf(label) > -1) {\r\n $('#daterange-btn').val(dayjs(start).format('YYYY/MM/DD') + '-' + dayjs(end).format('YYYY/MM/DD'));\r\n }\r\n }\r\n });\r\n },\r\n CFSplitRange: function(range1, range2, range3, type){\r\n let range = [];\r\n\r\n let offset_r = range3[\"row\"][0] - range2[\"row\"][0];\r\n let offset_c = range3[\"column\"][0] - range2[\"column\"][0];\r\n\r\n let r1 = range1[\"row\"][0], r2 = range1[\"row\"][1];\r\n let c1 = range1[\"column\"][0], c2 = range1[\"column\"][1];\r\n\r\n if(r1 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1] && c1 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 全部\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r1 >= range2[\"row\"][0] && r1 <= range2[\"row\"][1] && c1 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1]){\r\n //选区 行贯穿 条件格式应用范围 上部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r2 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1] && c1 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1]){\r\n //选区 行贯穿 条件格式应用范围 下部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r1 < range2[\"row\"][0] && r2 > range2[\"row\"][1] && c1 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1]){\r\n //选区 行贯穿 条件格式应用范围 中间部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(c1 >= range2[\"column\"][0] && c1 <= range2[\"column\"][1] && r1 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1]){\r\n //选区 列贯穿 条件格式应用范围 左部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [range2[\"column\"][1] + 1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(c2 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1] && r1 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1]){\r\n //选区 列贯穿 条件格式应用范围 右部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [c1, range2[\"column\"][0] - 1] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(c1 < range2[\"column\"][0] && c2 > range2[\"column\"][1] && r1 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1]){\r\n //选区 列贯穿 条件格式应用范围 中间部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [r1, r2], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [r1, r2], \"column\": [range2[\"column\"][1] + 1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r1 >= range2[\"row\"][0] && r1 <= range2[\"row\"][1] && c1 >= range2[\"column\"][0] && c1 <= range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 左上角部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r1 >= range2[\"row\"][0] && r1 <= range2[\"row\"][1] && c2 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 右上角部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r2 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1] && c1 >= range2[\"column\"][0] && c1 <= range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 左下角部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [range2[\"column\"][1] + 1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r2 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1] && c2 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 右下角部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [c1, range2[\"column\"][0] - 1] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r1 < range2[\"row\"][0] && r2 > range2[\"row\"][1] && c1 >= range2[\"column\"][0] && c1 <= range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 左中间部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [c1 + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r1 < range2[\"row\"][0] && r2 > range2[\"row\"][1] && c2 >= range2[\"column\"][0] && c2 <= range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 右中间部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, c2 + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(c1 < range2[\"column\"][0] && c2 > range2[\"column\"][1] && r1 >= range2[\"row\"][0] && r1 <= range2[\"row\"][1]){\r\n //选区 包含 条件格式应用范围 上中间部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [r1, range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [r1 + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(c1 < range2[\"column\"][0] && c2 > range2[\"column\"][1] && r2 >= range2[\"row\"][0] && r2 <= range2[\"row\"][1]){\r\n //选区 包含 条件格式应用范围 下中间部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][0], r2], \"column\": [range2[\"column\"][1] + 1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, r2 + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else if(r1 < range2[\"row\"][0] && r2 > range2[\"row\"][1] && c1 < range2[\"column\"][0] && c2 > range2[\"column\"][1]){\r\n //选区 包含 条件格式应用范围 正中间部分\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, range2[\"row\"][0] - 1], \"column\": [c1, c2] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [c1, range2[\"column\"][0] - 1] },\r\n { \"row\": [range2[\"row\"][0], range2[\"row\"][1]], \"column\": [range2[\"column\"][1] + 1, c2] },\r\n { \"row\": [range2[\"row\"][1] + 1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [\r\n { \"row\": [range2[\"row\"][0] + offset_r, range2[\"row\"][1] + offset_r], \"column\": [range2[\"column\"][0] + offset_c, range2[\"column\"][1] + offset_c] }\r\n ];\r\n }\r\n }\r\n else{\r\n //选区 在 条件格式应用范围 之外\r\n\r\n if(type == \"allPart\"){ //所有部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"restPart\"){ //剩余部分\r\n range = [\r\n { \"row\": [r1, r2], \"column\": [c1, c2] }\r\n ];\r\n }\r\n else if(type == \"operatePart\"){ //操作部分\r\n range = [];\r\n }\r\n }\r\n\r\n return range;\r\n },\r\n getcolorGradation: function(color1, color2, value1, value2, value){\r\n let rgb1 = color1.split(',');\r\n let r1 = parseInt(rgb1[0].split('(')[1]);\r\n let g1 = parseInt(rgb1[1]);\r\n let b1 = parseInt(rgb1[2].split(')')[0]);\r\n\r\n let rgb2 = color2.split(',');\r\n let r2 = parseInt(rgb2[0].split('(')[1]);\r\n let g2 = parseInt(rgb2[1]);\r\n let b2 = parseInt(rgb2[2].split(')')[0]);\r\n\r\n let r = Math.round(r1 - (r1 - r2) / (value1 - value2) * (value1 - value));\r\n let g = Math.round(g1 - (g1 - g2) / (value1 - value2) * (value1 - value));\r\n let b = Math.round(b1 - (b1 - b2) / (value1 - value2) * (value1 - value));\r\n\r\n return \"rgb(\"+ r +\", \"+ g +\", \"+ b +\")\";\r\n },\r\n getCFPartRange: function(sheetIndex, range1, range2){\r\n let ruleArr = [];\r\n\r\n let cf = Store.luckysheetfile[getSheetIndex(sheetIndex)].luckysheet_conditionformat_save;\r\n if(cf != null && cf.length > 0){\r\n label: for(let i = 0; i < cf.length; i++){\r\n let cellrange = cf[i].cellrange;\r\n\r\n for(let j = 0; j < cellrange.length; j++){\r\n let r1 = cellrange[j].row[0], r2 = cellrange[j].row[1];\r\n let c1 = cellrange[j].column[0], c2 = cellrange[j].column[1];\r\n\r\n for(let s = 0; s < range.length; s++){\r\n if((range[s].row[0] >= r1 && range[s].row[0] <= r2) || (range[s].row[1] >= r1 && range[s].row[1] <= r2) || (range[s].column[0] >= c1 && range[s].column[0] <= c2) || (range[s].column[1] >= c1 && range[s].column[1] <= c2)){\r\n ruleArr.push(cf[i]);\r\n\r\n continue label;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return ruleArr;\r\n },\r\n checksCF: function(r, c, computeMap){\r\n if(computeMap != null && (r + \"_\" + c) in computeMap){\r\n return computeMap[r + \"_\" + c];\r\n }\r\n else{\r\n return null;\r\n }\r\n },\r\n getComputeMap: function(sheetIndex){\r\n let index = getSheetIndex(Store.currentSheetIndex);\r\n\r\n if(sheetIndex != null){\r\n index = getSheetIndex(sheetIndex);\r\n }\r\n\r\n let ruleArr = Store.luckysheetfile[index][\"luckysheet_conditionformat_save\"];\r\n let data = Store.luckysheetfile[index][\"data\"];\r\n\r\n if(data == null){\r\n return null;\r\n }\r\n\r\n let computeMap = this.compute(ruleArr, data);\r\n\r\n return computeMap;\r\n },\r\n compute: function(ruleArr, d){\r\n let _this = this;\r\n\r\n if(ruleArr == null){\r\n ruleArr = [];\r\n }\r\n\r\n //条件计算存储\r\n let computeMap = {};\r\n\r\n if(ruleArr.length > 0){\r\n for(let i = 0; i < ruleArr.length; i++){\r\n let type = ruleArr[i][\"type\"];\r\n let cellrange = ruleArr[i][\"cellrange\"];\r\n let format = ruleArr[i][\"format\"];\r\n\r\n if(type == \"dataBar\"){ //数据条\r\n let max = null, min = null;\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(max == null || parseInt(cell.v) > max){\r\n max = parseInt(cell.v);\r\n }\r\n\r\n if(min == null || parseInt(cell.v) < min){\r\n min = parseInt(cell.v);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(max != null && min != null){\r\n if(min < 0){ //选区范围内有负数\r\n let plusLen = Math.round(max / (max - min) * 10) / 10; //正数所占比\r\n let minusLen = Math.round(Math.abs(min) / (max - min) * 10) / 10; //负数所占比\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(parseInt(cell.v) < 0){ //负数\r\n let valueLen = Math.round(Math.abs(parseInt(cell.v)) / Math.abs(min) * 100) / 100;\r\n\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"dataBar\"] = { \"valueType\": \"minus\", \"minusLen\": minusLen, \"valueLen\": valueLen, \"format\": format };\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"dataBar\": { \"valueType\": \"minus\", \"minusLen\": minusLen, \"valueLen\": valueLen, \"format\": format } };\r\n }\r\n }\r\n\r\n if(parseInt(cell.v) > 0){ //正数\r\n let valueLen = Math.round(parseInt(cell.v) / max * 100) / 100;\r\n\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"dataBar\"] = { \"valueType\": \"plus\", \"plusLen\": plusLen, \"minusLen\": minusLen, \"valueLen\": valueLen, \"format\": format };\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"dataBar\": { \"valueType\": \"plus\", \"plusLen\": plusLen, \"minusLen\": minusLen, \"valueLen\": valueLen, \"format\": format } };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n let plusLen = 1;\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n let valueLen;\r\n if(max == 0){\r\n valueLen = 1;\r\n }\r\n else{\r\n valueLen = Math.round(parseInt(cell.v) / max * 100) / 100;\r\n }\r\n\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"dataBar\"] = { \"valueType\": \"plus\", \"plusLen\": plusLen, \"valueLen\": valueLen, \"format\": format };\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"dataBar\": { \"valueType\": \"plus\", \"plusLen\": plusLen, \"valueLen\": valueLen, \"format\": format } };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"colorGradation\"){ //色阶\r\n let max = null, min = null, sum = 0, count = 0;\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n count++;\r\n sum += parseInt(cell.v);\r\n\r\n if(max == null || parseInt(cell.v) > max){\r\n max = parseInt(cell.v);\r\n }\r\n\r\n if(min == null || parseInt(cell.v) < min){\r\n min = parseInt(cell.v);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(max != null && min != null){\r\n if(format.length == 3){ //三色色阶\r\n let avg = Math.floor(sum / count);\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(parseInt(cell.v) == min){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = format[2];\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": format[2] };\r\n }\r\n }\r\n else if(parseInt(cell.v) > min && parseInt(cell.v) < avg){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = _this.getcolorGradation(format[2], format[1], min, avg, parseInt(cell.v));\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": _this.getcolorGradation(format[2], format[1], min, avg, parseInt(cell.v)) };\r\n }\r\n }\r\n else if(parseInt(cell.v) == avg){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = format[1];\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": format[1] };\r\n }\r\n }\r\n else if(parseInt(cell.v) > avg && parseInt(cell.v) < max){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = _this.getcolorGradation(format[1], format[0], avg, max, parseInt(cell.v));\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": _this.getcolorGradation(format[1], format[0], avg, max, parseInt(cell.v)) };\r\n }\r\n }\r\n else if(parseInt(cell.v) == max){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = format[0];\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": format[0] };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(format.length == 2){ //两色色阶\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(parseInt(cell.v) == min){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = format[1];\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": format[1] };\r\n }\r\n }\r\n else if(parseInt(cell.v) > min && parseInt(cell.v) < max){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = _this.getcolorGradation(format[1], format[0], min, max, parseInt(cell.v));\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": _this.getcolorGradation(format[1], format[0], min, max, parseInt(cell.v)) };\r\n }\r\n }\r\n else if(parseInt(cell.v) == max){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"cellColor\"] = format[0];\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"cellColor\": format[0] };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"icons\"){ //图标集\r\n let len = parseInt(format[\"len\"]);\r\n let leftMin = parseInt(format[\"leftMin\"]);\r\n let top = parseInt(format[\"top\"]);\r\n\r\n let max = null, min = null;\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(max == null || parseInt(cell.v) > max){\r\n max = parseInt(cell.v);\r\n }\r\n\r\n if(min == null || parseInt(cell.v) < min){\r\n min = parseInt(cell.v);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(max != null && min != null){\r\n let a = Math.floor((max - min + 1) / len);\r\n let b = (max - min + 1) % len;\r\n\r\n if(len == 3){ //一组图标有三个\r\n let v1, v2, v3;\r\n if(b == 2){\r\n v1 = [min, min + a];\r\n v2 = [min + a + 1, min + a * 2];\r\n v3 = [min + a * 2 + 1, max];\r\n }\r\n else{\r\n v1 = [min, min + a - 1];\r\n v2 = [min + a, min + a * 2 - 1];\r\n v3 = [min + a * 2, max];\r\n }\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(parseInt(cell.v) >= v1[0] && parseInt(cell.v) <= v1[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 2, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 2, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v2[0] && parseInt(cell.v) <= v2[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 1, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 1, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v3[0] && parseInt(cell.v) <= v3[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin, \"top\": top} };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(len == 4){ //一组图标有四个\r\n let v1, v2, v3, v4;\r\n if(b == 2){\r\n v1 = [min, min + a];\r\n v2 = [min + a + 1, min + a * 2];\r\n v3 = [min + a * 2 + 1, min + a * 3];\r\n v4 = [min + a * 3 + 1, max];\r\n }\r\n else if(b == 3){\r\n v1 = [min, min + a];\r\n v2 = [min + a + 1, min + a * 2];\r\n v3 = [min + a * 2 + 1, min + a * 3 + 1];\r\n v4 = [min + a * 3 + 2, max];\r\n }\r\n else{\r\n v1 = [min, min + a - 1];\r\n v2 = [min + a, min + a * 2 - 1];\r\n v3 = [min + a * 2, min + a * 3 - 1];\r\n v4 = [min + a * 3, max];\r\n }\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(parseInt(cell.v) >= v1[0] && parseInt(cell.v) <= v1[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 3, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 3, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v2[0] && parseInt(cell.v) <= v2[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 2, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 2, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v3[0] && parseInt(cell.v) <= v3[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 1, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 1, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v4[0] && parseInt(cell.v) <= v4[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin, \"top\": top} };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(len == 5){ //一组图标有五个\r\n let v1, v2, v3, v4, v5;\r\n if(b == 2){\r\n v1 = [min, min + a];\r\n v2 = [min + a + 1, min + a * 2];\r\n v3 = [min + a * 2 + 1, min + a * 3];\r\n v4 = [min + a * 3 + 1, min + a * 4];\r\n v5 = [min + a * 4 + 1, max];\r\n }\r\n else if(b == 3){\r\n v1 = [min, min + a];\r\n v2 = [min + a + 1, min + a * 2];\r\n v3 = [min + a * 2 + 1, min + a * 3 + 1];\r\n v4 = [min + a * 3 + 2, min + a * 4 + 1];\r\n v5 = [min + a * 4 + 2, max];\r\n }\r\n else if(b == 4){\r\n v1 = [min, min + a];\r\n v2 = [min + a + 1, min + a * 2 + 1];\r\n v3 = [min + a * 2 + 2, min + a * 3 + 1];\r\n v4 = [min + a * 3 + 2, min + a * 4 + 2];\r\n v5 = [min + a * 4 + 3, max];\r\n }\r\n else{\r\n v1 = [min, min + a - 1];\r\n v2 = [min + a, min + a * 2 - 1];\r\n v3 = [min + a * 2, min + a * 3 - 1];\r\n v4 = [min + a * 3, min + a * 4 - 1];\r\n v5 = [min + a * 4, max];\r\n }\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && cell[\"ct\"] != null && cell[\"ct\"].t == \"n\" && cell.v != null){\r\n if(parseInt(cell.v) >= v1[0] && parseInt(cell.v) <= v1[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 4, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 4, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v2[0] && parseInt(cell.v) <= v2[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 3, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 3, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v3[0] && parseInt(cell.v) <= v3[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 2, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 2, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v4[0] && parseInt(cell.v) <= v4[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin + 1, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin + 1, \"top\": top} };\r\n }\r\n }\r\n else if(parseInt(cell.v) >= v5[0] && parseInt(cell.v) <= v5[1]){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"icons\"] = {\"left\": leftMin, \"top\": top};\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"icons\": {\"left\": leftMin, \"top\": top} };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n //获取变量值\r\n let conditionName = ruleArr[i].conditionName, //条件名称\r\n conditionValue0 = ruleArr[i].conditionValue[0], //条件值1\r\n conditionValue1 = ruleArr[i].conditionValue[1], //条件值2\r\n textColor = format.textColor, //条件格式文本颜色 fc\r\n cellColor = format.cellColor; //条件格式单元格颜色 bg\r\n\r\n for(let s = 0; s < cellrange.length; s++){\r\n //条件类型判断\r\n if(conditionName == \"greaterThan\" || conditionName == \"lessThan\" || conditionName == \"equal\" || conditionName == \"textContains\"){\r\n //循环应用范围计算\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n //单元格值\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) != \"object\" || isRealNull(cell.v)){\r\n continue;\r\n }\r\n\r\n //符合条件\r\n if(conditionName == \"greaterThan\" && cell.v > conditionValue0){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n else if(conditionName == \"lessThan\" && cell.v < conditionValue0){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n else if(conditionName == \"equal\" && cell.v == conditionValue0){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n else if(conditionName == \"textContains\" && cell.v.toString().indexOf(conditionValue0) != -1){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(conditionName == \"betweenness\"){\r\n //比较条件值1和条件值2的大小\r\n let vBig, vSmall;\r\n if(conditionValue0 > conditionValue1){\r\n vBig = conditionValue0;\r\n vSmall = conditionValue1;\r\n }\r\n else{\r\n vBig = conditionValue1;\r\n vSmall = conditionValue0;\r\n }\r\n //循环应用范围计算\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n //单元格值\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) != \"object\" || isRealNull(cell.v)){\r\n continue;\r\n }\r\n\r\n //符合条件\r\n if(cell.v >= vSmall && cell.v <= vBig){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(conditionName == \"occurrenceDate\"){\r\n //获取日期所对应的数值\r\n let dBig, dSmall;\r\n if(conditionValue0.toString().indexOf(\"-\") == -1){\r\n dBig = genarate(conditionValue0)[2];\r\n dSmall = genarate(conditionValue0)[2];\r\n }\r\n else{\r\n let str = conditionValue0.toString().split(\"-\");\r\n dBig = genarate(str[1].trim())[2];\r\n dSmall = genarate(str[0].trim())[2];\r\n }\r\n //循环应用范围计算\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n //单元格值类型为日期类型\r\n if(d[r][c].ct != null && d[r][c].ct.t == \"d\"){\r\n //单元格值\r\n let cellVal = getcellvalue(r, c, d);\r\n //符合条件\r\n if(cellVal >= dSmall && cellVal <= dBig){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(conditionName == \"duplicateValue\"){\r\n //应用范围单元格值处理\r\n let dmap = {};\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n let item = getcellvalue(r, c, d);\r\n if(!(item in dmap)){\r\n dmap[item] = [];\r\n }\r\n dmap[item].push({\"r\": r, \"c\": c});\r\n }\r\n }\r\n //循环应用范围计算\r\n if(conditionValue0 == \"0\"){//重复值\r\n for(let x in dmap){\r\n if(x != \"null\" && x != \"undefined\" && dmap[x].length > 1){\r\n for(let j = 0; j < dmap[x].length; j++){\r\n if((dmap[x][j].r + \"_\" + dmap[x][j].c) in computeMap){\r\n computeMap[dmap[x][j].r + \"_\" + dmap[x][j].c][\"textColor\"] = textColor;\r\n computeMap[dmap[x][j].r + \"_\" + dmap[x][j].c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[dmap[x][j].r + \"_\" + dmap[x][j].c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n if(conditionValue0 == \"1\"){//唯一值\r\n for(let x in dmap){\r\n if(x != \"null\" && x != \"undefined\" && dmap[x].length == 1){\r\n if((dmap[x][0].r + \"_\" + dmap[x][0].c) in computeMap){\r\n computeMap[dmap[x][0].r + \"_\" + dmap[x][0].c][\"textColor\"] = textColor;\r\n computeMap[dmap[x][0].r + \"_\" + dmap[x][0].c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[dmap[x][0].r + \"_\" + dmap[x][0].c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(conditionName == \"top10\" || conditionName == \"top10%\" || conditionName == \"last10\" || conditionName == \"last10%\" || conditionName == \"AboveAverage\" || conditionName == \"SubAverage\"){\r\n //应用范围单元格值(数值型)\r\n let dArr=[];\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n //单元格值类型为数字类型\r\n if(d[r][c].ct != null && d[r][c].ct.t == \"n\"){\r\n dArr.push(getcellvalue(r, c, d));\r\n }\r\n }\r\n }\r\n //数组处理\r\n if(conditionName == \"top10\" || conditionName == \"top10%\" || conditionName == \"last10\" || conditionName == \"last10%\"){\r\n //从大到小排序\r\n for(let j = 0; j < dArr.length; j++){\r\n for(let k = 0; k < dArr.length - 1 - j; k++){\r\n if(dArr[k] averageNum){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(conditionName == \"SubAverage\"){ //低于平均值\r\n for(let r = cellrange[s].row[0]; r <= cellrange[s].row[1]; r++){\r\n for(let c = cellrange[s].column[0]; c <= cellrange[s].column[1]; c++){\r\n if(d[r] == null || d[r][c] == null){\r\n continue;\r\n }\r\n\r\n //单元格值\r\n let cellVal = getcellvalue(r, c, d);\r\n //符合条件\r\n if(cellVal < averageNum){\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(conditionName == \"formula\"){\r\n let str = cellrange[s].row[0],\r\n edr = cellrange[s].row[1],\r\n stc = cellrange[s].column[0],\r\n edc = cellrange[s].column[1];\r\n\r\n let formulaTxt = conditionValue0;\r\n if(conditionValue0.toString().slice(0, 1) != '='){\r\n formulaTxt = '=' + conditionValue0;\r\n }\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = stc; c <= edc; c++){\r\n let func = formulaTxt;\r\n let offsetRow = r - str;\r\n let offsetCol = c - stc;\r\n\r\n if(offsetRow > 0){\r\n func = \"=\" + formula.functionCopy(func, \"down\", offsetRow);\r\n }\r\n\r\n if(offsetCol > 0){\r\n func = \"=\" + formula.functionCopy(func, \"right\", offsetCol);\r\n }\r\n\r\n let funcV = formula.execfunction(func);\r\n let v = funcV[1];\r\n\r\n if(typeof v != 'boolean'){\r\n v = !!Number(v);\r\n }\r\n\r\n if(!v){\r\n continue;\r\n }\r\n\r\n if((r + \"_\" + c) in computeMap){\r\n computeMap[r + \"_\" + c][\"textColor\"] = textColor;\r\n computeMap[r + \"_\" + c][\"cellColor\"] = cellColor;\r\n }\r\n else{\r\n computeMap[r + \"_\" + c] = { \"textColor\": textColor, \"cellColor\": cellColor };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return computeMap;\r\n },\r\n updateItem: function(type, cellrange, format){\r\n if(!checkProtectionFormatCells(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n let _this = this;\r\n let index = getSheetIndex(Store.currentSheetIndex);\r\n\r\n //保存之前的规则\r\n let fileH = $.extend(true, [], Store.luckysheetfile);\r\n let historyRules = _this.getHistoryRules(fileH);\r\n\r\n //保存当前的规则\r\n let ruleArr;\r\n if(type == \"delSheet\"){\r\n ruleArr = [];\r\n }\r\n else{\r\n let rule = {\r\n \"type\": type,\r\n \"cellrange\": cellrange,\r\n \"format\": format\r\n };\r\n ruleArr = Store.luckysheetfile[index][\"luckysheet_conditionformat_save\"] == null ? [] : Store.luckysheetfile[index][\"luckysheet_conditionformat_save\"];\r\n ruleArr.push(rule);\r\n }\r\n\r\n Store.luckysheetfile[index][\"luckysheet_conditionformat_save\"] = ruleArr;\r\n\r\n let fileC = $.extend(true, [], Store.luckysheetfile);\r\n let currentRules = _this.getCurrentRules(fileC);\r\n\r\n //刷新一次表格\r\n _this.ref(historyRules, currentRules);\r\n\r\n //发送给后台\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", Store.currentSheetIndex, ruleArr, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n },\r\n getHistoryRules: function(fileH){\r\n let historyRules = [];\r\n\r\n for(let h = 0; h < fileH.length; h++){\r\n historyRules.push({\"sheetIndex\": fileH[h][\"index\"], \"luckysheet_conditionformat_save\": fileH[h][\"luckysheet_conditionformat_save\"]});\r\n }\r\n\r\n return historyRules;\r\n },\r\n getCurrentRules: function(fileC){\r\n let currentRules = [];\r\n\r\n for(let c = 0; c < fileC.length; c++){\r\n currentRules.push({\"sheetIndex\": fileC[c][\"index\"], \"luckysheet_conditionformat_save\": fileC[c][\"luckysheet_conditionformat_save\"]});\r\n }\r\n\r\n return currentRules;\r\n },\r\n ref: function(historyRules, currentRules){\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let redo = {};\r\n redo[\"type\"] = \"updateCF\";\r\n redo[\"data\"] = {\"historyRules\": historyRules, \"currentRules\": currentRules};\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n}\r\n\r\nexport default conditionformat;\r\n","import { selectHightlightShow, selectionCopyShow } from './select';\r\nimport menuButton from './menuButton';\r\nimport conditionformat from './conditionformat';\r\nimport {checkProtectionLockedRangeList} from './protection';\r\nimport editor from '../global/editor';\r\nimport tooltip from '../global/tooltip';\r\nimport formula from '../global/formula';\r\nimport { getBorderInfoCompute } from '../global/border';\r\nimport { getdatabyselection, getcellvalue, datagridgrowth } from '../global/getdata';\r\nimport { rowlenByRange } from '../global/getRowlen';\r\nimport { isEditMode, hasPartMC, isRealNum } from '../global/validate';\r\nimport { jfrefreshgrid, jfrefreshgrid_pastcut } from '../global/refresh';\r\nimport { genarate, update } from '../global/format';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { replaceHtml, getObjType, luckysheetfontformat } from '../utils/util';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\nconst selection = {\r\n clearcopy: function (e) {\r\n let clipboardData = window.clipboardData; //for IE\r\n if (!clipboardData) { // for chrome\r\n if (!!e) {\r\n clipboardData = e.originalEvent.clipboardData;\r\n }\r\n }\r\n let cpdata = \" \";\r\n\r\n Store.luckysheet_selection_range = [];\r\n selectionCopyShow();\r\n // Store.luckysheet_copy_save = {};\r\n\r\n if (!clipboardData) {\r\n let textarea = $(\"#luckysheet-copy-content\").css(\"visibility\", \"hidden\");\r\n textarea.val(cpdata);\r\n textarea.focus();\r\n textarea.select();\r\n // 等50毫秒,keyPress事件发生了再去处理数据\r\n setTimeout(function () { textarea.blur().css(\"visibility\", \"visible\"); }, 10);\r\n }\r\n else {\r\n clipboardData.setData('Text', cpdata);\r\n return false;//否则设不生效\r\n }\r\n },\r\n getHtmlBorderStyle: function(type, color){\r\n let style = \"\";\r\n let borderType = {\r\n \"0\": \"none\",\r\n \"1\": \"Thin\",\r\n \"2\": \"Hair\",\r\n \"3\": \"Dotted\",\r\n \"4\": \"Dashed\",\r\n \"5\": \"DashDot\",\r\n \"6\": \"DashDotDot\",\r\n \"7\": \"Double\",\r\n \"8\": \"Medium\",\r\n \"9\": \"MediumDashed\",\r\n \"10\": \"MediumDashDot\",\r\n \"11\": \"MediumDashDotDot\",\r\n \"12\": \"SlantedDashDot\",\r\n \"13\": \"Thick\"\r\n };\r\n type = borderType[type.toString()];\r\n\r\n if(type.indexOf(\"Medium\") > -1){\r\n style += \"1pt \";\r\n }\r\n else if(type == \"Thick\"){\r\n style += \"1.5pt \";\r\n }\r\n else {\r\n style += \"0.5pt \";\r\n }\r\n\r\n if(type == \"Hair\"){\r\n style += \"double \";\r\n }\r\n else if(type.indexOf(\"DashDotDot\") > -1){\r\n style += \"dotted \";\r\n }\r\n else if(type.indexOf(\"DashDot\") > -1){\r\n style += \"dashed \";\r\n }\r\n else if(type.indexOf(\"Dotted\") > -1){\r\n style += \"dotted \";\r\n }\r\n else if(type.indexOf(\"Dashed\") > -1){\r\n style += \"dashed \";\r\n }\r\n else{\r\n style += \"solid \";\r\n }\r\n\r\n return style + color + \";\";\r\n },\r\n copy: function (e) {//copy事件\r\n let clipboardData = window.clipboardData; //for IE\r\n if (!clipboardData) { // for chrome\r\n clipboardData = e.originalEvent.clipboardData;\r\n }\r\n\r\n Store.luckysheet_selection_range = [];\r\n //copy范围\r\n let rowIndexArr = [], colIndexArr = [];\r\n let copyRange = [], RowlChange = false, HasMC = false;\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let range = Store.luckysheet_select_save[s];\r\n\r\n let r1 = range.row[0],\r\n r2 = range.row[1];\r\n let c1 = range.column[0],\r\n c2 = range.column[1];\r\n\r\n for(let copyR = r1; copyR <= r2; copyR++){\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][copyR] != null) {\r\n continue;\r\n }\r\n\r\n if(!rowIndexArr.includes(copyR)){\r\n rowIndexArr.push(copyR);\r\n }\r\n\r\n if (Store.config[\"rowlen\"] != null && (copyR in Store.config[\"rowlen\"])){\r\n RowlChange = true;\r\n }\r\n\r\n for(let copyC = c1; copyC <= c2; copyC++){\r\n if (Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][copyC] != null) {\r\n continue;\r\n }\r\n\r\n if(!colIndexArr.includes(copyC)){\r\n colIndexArr.push(copyC);\r\n }\r\n\r\n let cell = Store.flowdata[copyR][copyC];\r\n\r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell) && cell.mc.rs != null){\r\n HasMC = true;\r\n }\r\n }\r\n }\r\n\r\n Store.luckysheet_selection_range.push({ \"row\": range.row, \"column\": range.column });\r\n copyRange.push({ \"row\": range.row, \"column\": range.column });\r\n }\r\n\r\n selectionCopyShow();\r\n\r\n //luckysheet内copy保存\r\n Store.luckysheet_copy_save = {\r\n \"dataSheetIndex\": Store.currentSheetIndex,\r\n \"copyRange\": copyRange,\r\n \"RowlChange\": RowlChange,\r\n \"HasMC\": HasMC\r\n };\r\n\r\n //copy范围数据拼接成table 赋给剪贴板\r\n let _this = this;\r\n\r\n let borderInfoCompute;\r\n if(Store.config[\"borderInfo\"] && Store.config[\"borderInfo\"].length > 0){ //边框\r\n borderInfoCompute = getBorderInfoCompute();\r\n }\r\n\r\n let cpdata = \"\",\r\n d = editor.deepCopyFlowData(Store.flowdata);\r\n let colgroup = \"\";\r\n\r\n // rowIndexArr = rowIndexArr.sort();\r\n // colIndexArr = colIndexArr.sort();\r\n\r\n for (let i = 0; i < rowIndexArr.length; i++) {\r\n let r = rowIndexArr[i];\r\n\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n cpdata += '';\r\n\r\n for (let j = 0; j < colIndexArr.length; j++) {\r\n let c = colIndexArr[j];\r\n\r\n if (Store.config[\"colhidden\"] != null && Store.config[\"colhidden\"][c] != null) {\r\n continue;\r\n }\r\n\r\n let column = '';\r\n\r\n if (d[r] != null && d[r][c] != null) {\r\n let style = \"\", span = \"\";\r\n\r\n if(r == rowIndexArr[0]){\r\n if(Store.config == null || Store.config[\"columnlen\"] == null || Store.config[\"columnlen\"][c.toString()] == null){\r\n colgroup += '';\r\n }\r\n else {\r\n colgroup += '';\r\n }\r\n }\r\n\r\n if(c == colIndexArr[0]){\r\n if(Store.config == null || Store.config[\"rowlen\"] == null || Store.config[\"rowlen\"][r.toString()] == null){\r\n style += 'height:19px;';\r\n }\r\n else {\r\n style += 'height:'+ Store.config[\"rowlen\"][r.toString()] + 'px;';\r\n }\r\n }\r\n\r\n let reg = /^(w|W)((0?)|(0\\.0+))$/;\r\n let c_value;\r\n if(d[r][c].ct != null && d[r][c].ct.fa != null && d[r][c].ct.fa.match(reg)){\r\n c_value = getcellvalue(r, c, d);\r\n }\r\n else{\r\n c_value = getcellvalue(r, c, d, \"m\");\r\n }\r\n\r\n style += menuButton.getStyleByCell(d, r, c);\r\n\r\n if(getObjType(d[r][c]) == \"object\" && (\"mc\" in d[r][c])){\r\n if(\"rs\" in d[r][c][\"mc\"]){\r\n span = 'rowspan=\"'+ d[r][c][\"mc\"].rs +'\" colspan=\"'+ d[r][c][\"mc\"].cs +'\"';\r\n\r\n //边框\r\n if(borderInfoCompute && borderInfoCompute[r + \"_\" + c]){\r\n let bl_obj = { \"color\": {}, \"style\": {} },\r\n br_obj = { \"color\": {}, \"style\": {} },\r\n bt_obj = { \"color\": {}, \"style\": {} },\r\n bb_obj = { \"color\": {}, \"style\": {} };\r\n\r\n for(let bd_r = r; bd_r < (r + d[r][c][\"mc\"].rs); bd_r++){\r\n for(let bd_c = c; bd_c < (c + d[r][c][\"mc\"].cs); bd_c++){\r\n if(bd_r == r && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].t){\r\n let linetype = borderInfoCompute[bd_r + \"_\" + bd_c].t.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].t.color;\r\n\r\n if(bt_obj[\"style\"][linetype] == null){\r\n bt_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n bt_obj[\"style\"][linetype] = bt_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(bt_obj[\"color\"][bcolor] == null){\r\n bt_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n bt_obj[\"color\"][bcolor] = bt_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n\r\n if(bd_r == (r + d[r][c][\"mc\"].rs - 1) && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].b){\r\n let linetype = borderInfoCompute[bd_r + \"_\" + bd_c].b.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].b.color;\r\n\r\n if(bb_obj[\"style\"][linetype] == null){\r\n bb_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n bb_obj[\"style\"][linetype] = bb_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(bb_obj[\"color\"][bcolor] == null){\r\n bb_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n bb_obj[\"color\"][bcolor] = bb_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n\r\n if(bd_c == c && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].l){\r\n let linetype = borderInfoCompute[r + \"_\" + c].l.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].l.color;\r\n\r\n if(bl_obj[\"style\"][linetype] == null){\r\n bl_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n bl_obj[\"style\"][linetype] = bl_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(bl_obj[\"color\"][bcolor] == null){\r\n bl_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n bl_obj[\"color\"][bcolor] = bl_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n\r\n if(bd_c == (c + d[r][c][\"mc\"].cs - 1) && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].r){\r\n let linetype = borderInfoCompute[bd_r + \"_\" + bd_c].r.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].r.color;\r\n\r\n if(br_obj[\"style\"][linetype] == null){\r\n br_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n br_obj[\"style\"][linetype] = br_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(br_obj[\"color\"][bcolor] == null){\r\n br_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n br_obj[\"color\"][bcolor] = br_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n let rowlen = d[r][c][\"mc\"].rs, collen = d[r][c][\"mc\"].cs;\r\n\r\n if(JSON.stringify(bl_obj).length > 23){\r\n let bl_color = null, bl_style = null;\r\n\r\n for(let x in bl_obj.color){\r\n if(bl_obj.color[x] >= (rowlen / 2)){\r\n bl_color = x;\r\n }\r\n }\r\n\r\n for(let x in bl_obj.style){\r\n if(bl_obj.style[x] >= (rowlen / 2)){\r\n bl_style = x;\r\n }\r\n }\r\n\r\n if(bl_color != null && bl_style != null){\r\n style += \"border-left:\" + _this.getHtmlBorderStyle(bl_style, bl_color);\r\n }\r\n }\r\n\r\n if(JSON.stringify(br_obj).length > 23){\r\n let br_color = null, br_style = null;\r\n\r\n for(let x in br_obj.color){\r\n if(br_obj.color[x] >= (rowlen / 2)){\r\n br_color = x;\r\n }\r\n }\r\n\r\n for(let x in br_obj.style){\r\n if(br_obj.style[x] >= (rowlen / 2)){\r\n br_style = x;\r\n }\r\n }\r\n\r\n if(br_color != null && br_style != null){\r\n style += \"border-right:\" + _this.getHtmlBorderStyle(br_style, br_color);\r\n }\r\n }\r\n\r\n if(JSON.stringify(bt_obj).length > 23){\r\n let bt_color = null, bt_style = null;\r\n\r\n for(let x in bt_obj.color){\r\n if(bt_obj.color[x] >= (collen / 2)){\r\n bt_color = x;\r\n }\r\n }\r\n\r\n for(let x in bt_obj.style){\r\n if(bt_obj.style[x] >= (collen / 2)){\r\n bt_style = x;\r\n }\r\n }\r\n\r\n if(bt_color != null && bt_style != null){\r\n style += \"border-top:\" + _this.getHtmlBorderStyle(bt_style, bt_color);\r\n }\r\n }\r\n\r\n if(JSON.stringify(bb_obj).length > 23){\r\n let bb_color = null, bb_style = null;\r\n\r\n for(let x in bb_obj.color){\r\n if(bb_obj.color[x] >= (collen / 2)){\r\n bb_color = x;\r\n }\r\n }\r\n\r\n for(let x in bb_obj.style){\r\n if(bb_obj.style[x] >= (collen / 2)){\r\n bb_style = x;\r\n }\r\n }\r\n\r\n if(bb_color != null && bb_style != null){\r\n style += \"border-bottom:\" + _this.getHtmlBorderStyle(bb_style, bb_color);\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n continue;\r\n }\r\n }\r\n else{\r\n //边框\r\n if(borderInfoCompute && borderInfoCompute[r + \"_\" + c]){\r\n //左边框\r\n if(borderInfoCompute[r + \"_\" + c].l){\r\n let linetype = borderInfoCompute[r + \"_\" + c].l.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].l.color;\r\n style += \"border-left:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //右边框\r\n if(borderInfoCompute[r + \"_\" + c].r){\r\n let linetype = borderInfoCompute[r + \"_\" + c].r.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].r.color;\r\n style += \"border-right:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //下边框\r\n if(borderInfoCompute[r + \"_\" + c].b){\r\n let linetype = borderInfoCompute[r + \"_\" + c].b.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].b.color;\r\n style += \"border-bottom:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //上边框\r\n if(borderInfoCompute[r + \"_\" + c].t){\r\n let linetype = borderInfoCompute[r + \"_\" + c].t.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].t.color;\r\n style += \"border-top:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n }\r\n }\r\n\r\n column = replaceHtml(column, {\"style\": style, \"span\": span});\r\n\r\n if(c_value == null){\r\n c_value = getcellvalue(r, c, d);\r\n }\r\n\r\n if(c_value == null){\r\n c_value = \"\";\r\n }\r\n\r\n column += c_value;\r\n }\r\n else {\r\n let style = \"\";\r\n\r\n //边框\r\n if(borderInfoCompute && borderInfoCompute[r + \"_\" + c]){\r\n //左边框\r\n if(borderInfoCompute[r + \"_\" + c].l){\r\n let linetype = borderInfoCompute[r + \"_\" + c].l.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].l.color;\r\n style += \"border-left:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //右边框\r\n if(borderInfoCompute[r + \"_\" + c].r){\r\n let linetype = borderInfoCompute[r + \"_\" + c].r.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].r.color;\r\n style += \"border-right:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //下边框\r\n if(borderInfoCompute[r + \"_\" + c].b){\r\n let linetype = borderInfoCompute[r + \"_\" + c].b.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].b.color;\r\n style += \"border-bottom:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //上边框\r\n if(borderInfoCompute[r + \"_\" + c].t){\r\n let linetype = borderInfoCompute[r + \"_\" + c].t.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].t.color;\r\n style += \"border-top:\" + _this.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n }\r\n\r\n column += \"\";\r\n\r\n if(r == rowIndexArr[0]){\r\n if(Store.config == null || Store.config[\"columnlen\"] == null || Store.config[\"columnlen\"][c.toString()] == null){\r\n colgroup += '';\r\n }\r\n else {\r\n colgroup += '';\r\n }\r\n }\r\n\r\n if(c == colIndexArr[0]){\r\n if(Store.config == null || Store.config[\"rowlen\"] == null || Store.config[\"rowlen\"][r.toString()] == null){\r\n style += 'height:19px;';\r\n }\r\n else {\r\n style += 'height:'+ Store.config[\"rowlen\"][r.toString()] + 'px;';\r\n }\r\n }\r\n\r\n column = replaceHtml(column, {\"style\": style, \"span\": \"\"});\r\n column += \"\";\r\n }\r\n\r\n column += '';\r\n cpdata += column;\r\n }\r\n\r\n cpdata += \"\";\r\n }\r\n cpdata = '' + colgroup + cpdata + '
';\r\n\r\n Store.iscopyself = true;\r\n\r\n if (!clipboardData) {\r\n // let textarea = $(\"#luckysheet-copy-content\");\r\n // textarea.html(cpdata);\r\n // textarea.focus();\r\n // textarea.select();\r\n // document.execCommand(\"selectAll\");\r\n // document.execCommand(\"Copy\");\r\n\r\n // 等50毫秒,keyPress事件发生了再去处理数据\r\n // setTimeout(function () {\r\n // $(\"#luckysheet-copy-content\").blur();\r\n // }, 10);\r\n\r\n var oInput = document.createElement('input');\r\n oInput.setAttribute('readonly', 'readonly');\r\n oInput.value = cpdata;\r\n document.body.appendChild(oInput);\r\n oInput.select(); // 选择对象\r\n document.execCommand(\"Copy\");\r\n oInput.style.display='none';\r\n document.body.removeChild(oInput);\r\n }\r\n else {\r\n clipboardData.setData('Text', cpdata);\r\n return false;//否则设不生效\r\n }\r\n },\r\n copybyformat: function (e, txt) {//copy事件\r\n let clipboardData = window.clipboardData; //for IE\r\n if (!clipboardData) { // for chrome\r\n clipboardData = e.originalEvent && e.originalEvent.clipboardData;\r\n }\r\n\r\n Store.luckysheet_selection_range = [{ \"row\": Store.luckysheet_select_save[0].row, \"column\": Store.luckysheet_select_save[0].column }];\r\n selectionCopyShow();\r\n\r\n let cpdata = txt;\r\n Store.iscopyself = true;\r\n\r\n if (!clipboardData) {\r\n let textarea = $(\"#luckysheet-copy-content\");\r\n textarea.text(cpdata);\r\n textarea.focus();\r\n textarea.select();\r\n document.execCommand(\"selectAll\");\r\n document.execCommand(\"Copy\");\r\n // 等50毫秒,keyPress事件发生了再去处理数据\r\n setTimeout(function () { textarea.blur(); }, 10);\r\n }\r\n else {\r\n clipboardData.setData('Text', cpdata);\r\n return false;//否则设不生效\r\n }\r\n },\r\n isPasteAction: false,\r\n paste: function (e, triggerType) {//paste事件\r\n let _this = this;\r\n\r\n if(Store.allowEdit===false){\r\n return;\r\n }\r\n\r\n const _locale = locale();\r\n const local_drag = _locale.drag;\r\n\r\n let textarea = $(\"#luckysheet-copy-content\");\r\n textarea.focus();\r\n textarea.select();\r\n\r\n // 等50毫秒,keyPress事件发生了再去处理数据\r\n setTimeout(function () {\r\n let data = textarea.html();\r\n\r\n if (data.indexOf(\"luckysheet_copy_action_table\") >- 1 && Store.luckysheet_copy_save[\"copyRange\"] != null && Store.luckysheet_copy_save[\"copyRange\"].length > 0) {\r\n if(Store.luckysheet_paste_iscut){\r\n Store.luckysheet_paste_iscut = false;\r\n _this.pasteHandlerOfCutPaste(Store.luckysheet_copy_save);\r\n _this.clearcopy(e);\r\n }\r\n else{\r\n _this.pasteHandlerOfCopyPaste(Store.luckysheet_copy_save);\r\n }\r\n }\r\n else if (triggerType != \"btn\") {\r\n _this.pasteHandler(data);\r\n }\r\n else {\r\n if(isEditMode()){\r\n alert(local_drag.pasteMustKeybordAlert);\r\n }\r\n else{\r\n tooltip.info(local_drag.pasteMustKeybordAlertHTMLTitle, local_drag.pasteMustKeybordAlertHTML);\r\n }\r\n }\r\n }, 10);\r\n },\r\n pasteHandler: function (data, borderInfo) {\r\n\r\n if(!checkProtectionLockedRangeList(Store.luckysheet_select_save, Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n if(Store.allowEdit===false){\r\n return;\r\n }\r\n if(Store.luckysheet_select_save.length > 1){\r\n if(isEditMode()){\r\n alert(\"不能对多重选择区域执行此操作,请选择单个区域,然后再试\");\r\n }\r\n else{\r\n tooltip.info('提示', \"不能对多重选择区域执行此操作,请选择单个区域,然后再试\");\r\n }\r\n }\r\n\r\n if (typeof data == \"object\") {\r\n if (data.length == 0) { return; };\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n if(JSON.stringify(borderInfo).length > 2 && cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n let copyh = data.length, copyc = data[0].length;\r\n\r\n let minh = Store.luckysheet_select_save[0].row[0], //应用范围首尾行\r\n maxh = minh + copyh - 1;\r\n let minc = Store.luckysheet_select_save[0].column[0], //应用范围首尾列\r\n maxc = minc + copyc - 1;\r\n\r\n //应用范围包含部分合并单元格,则return提示\r\n let has_PartMC = false;\r\n if(cfg[\"merge\"] != null){\r\n has_PartMC = hasPartMC(cfg, minh, maxh, minc, maxc);\r\n }\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(\"不能对合并单元格做部分更改\");\r\n }\r\n else{\r\n tooltip.info('提示', \"不能对合并单元格做部分更改\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n let rowMaxLength = d.length;\r\n let cellMaxLength = d[0].length;\r\n\r\n //若应用范围超过最大行或最大列,增加行列\r\n let addr = maxh - rowMaxLength + 1, addc = maxc - cellMaxLength + 1;\r\n if(addr > 0 || addc > 0){\r\n d = datagridgrowth([].concat(d), addr, addc, true);\r\n }\r\n\r\n if(cfg[\"rowlen\"] == null){\r\n cfg[\"rowlen\"] = {};\r\n }\r\n\r\n let RowlChange = false;\r\n let offsetMC = {};\r\n for (let h = minh; h <= maxh; h++) {\r\n let x = [].concat(d[h]);\r\n\r\n let currentRowLen = Store.defaultrowlen;\r\n if(cfg[\"rowlen\"][h] != null){\r\n currentRowLen = cfg[\"rowlen\"][h];\r\n }\r\n\r\n for (let c = minc; c <= maxc; c++) {\r\n if(getObjType(x[c]) == \"object\" && (\"mc\" in x[c])){\r\n if(\"rs\" in x[c].mc){\r\n delete cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c];\r\n }\r\n\r\n delete x[c].mc;\r\n }\r\n\r\n let value = null;\r\n if (data[h - minh] != null && data[h - minh][c - minc] != null) {\r\n value = data[h - minh][c - minc];\r\n }\r\n\r\n x[c] = $.extend(true, {}, value);\r\n\r\n if(value != null && \"mc\" in x[c]){\r\n if(x[c][\"mc\"].rs != null){\r\n x[c][\"mc\"].r = h;\r\n x[c][\"mc\"].c = c;\r\n\r\n cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c] = x[c][\"mc\"];\r\n\r\n offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c] = [x[c][\"mc\"].r, x[c][\"mc\"].c];\r\n }\r\n else{\r\n x[c] = { \"mc\": { r: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][0], c: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][1] } }\r\n }\r\n }\r\n\r\n if(borderInfo[(h - minh) + \"_\" + (c - minc)]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": h,\r\n \"col_index\": c,\r\n \"l\": borderInfo[(h - minh) + \"_\" + (c - minc)].l,\r\n \"r\": borderInfo[(h - minh) + \"_\" + (c - minc)].r,\r\n \"t\": borderInfo[(h - minh) + \"_\" + (c - minc)].t,\r\n \"b\": borderInfo[(h - minh) + \"_\" + (c - minc)].b\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n let fontset = luckysheetfontformat(x[c]);\r\n let oneLineTextHeight = menuButton.getTextSize(\"田\", fontset)[1];\r\n //比较计算高度和当前高度取最大高度\r\n if(oneLineTextHeight > currentRowLen){\r\n currentRowLen = oneLineTextHeight;\r\n RowlChange = true;\r\n }\r\n }\r\n d[h] = x;\r\n\r\n if(currentRowLen != Store.defaultrowlen){\r\n cfg[\"rowlen\"][h] = currentRowLen;\r\n }\r\n }\r\n\r\n Store.luckysheet_select_save = [{ \"row\": [minh, maxh], \"column\": [minc, maxc] }];\r\n\r\n\r\n if(addr > 0 || addc > 0 || RowlChange){\r\n let allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n }\r\n else{\r\n let allParam = {\r\n \"cfg\": cfg\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n selectHightlightShow();\r\n }\r\n }\r\n else {\r\n data = data.replace(/\\r/g, \"\");\r\n let dataChe = [];\r\n let che = data.split(\"\\n\"),\r\n colchelen = che[0].split(\"\\t\").length;\r\n\r\n for (let i = 0; i < che.length; i++) {\r\n if (che[i].split(\"\\t\").length < colchelen) {\r\n continue;\r\n }\r\n\r\n dataChe.push(che[i].split(\"\\t\"));\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let curR = last[\"row\"] == null ? 0 : last[\"row\"][0];\r\n let curC = last[\"column\"] == null ? 0 : last[\"column\"][0];\r\n let rlen = dataChe.length, clen = dataChe[0].length;\r\n\r\n //应用范围包含部分合并单元格,则return提示\r\n let has_PartMC = false;\r\n if(Store.config[\"merge\"] != null){\r\n has_PartMC = hasPartMC(Store.config, curR, curR + rlen - 1, curC, curC + clen - 1);\r\n }\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(\"不能对合并单元格做部分更改\");\r\n }\r\n else{\r\n tooltip.info('提示',\"不能对合并单元格做部分更改\");\r\n }\r\n return;\r\n }\r\n\r\n let addr = curR + rlen - d.length, addc = curC + clen - d[0].length;\r\n if(addr > 0 || addc > 0){\r\n d = datagridgrowth([].concat(d), addr, addc, true);\r\n }\r\n\r\n for (let r = 0; r < rlen; r++) {\r\n let x = [].concat(d[r + curR]);\r\n for (let c = 0; c < clen; c++) {\r\n let originCell = x[c + curC];\r\n let value = dataChe[r][c];\r\n if(isRealNum(value)){\r\n // 如果单元格设置了纯文本格式,那么就不要转成数值类型了,防止数值过大自动转成科学计数法\r\n if (originCell && originCell.ct && originCell.ct.fa === '@') {\r\n value = String(value);\r\n } else {\r\n value = parseFloat(value);\r\n } \r\n }\r\n if(originCell instanceof Object){\r\n originCell.v = value;\r\n if(originCell.ct!=null && originCell.ct.fa!=null){\r\n originCell.m = update(originCell[\"ct\"][\"fa\"], value);\r\n }\r\n else{\r\n originCell.m = value;\r\n }\r\n\r\n if(originCell.f!=null && originCell.f.length>0){\r\n originCell.f = \"\";\r\n formula.delFunctionGroup(r + curR,c + curC,Store.currentSheetIndex);\r\n }\r\n }\r\n else{\r\n let cell = {};\r\n let mask = genarate(value);\r\n cell.v = mask[2];\r\n cell.ct = mask[1];\r\n cell.m = mask[0];\r\n\r\n x[c + curC] = cell;\r\n }\r\n\r\n }\r\n d[r + curR] = x;\r\n }\r\n\r\n last[\"row\"] = [curR, curR + rlen - 1];\r\n last[\"column\"] = [curC, curC + clen - 1];\r\n\r\n if (addr > 0 || addc > 0) {\r\n let allParam = {\r\n \"RowlChange\": true\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n }\r\n else {\r\n jfrefreshgrid(d, Store.luckysheet_select_save);\r\n selectHightlightShow();\r\n }\r\n }\r\n },\r\n pasteHandlerOfCutPaste: function(copyRange){\r\n if(!checkProtectionLockedRangeList(Store.luckysheet_select_save, Store.currentSheetIndex)){\r\n return;\r\n }\r\n if(Store.allowEdit === false){\r\n return;\r\n }\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n //复制范围\r\n let copyHasMC = copyRange[\"HasMC\"];\r\n let copyRowlChange = copyRange[\"RowlChange\"];\r\n let copySheetIndex = copyRange[\"dataSheetIndex\"];\r\n\r\n let c_r1 = copyRange[\"copyRange\"][0].row[0],\r\n c_r2 = copyRange[\"copyRange\"][0].row[1],\r\n c_c1 = copyRange[\"copyRange\"][0].column[0],\r\n c_c2 = copyRange[\"copyRange\"][0].column[1];\r\n\r\n let copyData = $.extend(true, [], getdatabyselection({\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]}, copySheetIndex));\r\n\r\n let copyh = copyData.length, copyc = copyData[0].length;\r\n\r\n //应用范围\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let minh = last[\"row_focus\"], maxh = minh + copyh - 1; //应用范围首尾行\r\n let minc = last[\"column_focus\"], maxc = minc + copyc - 1; //应用范围首尾列\r\n\r\n //应用范围包含部分合并单元格,则提示\r\n let has_PartMC = false;\r\n if(cfg[\"merge\"] != null){\r\n has_PartMC = hasPartMC(cfg, minh, maxh, minc, maxc);\r\n }\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(\"不能对合并单元格做部分更改\");\r\n }\r\n else{\r\n tooltip.info('提示',\"不能对合并单元格做部分更改\");\r\n }\r\n return;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n let rowMaxLength = d.length;\r\n let cellMaxLength = d[0].length;\r\n\r\n let addr = copyh + minh - rowMaxLength, addc = copyc + minc - cellMaxLength;\r\n if(addr > 0 || addc > 0){\r\n d = datagridgrowth([].concat(d), addr, addc, true);\r\n }\r\n\r\n let borderInfoCompute = getBorderInfoCompute(copySheetIndex);\r\n let c_dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)][\"dataVerification\"]);\r\n let dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dataVerification\"]);\r\n\r\n //剪切粘贴在当前表操作,删除剪切范围内数据、合并单元格和数据验证\r\n if(Store.currentSheetIndex == copySheetIndex){\r\n for(let i = c_r1; i <= c_r2; i++){\r\n for(let j = c_c1; j <= c_c2; j++){\r\n let cell = d[i][j];\r\n\r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n if(\"rs\" in cell[\"mc\"]){\r\n delete cfg[\"merge\"][cell[\"mc\"].r + \"_\" + cell[\"mc\"].c];\r\n }\r\n delete cell[\"mc\"];\r\n }\r\n\r\n d[i][j] = null;\r\n\r\n delete dataVerification[i + \"_\" + j];\r\n }\r\n }\r\n\r\n //边框\r\n if(cfg[\"borderInfo\"] && cfg[\"borderInfo\"].length > 0){\r\n let source_borderInfo = [];\r\n\r\n for(let i = 0; i < cfg[\"borderInfo\"].length; i++){\r\n let bd_rangeType = cfg[\"borderInfo\"][i].rangeType;\r\n\r\n if(bd_rangeType == \"range\"){\r\n let bd_range = cfg[\"borderInfo\"][i].range;\r\n let bd_emptyRange = [];\r\n\r\n for(let j = 0; j < bd_range.length; j++){\r\n bd_emptyRange = bd_emptyRange.concat(conditionformat.CFSplitRange(\r\n bd_range[j],\r\n {\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]},\r\n {\"row\": [minh, maxh], \"column\": [minc, maxc]},\r\n \"restPart\"\r\n ));\r\n }\r\n\r\n cfg[\"borderInfo\"][i].range = bd_emptyRange;\r\n\r\n source_borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n else if(bd_rangeType == \"cell\"){\r\n let bd_r = cfg[\"borderInfo\"][i].value.row_index;\r\n let bd_c = cfg[\"borderInfo\"][i].value.col_index;\r\n\r\n if(!(bd_r >= c_r1 && bd_r <= c_r2 && bd_c >= c_c1 && bd_c <= c_c2)){\r\n source_borderInfo.push(cfg[\"borderInfo\"][i]);\r\n }\r\n }\r\n }\r\n\r\n cfg[\"borderInfo\"] = source_borderInfo;\r\n }\r\n }\r\n\r\n let offsetMC = {};\r\n for (let h = minh; h <= maxh; h++) {\r\n let x = [].concat(d[h]);\r\n\r\n for (let c = minc; c <= maxc; c++) {\r\n if(borderInfoCompute[(c_r1 + h - minh) + \"_\" + (c_c1 + c - minc)]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": h,\r\n \"col_index\": c,\r\n \"l\": borderInfoCompute[(c_r1 + h - minh) + \"_\" + (c_c1 + c - minc)].l,\r\n \"r\": borderInfoCompute[(c_r1 + h - minh) + \"_\" + (c_c1 + c - minc)].r,\r\n \"t\": borderInfoCompute[(c_r1 + h - minh) + \"_\" + (c_c1 + c - minc)].t,\r\n \"b\": borderInfoCompute[(c_r1 + h - minh) + \"_\" + (c_c1 + c - minc)].b\r\n }\r\n }\r\n\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n else if(borderInfoCompute[h + \"_\" + c]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": h,\r\n \"col_index\": c,\r\n \"l\": null,\r\n \"r\": null,\r\n \"t\": null,\r\n \"b\": null\r\n }\r\n }\r\n\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n //数据验证 剪切\r\n if(c_dataVerification[(c_r1 + h - minh) + \"_\" + (c_c1 + c - minc)]){\r\n dataVerification[h + \"_\" + c] = c_dataVerification[(c_r1 + h - minh) + \"_\" + (c_c1 + c - minc)];\r\n }\r\n\r\n if(getObjType(x[c]) == \"object\" && (\"mc\" in x[c])){\r\n if(\"rs\" in x[c].mc){\r\n delete cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c];\r\n }\r\n delete x[c].mc;\r\n }\r\n\r\n let value = null;\r\n if (copyData[h - minh] != null && copyData[h - minh][c - minc] != null) {\r\n value = copyData[h - minh][c - minc];\r\n }\r\n\r\n x[c] = $.extend(true, {}, value);\r\n\r\n if(value != null && copyHasMC && (\"mc\" in x[c])){\r\n if(x[c][\"mc\"].rs != null){\r\n x[c][\"mc\"].r = h;\r\n x[c][\"mc\"].c = c;\r\n\r\n cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c] = x[c][\"mc\"];\r\n\r\n offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c] = [x[c][\"mc\"].r, x[c][\"mc\"].c];\r\n }\r\n else{\r\n x[c] = { \"mc\": { r: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][0], c: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][1] } }\r\n }\r\n }\r\n }\r\n\r\n d[h] = x;\r\n }\r\n\r\n last[\"row\"] = [minh, maxh];\r\n last[\"column\"] = [minc, maxc];\r\n\r\n //若有行高改变,重新计算行高改变\r\n if(copyRowlChange){\r\n if(Store.currentSheetIndex != copySheetIndex){\r\n cfg = rowlenByRange(d, minh, maxh, cfg);\r\n }\r\n else{\r\n cfg = rowlenByRange(d, c_r1, c_r2, cfg);\r\n cfg = rowlenByRange(d, minh, maxh, cfg);\r\n }\r\n }\r\n\r\n let source, target;\r\n if(Store.currentSheetIndex != copySheetIndex){\r\n //跨表操作\r\n let sourceData = $.extend(true, [], Store.luckysheetfile[getSheetIndex(copySheetIndex)][\"data\"]);\r\n let sourceConfig = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)][\"config\"]);\r\n\r\n let sourceCurData = $.extend(true, [], sourceData);\r\n let sourceCurConfig = $.extend(true, {}, sourceConfig);\r\n if(sourceCurConfig[\"merge\"] == null){\r\n sourceCurConfig[\"merge\"] = {};\r\n }\r\n\r\n for(let source_r = c_r1; source_r <= c_r2; source_r++){\r\n for(let source_c = c_c1; source_c <= c_c2; source_c++){\r\n let cell = sourceCurData[source_r][source_c];\r\n\r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n if(\"rs\" in cell[\"mc\"]){\r\n delete sourceCurConfig[\"merge\"][cell[\"mc\"].r + \"_\" + cell[\"mc\"].c];\r\n }\r\n delete cell[\"mc\"];\r\n }\r\n sourceCurData[source_r][source_c] = null;\r\n }\r\n }\r\n\r\n if(copyRowlChange){\r\n sourceCurConfig = rowlenByRange(sourceCurData, c_r1, c_r2, sourceCurConfig);\r\n }\r\n\r\n //边框\r\n if(sourceCurConfig[\"borderInfo\"] && sourceCurConfig[\"borderInfo\"].length > 0){\r\n let source_borderInfo = [];\r\n\r\n for(let i = 0; i < sourceCurConfig[\"borderInfo\"].length; i++){\r\n let bd_rangeType = sourceCurConfig[\"borderInfo\"][i].rangeType;\r\n\r\n if(bd_rangeType == \"range\"){\r\n let bd_range = sourceCurConfig[\"borderInfo\"][i].range;\r\n let bd_emptyRange = [];\r\n\r\n for(let j = 0; j < bd_range.length; j++){\r\n bd_emptyRange = bd_emptyRange.concat(conditionformat.CFSplitRange(\r\n bd_range[j],\r\n {\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]},\r\n {\"row\": [minh, maxh], \"column\": [minc, maxc]},\r\n \"restPart\"\r\n ));\r\n }\r\n\r\n sourceCurConfig[\"borderInfo\"][i].range = bd_emptyRange;\r\n\r\n source_borderInfo.push(sourceCurConfig[\"borderInfo\"][i]);\r\n }\r\n else if(bd_rangeType == \"cell\"){\r\n let bd_r = sourceCurConfig[\"borderInfo\"][i].value.row_index;\r\n let bd_c = sourceCurConfig[\"borderInfo\"][i].value.col_index;\r\n\r\n if(!(bd_r >= c_r1 && bd_r <= c_r2 && bd_c >= c_c1 && bd_c <= c_c2)){\r\n source_borderInfo.push(sourceCurConfig[\"borderInfo\"][i]);\r\n }\r\n }\r\n }\r\n\r\n sourceCurConfig[\"borderInfo\"] = source_borderInfo;\r\n }\r\n\r\n //条件格式\r\n let source_cdformat = $.extend(true, [], Store.luckysheetfile[getSheetIndex(copySheetIndex)][\"luckysheet_conditionformat_save\"]);\r\n let source_curCdformat = $.extend(true, [], source_cdformat);\r\n let ruleArr = [];\r\n if(source_curCdformat != null && source_curCdformat.length > 0){\r\n for(let i = 0; i < source_curCdformat.length; i++){\r\n let source_curCdformat_cellrange = source_curCdformat[i].cellrange;\r\n let emptyRange = [];\r\n let emptyRange2 = [];\r\n\r\n for(let j = 0; j < source_curCdformat_cellrange.length; j++){\r\n let range = conditionformat.CFSplitRange(\r\n source_curCdformat_cellrange[j],\r\n {\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]},\r\n {\"row\": [minh, maxh], \"column\": [minc, maxc]},\r\n \"restPart\"\r\n );\r\n\r\n emptyRange = emptyRange.concat(range);\r\n\r\n let range2 = conditionformat.CFSplitRange(\r\n source_curCdformat_cellrange[j],\r\n {\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]},\r\n {\"row\": [minh, maxh], \"column\": [minc, maxc]},\r\n \"operatePart\"\r\n );\r\n\r\n if(range2.length > 0){\r\n emptyRange2 = emptyRange2.concat(range2);\r\n }\r\n }\r\n\r\n source_curCdformat[i].cellrange = emptyRange;\r\n\r\n if(emptyRange2.length > 0){\r\n let ruleObj = $.extend(true, {}, source_curCdformat[i]);\r\n ruleObj.cellrange = emptyRange2;\r\n ruleArr.push(ruleObj);\r\n }\r\n }\r\n }\r\n\r\n let target_cdformat = $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"]);\r\n let target_curCdformat = $.extend(true, [], target_cdformat);\r\n if(ruleArr.length > 0){\r\n target_curCdformat = target_curCdformat.concat(ruleArr);\r\n }\r\n\r\n //数据验证\r\n for(let i = c_r1; i <= c_r2; i++){\r\n for(let j = c_c1; j <= c_c2; j++){\r\n delete c_dataVerification[i + \"_\" + j];\r\n }\r\n }\r\n\r\n source = {\r\n \"sheetIndex\": copySheetIndex,\r\n \"data\": sourceData,\r\n \"curData\": sourceCurData,\r\n \"config\": sourceConfig,\r\n \"curConfig\": sourceCurConfig,\r\n \"cdformat\": source_cdformat,\r\n \"curCdformat\": source_curCdformat,\r\n \"dataVerification\": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)][\"dataVerification\"]),\r\n \"curDataVerification\": c_dataVerification,\r\n \"range\": {\r\n \"row\": [c_r1, c_r2],\r\n \"column\": [c_c1, c_c2]\r\n }\r\n }\r\n target = {\r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"data\": Store.flowdata,\r\n \"curData\": d,\r\n \"config\": $.extend(true, {}, Store.config),\r\n \"curConfig\": cfg,\r\n \"cdformat\": target_cdformat,\r\n \"curCdformat\": target_curCdformat,\r\n \"dataVerification\": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dataVerification\"]),\r\n \"curDataVerification\": dataVerification,\r\n \"range\": {\r\n \"row\": [minh, maxh],\r\n \"column\": [minc, maxc]\r\n }\r\n }\r\n }\r\n else{\r\n //条件格式\r\n let cdformat = $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"]);\r\n let curCdformat = $.extend(true, [], cdformat);\r\n if(curCdformat != null && curCdformat.length > 0){\r\n for(let i = 0; i < curCdformat.length; i++){\r\n let cellrange = curCdformat[i].cellrange;\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < cellrange.length; j++){\r\n let range = conditionformat.CFSplitRange(\r\n cellrange[j],\r\n {\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]},\r\n {\"row\": [minh, maxh], \"column\": [minc, maxc]},\r\n \"allPart\"\r\n );\r\n\r\n emptyRange = emptyRange.concat(range);\r\n }\r\n\r\n curCdformat[i].cellrange = emptyRange;\r\n }\r\n }\r\n\r\n //当前表操作\r\n source = {\r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"data\": Store.flowdata,\r\n \"curData\": d,\r\n \"config\": $.extend(true, {}, Store.config),\r\n \"curConfig\": cfg,\r\n \"cdformat\": cdformat,\r\n \"curCdformat\": curCdformat,\r\n \"dataVerification\": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dataVerification\"]),\r\n \"curDataVerification\": dataVerification,\r\n \"range\": {\r\n \"row\": [c_r1, c_r2],\r\n \"column\": [c_c1, c_c2]\r\n }\r\n }\r\n target = {\r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"data\": Store.flowdata,\r\n \"curData\": d,\r\n \"config\": $.extend(true, {}, Store.config),\r\n \"curConfig\": cfg,\r\n \"cdformat\": cdformat,\r\n \"curCdformat\": curCdformat,\r\n \"dataVerification\": $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dataVerification\"]),\r\n \"curDataVerification\": dataVerification,\r\n \"range\": {\r\n \"row\": [minh, maxh],\r\n \"column\": [minc, maxc]\r\n }\r\n }\r\n }\r\n\r\n if(addr > 0 || addc > 0){\r\n jfrefreshgrid_pastcut(source, target, true);\r\n }\r\n else{\r\n jfrefreshgrid_pastcut(source, target, copyRowlChange);\r\n }\r\n },\r\n pasteHandlerOfCopyPaste: function(copyRange){\r\n if(!checkProtectionLockedRangeList(Store.luckysheet_select_save, Store.currentSheetIndex)){\r\n return;\r\n }\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n //复制范围\r\n let copyHasMC = copyRange[\"HasMC\"];\r\n let copyRowlChange = copyRange[\"RowlChange\"];\r\n let copySheetIndex = copyRange[\"dataSheetIndex\"];\r\n\r\n let c_r1 = copyRange[\"copyRange\"][0].row[0],\r\n c_r2 = copyRange[\"copyRange\"][0].row[1],\r\n c_c1 = copyRange[\"copyRange\"][0].column[0],\r\n c_c2 = copyRange[\"copyRange\"][0].column[1];\r\n\r\n let arr = [], isSameRow = false;\r\n for(let i = 0; i < copyRange[\"copyRange\"].length; i++){\r\n let arrData = getdatabyselection({\"row\": copyRange[\"copyRange\"][i].row, \"column\": copyRange[\"copyRange\"][i].column}, copySheetIndex);\r\n if(copyRange[\"copyRange\"].length > 1){\r\n if(c_r1 == copyRange[\"copyRange\"][1].row[0] && c_r2 == copyRange[\"copyRange\"][1].row[1]){\r\n arrData = arrData[0].map(function(col, a){\r\n return arrData.map(function(row){\r\n return row[a];\r\n });\r\n });\r\n\r\n arr = arr.concat(arrData);\r\n\r\n isSameRow = true;\r\n }\r\n else if(c_c1 == copyRange[\"copyRange\"][1].column[0] && c_c2 == copyRange[\"copyRange\"][1].column[1]){\r\n arr = arr.concat(arrData);\r\n }\r\n }\r\n else{\r\n arr = arrData;\r\n }\r\n }\r\n\r\n if(isSameRow){\r\n arr = arr[0].map(function(col, b){\r\n return arr.map(function(row){\r\n return row[b];\r\n })\r\n })\r\n }\r\n\r\n let copyData = $.extend(true, [], arr);\r\n\r\n //多重选择选择区域 单元格如果有函数 则只取值 不取函数\r\n if(copyRange[\"copyRange\"].length > 1){\r\n for(let i = 0; i < copyData.length; i++){\r\n for(let j = 0; j < copyData[i].length; j++){\r\n if(copyData[i][j] != null && copyData[i][j].f != null){\r\n delete copyData[i][j].f;\r\n delete copyData[i][j].spl;\r\n }\r\n }\r\n }\r\n }\r\n\r\n let copyh = copyData.length, copyc = copyData[0].length;\r\n\r\n //应用范围\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let minh = last[\"row\"][0], maxh = last[\"row\"][1]; //应用范围首尾行\r\n let minc = last[\"column\"][0], maxc = last[\"column\"][1]; //应用范围首尾列\r\n\r\n let mh = (maxh - minh + 1) % copyh;\r\n let mc = (maxc - minc + 1) % copyc;\r\n\r\n if(mh != 0 || mc != 0){ //若应用范围不是copydata行列数的整数倍,则取copydata的行列数\r\n maxh = minh + copyh - 1;\r\n maxc = minc + copyc - 1;\r\n }\r\n\r\n //应用范围包含部分合并单元格,则提示\r\n let has_PartMC = false;\r\n if(cfg[\"merge\"] != null){\r\n has_PartMC = hasPartMC(cfg, minh, maxh, minc, maxc);\r\n }\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(\"不能对合并单元格做部分更改\");\r\n }\r\n else{\r\n tooltip.info('提示',\"不能对合并单元格做部分更改\");\r\n }\r\n return;\r\n }\r\n\r\n let timesH = (maxh - minh + 1) / copyh;\r\n let timesC = (maxc - minc + 1) / copyc;\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n let rowMaxLength = d.length;\r\n let cellMaxLength = d[0].length;\r\n\r\n //若应用范围超过最大行或最大列,增加行列\r\n let addr = copyh + minh - rowMaxLength, addc = copyc + minc - cellMaxLength;\r\n if(addr > 0 || addc > 0){\r\n d = datagridgrowth([].concat(d), addr, addc, true);\r\n }\r\n\r\n let borderInfoCompute = getBorderInfoCompute(copySheetIndex);\r\n let c_dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)].dataVerification);\r\n let dataVerification = null;\r\n\r\n let mth = 0, mtc = 0, maxcellCahe = 0, maxrowCache = 0;\r\n for(let th = 1; th <= timesH; th++){\r\n for(let tc = 1; tc <= timesC; tc++){\r\n mth = minh + (th - 1) * copyh;\r\n mtc = minc + (tc - 1) * copyc;\r\n maxrowCache = minh + th * copyh;\r\n maxcellCahe = minc + tc * copyc;\r\n\r\n //行列位移值 用于单元格有函数\r\n let offsetRow = mth - c_r1;\r\n let offsetCol = mtc - c_c1;\r\n\r\n let offsetMC = {};\r\n for (let h = mth; h < maxrowCache; h++) {\r\n let x = [].concat(d[h]);\r\n\r\n for (let c = mtc; c < maxcellCahe; c++) {\r\n if(borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": h,\r\n \"col_index\": c,\r\n \"l\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].l,\r\n \"r\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].r,\r\n \"t\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].t,\r\n \"b\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].b\r\n }\r\n }\r\n\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n else if(borderInfoCompute[h + \"_\" + c]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": h,\r\n \"col_index\": c,\r\n \"l\": null,\r\n \"r\": null,\r\n \"t\": null,\r\n \"b\": null\r\n }\r\n }\r\n\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n //数据验证 复制\r\n if(c_dataVerification[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)]){\r\n if(dataVerification == null){\r\n dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].dataVerification)\r\n }\r\n\r\n dataVerification[h + \"_\" + c] = c_dataVerification[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)];\r\n }\r\n\r\n if(getObjType(x[c]) == \"object\" && \"mc\" in x[c]){\r\n if(\"rs\" in x[c].mc){\r\n delete cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c];\r\n }\r\n delete x[c].mc;\r\n }\r\n\r\n let value = null;\r\n if (copyData[h - mth] != null && copyData[h - mth][c - mtc] != null) {\r\n value = $.extend(true, {}, copyData[h - mth][c - mtc]);\r\n }\r\n\r\n if(value != null && value.f != null){\r\n let func = value.f;\r\n\r\n if(offsetRow > 0){\r\n func = \"=\" + formula.functionCopy(func, \"down\", offsetRow);\r\n }\r\n\r\n if(offsetRow < 0){\r\n func = \"=\" + formula.functionCopy(func, \"up\", Math.abs(offsetRow));\r\n }\r\n\r\n if(offsetCol > 0){\r\n func = \"=\" + formula.functionCopy(func, \"right\", offsetCol);\r\n }\r\n\r\n if(offsetCol < 0){\r\n func = \"=\" + formula.functionCopy(func, \"left\", Math.abs(offsetCol));\r\n }\r\n\r\n let funcV = formula.execfunction(func, h, c, undefined, true);\r\n\r\n if(value.spl != null){\r\n value.f = funcV[2];\r\n value.v = funcV[1];\r\n value.spl = funcV[3].data;\r\n }\r\n else{\r\n value.f = funcV[2];\r\n value.v = funcV[1];\r\n\r\n if(value.ct != null && value.ct[\"fa\"] != null){\r\n value.m = update(value.ct[\"fa\"], funcV[1]);\r\n }\r\n }\r\n }\r\n\r\n x[c] = $.extend(true, {}, value);\r\n\r\n if(value != null && copyHasMC && (\"mc\" in x[c])){\r\n if(x[c][\"mc\"].rs != null){\r\n x[c][\"mc\"].r = h;\r\n x[c][\"mc\"].c = c;\r\n\r\n cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c] = x[c][\"mc\"];\r\n\r\n offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c] = [x[c][\"mc\"].r, x[c][\"mc\"].c];\r\n }\r\n else{\r\n x[c] = { \"mc\": { r: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][0], c: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][1] } }\r\n }\r\n }\r\n }\r\n\r\n d[h] = x;\r\n }\r\n }\r\n }\r\n\r\n //复制范围 是否有 条件格式和数据验证\r\n let cdformat = null;\r\n if(copyRange[\"copyRange\"].length == 1){\r\n let c_file = Store.luckysheetfile[getSheetIndex(copySheetIndex)];\r\n let a_file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n\r\n let ruleArr_cf = $.extend(true, [], c_file[\"luckysheet_conditionformat_save\"]);\r\n\r\n if(ruleArr_cf != null && ruleArr_cf.length > 0){\r\n cdformat = $.extend(true, [], a_file[\"luckysheet_conditionformat_save\"]);\r\n\r\n for(let i = 0; i < ruleArr_cf.length; i++){\r\n let cf_range = ruleArr_cf[i].cellrange;\r\n\r\n let emptyRange = [];\r\n\r\n for(let th = 1; th <= timesH; th++){\r\n for(let tc = 1; tc <= timesC; tc++){\r\n mth = minh + (th - 1) * copyh;\r\n mtc = minc + (tc - 1) * copyc;\r\n maxrowCache = minh + th * copyh;\r\n maxcellCahe = minc + tc * copyc;\r\n\r\n for(let j = 0; j < cf_range.length; j++){\r\n let range = conditionformat.CFSplitRange(\r\n cf_range[j],\r\n {\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]},\r\n {\"row\": [mth, maxrowCache - 1], \"column\": [mtc, maxcellCahe - 1]},\r\n \"operatePart\"\r\n );\r\n\r\n if(range.length > 0){\r\n emptyRange = emptyRange.concat(range);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(emptyRange.length > 0){\r\n ruleArr_cf[i].cellrange = emptyRange;\r\n cdformat.push(ruleArr_cf[i]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n last[\"row\"] = [minh, maxh];\r\n last[\"column\"] = [minc, maxc];\r\n\r\n if(copyRowlChange || addr > 0 || addc > 0){\r\n cfg = rowlenByRange(d, minh, maxh, cfg);\r\n\r\n let allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true,\r\n \"cdformat\": cdformat,\r\n \"dataVerification\": dataVerification\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n }\r\n else{\r\n let allParam = {\r\n \"cfg\": cfg,\r\n \"cdformat\": cdformat,\r\n \"dataVerification\": dataVerification\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n\r\n selectHightlightShow();\r\n }\r\n },\r\n pasteHandlerOfPaintModel: function(copyRange){\r\n if(!checkProtectionLockedRangeList(Store.luckysheet_select_save, Store.currentSheetIndex)){\r\n return;\r\n }\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n //复制范围\r\n let copyHasMC = copyRange[\"HasMC\"];\r\n let copyRowlChange = copyRange[\"RowlChange\"];\r\n let copySheetIndex = copyRange[\"dataSheetIndex\"];\r\n\r\n let c_r1 = copyRange[\"copyRange\"][0].row[0],\r\n c_r2 = copyRange[\"copyRange\"][0].row[1],\r\n c_c1 = copyRange[\"copyRange\"][0].column[0],\r\n c_c2 = copyRange[\"copyRange\"][0].column[1];\r\n\r\n let copyData = $.extend(true, [], getdatabyselection({\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]}, copySheetIndex));\r\n\r\n //应用范围\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let minh = last[\"row\"][0], maxh = last[\"row\"][1]; //应用范围首尾行\r\n let minc = last[\"column\"][0], maxc = last[\"column\"][1]; //应用范围首尾列\r\n\r\n let copyh = copyData.length, copyc = copyData[0].length;\r\n\r\n if(minh == maxh && minc == maxc){\r\n //应用范围是一个单元格,自动增加到复制范围大小 (若自动增加的范围包含部分合并单元格,则提示)\r\n let has_PartMC = false;\r\n if(cfg[\"merge\"] != null){\r\n has_PartMC = hasPartMC(cfg, minh, minh + copyh - 1, minc, minc + copyc - 1);\r\n }\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(\"不能对合并单元格做部分更改\");\r\n }\r\n else{\r\n tooltip.info('提示',\"不能对合并单元格做部分更改\");\r\n }\r\n return;\r\n }\r\n\r\n maxh = minh + copyh - 1;\r\n maxc = minc + copyc - 1;\r\n }\r\n\r\n let timesH = Math.ceil((maxh - minh + 1) / copyh); //复制行 组数\r\n let timesC = Math.ceil((maxc - minc + 1) / copyc); //复制列 组数\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n let cellMaxLength = d[0].length;\r\n let rowMaxLength = d.length;\r\n\r\n let borderInfoCompute = getBorderInfoCompute(copySheetIndex);\r\n let c_dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(copySheetIndex)].dataVerification);\r\n let dataVerification = null;\r\n\r\n let mth = 0, mtc = 0, maxcellCahe = 0, maxrowCache = 0;\r\n for (let th = 1; th <= timesH; th++) {\r\n for (let tc = 1; tc <= timesC; tc++) {\r\n mth = minh + (th - 1) * copyh;\r\n mtc = minc + (tc - 1) * copyc;\r\n\r\n maxrowCache = minh + th * copyh > rowMaxLength ? rowMaxLength : minh + th * copyh;\r\n if(maxrowCache > (maxh + 1)){\r\n maxrowCache = maxh + 1;\r\n }\r\n\r\n maxcellCahe = minc + tc * copyc > cellMaxLength ? cellMaxLength : minc + tc * copyc;\r\n if(maxcellCahe > (maxc + 1)){\r\n maxcellCahe = maxc + 1;\r\n }\r\n\r\n let offsetMC = {};\r\n for (let h = mth; h < maxrowCache; h++) {\r\n let x = [].concat(d[h]);\r\n\r\n for (let c = mtc; c < maxcellCahe; c++) {\r\n if(borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": h,\r\n \"col_index\": c,\r\n \"l\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].l,\r\n \"r\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].r,\r\n \"t\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].t,\r\n \"b\": borderInfoCompute[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)].b\r\n }\r\n }\r\n\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n else if(borderInfoCompute[h + \"_\" + c]){\r\n let bd_obj = {\r\n \"rangeType\": \"cell\",\r\n \"value\": {\r\n \"row_index\": h,\r\n \"col_index\": c,\r\n \"l\": null,\r\n \"r\": null,\r\n \"t\": null,\r\n \"b\": null\r\n }\r\n }\r\n\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n cfg[\"borderInfo\"].push(bd_obj);\r\n }\r\n\r\n //数据验证 复制\r\n if(c_dataVerification[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)]){\r\n if(dataVerification == null){\r\n dataVerification = $.extend(true, {}, Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].dataVerification)\r\n }\r\n\r\n dataVerification[h + \"_\" + c] = c_dataVerification[(c_r1 + h - mth) + \"_\" + (c_c1 + c - mtc)];\r\n }\r\n\r\n if(getObjType(x[c]) == \"object\" && (\"mc\" in x[c])){\r\n if(\"rs\" in x[c].mc){\r\n delete cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c];\r\n }\r\n delete x[c].mc;\r\n }\r\n\r\n let value = null;\r\n if (copyData[h - mth] != null && copyData[h - mth][c - mtc] != null) {\r\n value = copyData[h - mth][c - mtc];\r\n }\r\n\r\n if(value != null){\r\n delete value[\"v\"];\r\n delete value[\"m\"];\r\n delete value[\"f\"];\r\n delete value[\"spl\"];\r\n\r\n if(value.ct && value.ct.t == 'inlineStr'){\r\n delete value.ct;\r\n }\r\n\r\n if(getObjType(x[c]) == \"object\"){\r\n\r\n }\r\n else{\r\n x[c] = {\"v\": x[c] };\r\n }\r\n\r\n x[c] = $.extend(true, x[c], value);\r\n\r\n if(copyHasMC && (\"mc\" in x[c])){\r\n if(x[c][\"mc\"].rs != null){\r\n x[c][\"mc\"].r = h;\r\n if(x[c][\"mc\"].rs + h >= maxrowCache){\r\n x[c][\"mc\"].rs = maxrowCache - h;\r\n }\r\n\r\n x[c][\"mc\"].c = c;\r\n if(x[c][\"mc\"].cs + c >= maxcellCahe){\r\n x[c][\"mc\"].cs = maxcellCahe - c;\r\n }\r\n\r\n cfg[\"merge\"][x[c][\"mc\"].r + \"_\" + x[c][\"mc\"].c] = x[c][\"mc\"];\r\n\r\n offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c] = [x[c][\"mc\"].r, x[c][\"mc\"].c];\r\n }\r\n else{\r\n x[c] = { \"mc\": { r: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][0], c: offsetMC[value[\"mc\"].r + \"_\" + value[\"mc\"].c][1] } }\r\n }\r\n }\r\n\r\n if(x[c].v != null){\r\n if(value[\"ct\"] != null && value[\"ct\"][\"fa\"] != null){\r\n let mask = update(value[\"ct\"][\"fa\"], x[c].v);\r\n x[c].m = mask;\r\n }\r\n }\r\n }\r\n }\r\n\r\n d[h] = x;\r\n }\r\n }\r\n }\r\n\r\n //复制范围 是否有 条件格式\r\n let cdformat = null;\r\n let ruleArr = $.extend(true, [], Store.luckysheetfile[getSheetIndex(copySheetIndex)][\"luckysheet_conditionformat_save\"]);\r\n\r\n if(ruleArr != null && ruleArr.length > 0){\r\n cdformat = $.extend(true, [], Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"luckysheet_conditionformat_save\"]);\r\n\r\n for(let i = 0; i < ruleArr.length; i++){\r\n let cdformat_cellrange = ruleArr[i].cellrange;\r\n let emptyRange = [];\r\n\r\n for(let j = 0; j < cdformat_cellrange.length; j++){\r\n let range = conditionformat.CFSplitRange(\r\n cdformat_cellrange[j],\r\n {\"row\": [c_r1, c_r2], \"column\": [c_c1, c_c2]},\r\n {\"row\": [minh, maxh], \"column\": [minc, maxc]},\r\n \"operatePart\"\r\n );\r\n\r\n if(range.length > 0){\r\n emptyRange = emptyRange.concat(range);\r\n }\r\n }\r\n\r\n if(emptyRange.length > 0){\r\n ruleArr[i].cellrange = [{\"row\": [minh, maxh], \"column\": [minc, maxc]}];\r\n cdformat.push(ruleArr[i]);\r\n }\r\n }\r\n }\r\n\r\n last[\"row\"] = [minh, maxh];\r\n last[\"column\"] = [minc, maxc];\r\n\r\n if(copyRowlChange){\r\n cfg = rowlenByRange(d, minh, maxh, cfg);\r\n\r\n let allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true,\r\n \"cdformat\": cdformat,\r\n \"dataVerification\": dataVerification\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n }\r\n else{\r\n let allParam = {\r\n \"cfg\": cfg,\r\n \"cdformat\": cdformat,\r\n \"dataVerification\": dataVerification\r\n }\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam);\r\n\r\n selectHightlightShow();\r\n }\r\n },\r\n matchcopy: function (data1, data2) {\r\n let data1cache = [], data2cache = [], data1len, data2len;\r\n if (typeof data1 == \"object\") {\r\n data1cache = data1;\r\n }\r\n else {\r\n data1cache = data1.split(\"\\n\");\r\n for (let i = 0; i < data1cache.length; i++) {\r\n data1cache[i] = data1cache[i].split(\"\\t\");\r\n }\r\n }\r\n\r\n data1len = data1cache.length;\r\n\r\n if (typeof data2 == \"object\") {\r\n data2cache = data2;\r\n }\r\n else {\r\n data2cache = data2.split(\"\\n\");\r\n for (let i = 0; i < data2cache.length; i++) {\r\n data2cache[i] = data2cache[i].split(\"\\t\");\r\n }\r\n }\r\n\r\n data2len = data2cache.length;\r\n\r\n if (data1len != data2len) {\r\n return false;\r\n }\r\n\r\n\r\n for (let r1 = 0; r1 < data1len; r1++) {\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r1] != null) {\r\n continue;\r\n }\r\n\r\n for (let r2 = 0; r2 < data2len; r2++) {\r\n if (data1cache[r1].length != data2cache[r2].length) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n for (let r = 0; r < data1len; r++) {\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n for (let c = 0; c < data1cache[0].length; c++) {\r\n if (getcellvalue(r, c, data1cache) != getcellvalue(r, c, data2cache)) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n};\r\n\r\nexport default selection;","import selection from '../controllers/selection';\r\nimport menuButton from '../controllers/menuButton';\r\n\r\nexport default function cleargridelement(event) {\r\n $(\"#luckysheet-cols-h-hover\").hide();\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n\r\n $(\"#luckysheet-cell-selected-boxs .luckysheet-cell-selected\").hide();\r\n $(\"#luckysheet-cols-h-selected .luckysheet-cols-h-selected\").hide();\r\n $(\"#luckysheet-rows-h-selected .luckysheet-rows-h-selected\").hide();\r\n\r\n $(\"#luckysheet-cell-selected-focus\").hide();\r\n $(\"#luckysheet-rows-h-hover\").hide();\r\n $(\"#luckysheet-selection-copy .luckysheet-selection-copy\").hide();\r\n $(\"#luckysheet-cols-menu-btn\").hide();\r\n $(\"#luckysheet-row-count-show, #luckysheet-column-count-show\").hide();\r\n if (!event) {\r\n selection.clearcopy(event);\r\n }\r\n //else{\r\n //\tselection.clearcopy();\r\n //}\r\n\r\n //选区下拉icon隐藏\r\n if($(\"#luckysheet-dropCell-icon\").is(\":visible\")){\r\n if(event){\r\n $(\"#luckysheet-dropCell-icon\").remove();\r\n }\r\n }\r\n //格式刷\r\n if(menuButton.luckysheetPaintModelOn && !event){\r\n menuButton.cancelPaintModel();\r\n }\r\n}","import { \r\n gridHTML, \r\n menuToolBar, \r\n flow, \r\n columnHeaderHTML,\r\n maskHTML,\r\n colsmenuHTML,\r\n rightclickHTML,\r\n inputHTML,\r\n filtermenuHTML,\r\n filtersubmenuHTML,\r\n sheetconfigHTML,\r\n} from '../controllers/constant';\r\nimport luckysheetConfigsetting from '../controllers/luckysheetConfigsetting';\r\nimport luckysheetPostil from '../controllers/postil';\r\nimport { datagridgrowth } from './getdata';\r\nimport editor from './editor';\r\nimport rhchInit from './rhchInit';\r\nimport { replaceHtml } from '../utils/util';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\nexport default function luckysheetcreatedom(colwidth, rowheight, data, menu, title) {\r\n // //最少30行\r\n // if(rowheight < 30){\r\n // rowheight = 30;\r\n // }\r\n\r\n // //最少22列\r\n // if(colwidth < 22){\r\n // colwidth = 22;\r\n // }\r\n\r\n let gh = gridHTML();\r\n gh = replaceHtml(gh, { \"logotitle\": title });//设置title\r\n gh = replaceHtml(gh, { \"menu\": menuToolBar() });//设置需要显示的菜单\r\n\r\n // if (data.length == 0) {\r\n // Store.flowdata = datagridgrowth(data, rowheight, colwidth);\r\n // }\r\n // else if (data.length < rowheight && data[0].length < colwidth) {\r\n // Store.flowdata = datagridgrowth(data, rowheight - data.length, colwidth - data[0].length);\r\n // }\r\n // else if (data.length < rowheight) {\r\n // Store.flowdata = datagridgrowth(data, rowheight - data.length, 0);\r\n // }\r\n // else if (data[0].length < colwidth) {\r\n // Store.flowdata = datagridgrowth(data, 0, colwidth - data[0].length);\r\n // }\r\n // else {\r\n // Store.flowdata = data;\r\n // }\r\n \r\n let flowHTML = flow;\r\n if(Store.config == null){\r\n Store.config = {};\r\n }\r\n\r\n rhchInit(rowheight, colwidth);\r\n\r\n const _locale = locale();\r\n const locale_info = _locale.info;\r\n\r\n let addControll = ''+ locale_info.row +'('+locale_info.addLast+')';\r\n let backControll = ' ';\r\n // let pageControll = ' 共'+ luckysheetConfigsetting.pageInfo.totalPage +'页,当前已显示'+ (luckysheetConfigsetting.pageInfo.currentPage) +'页,每页'+ luckysheetConfigsetting.pageInfo.pageSize +'条 ';\r\n let pageInfo = replaceHtml(locale_info.pageInfo,{\r\n total:luckysheetConfigsetting.total?luckysheetConfigsetting.total:\"\",\r\n totalPage:luckysheetConfigsetting.pageInfo.totalPage?luckysheetConfigsetting.pageInfo.totalPage:\"\",\r\n currentPage:luckysheetConfigsetting.pageInfo.currentPage?luckysheetConfigsetting.pageInfo.currentPage:\"\",\r\n });\r\n let pageControll = ' '+ pageInfo +' ';\r\n let pageControll2 = ' '+pageInfo+'';\r\n\r\n let bottomControll = \"\";\r\n if(luckysheetConfigsetting.enableAddRow){\r\n bottomControll += addControll;\r\n }\r\n\r\n if(luckysheetConfigsetting.enablePage){\r\n if(parseInt(luckysheetConfigsetting.pageInfo.totalPage) == 1){\r\n bottomControll += pageControll2;\r\n }\r\n else{\r\n bottomControll += pageControll;\r\n }\r\n }\r\n\r\n if(luckysheetConfigsetting.enableAddBackTop){\r\n bottomControll += backControll;\r\n }\r\n\r\n let flowstr = replaceHtml('
'+ bottomControll +'
', { \"height\": Store.rh_height, \"width\": Store.ch_width - 1 });\r\n\r\n let colsheader = replaceHtml(columnHeaderHTML, { \"width\": Store.ch_width, \"index\": 0, \"column\": \"\" });\r\n\r\n flowHTML = replaceHtml(flowHTML, { \"width\": Store.ch_width, \"flow\": flowstr, \"index\": 0 });\r\n\r\n gh = replaceHtml(gh, { \"flow\": flowHTML, \"rowHeader\": \"
\", \"columnHeader\": colsheader, \"functionButton\": luckysheetConfigsetting.functionButton });//设置需要显示的菜单\r\n\r\n $(\"#\" + Store.container).append(gh);\r\n\r\n $(\"#luckysheet-scrollbar-x div\").width(Store.ch_width);\r\n $(\"#luckysheet-scrollbar-y div\").height(Store.rh_height + Store.columnHeaderHeight - Store.cellMainSrollBarSize - 3);\r\n\r\n //新建行菜单\r\n $(\"body\").append(maskHTML);\r\n $(\"body\").append(colsmenuHTML);\r\n $(\"body\").append(rightclickHTML());\r\n $(\"body\").append(inputHTML);\r\n $(\"body\").append(replaceHtml(filtermenuHTML(), { \"menuid\": \"filter\" }));\r\n $(\"body\").append(replaceHtml(filtersubmenuHTML(), { \"menuid\": \"filter\" }));\r\n $(\"body\").append(sheetconfigHTML());\r\n\r\n $(\"#luckysheet-rows-h\").width((Store.rowHeaderWidth-1.5));\r\n $(\"#luckysheet-cols-h-c\").height((Store.columnHeaderHeight-1.5));\r\n $(\"#luckysheet-left-top\").css({width:Store.rowHeaderWidth-1.5, height:Store.columnHeaderHeight-1.5});\r\n\r\n // //批注\r\n // luckysheetPostil.buildAllPs(Store.flowdata);\r\n\r\n $(\"#luckysheet_info_detail_input\").val(luckysheetConfigsetting.title);\r\n}","'use strict';\nvar $ = require('../internals/export');\nvar $findIndex = require('../internals/array-iteration').findIndex;\nvar addToUnscopables = require('../internals/add-to-unscopables');\nvar arrayMethodUsesToLength = require('../internals/array-method-uses-to-length');\n\nvar FIND_INDEX = 'findIndex';\nvar SKIPS_HOLES = true;\n\nvar USES_TO_LENGTH = arrayMethodUsesToLength(FIND_INDEX);\n\n// Shouldn't skip holes\nif (FIND_INDEX in []) Array(1)[FIND_INDEX](function () { SKIPS_HOLES = false; });\n\n// `Array.prototype.findIndex` method\n// https://tc39.github.io/ecma262/#sec-array.prototype.findindex\n$({ target: 'Array', proto: true, forced: SKIPS_HOLES || !USES_TO_LENGTH }, {\n findIndex: function findIndex(callbackfn /* , that = undefined */) {\n return $findIndex(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n\n// https://tc39.github.io/ecma262/#sec-array.prototype-@@unscopables\naddToUnscopables(FIND_INDEX);\n","var fails = require('../internals/fails');\n\nmodule.exports = !fails(function () {\n return Object.isExtensible(Object.preventExtensions({}));\n});\n","var hiddenKeys = require('../internals/hidden-keys');\nvar isObject = require('../internals/is-object');\nvar has = require('../internals/has');\nvar defineProperty = require('../internals/object-define-property').f;\nvar uid = require('../internals/uid');\nvar FREEZING = require('../internals/freezing');\n\nvar METADATA = uid('meta');\nvar id = 0;\n\nvar isExtensible = Object.isExtensible || function () {\n return true;\n};\n\nvar setMetadata = function (it) {\n defineProperty(it, METADATA, { value: {\n objectID: 'O' + ++id, // object ID\n weakData: {} // weak collections IDs\n } });\n};\n\nvar fastKey = function (it, create) {\n // return a primitive with prefix\n if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n if (!has(it, METADATA)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return 'F';\n // not necessary to add metadata\n if (!create) return 'E';\n // add missing metadata\n setMetadata(it);\n // return object ID\n } return it[METADATA].objectID;\n};\n\nvar getWeakData = function (it, create) {\n if (!has(it, METADATA)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return true;\n // not necessary to add metadata\n if (!create) return false;\n // add missing metadata\n setMetadata(it);\n // return the store of weak collections IDs\n } return it[METADATA].weakData;\n};\n\n// add metadata on freeze-family methods calling\nvar onFreeze = function (it) {\n if (FREEZING && meta.REQUIRED && isExtensible(it) && !has(it, METADATA)) setMetadata(it);\n return it;\n};\n\nvar meta = module.exports = {\n REQUIRED: false,\n fastKey: fastKey,\n getWeakData: getWeakData,\n onFreeze: onFreeze\n};\n\nhiddenKeys[METADATA] = true;\n","var wellKnownSymbol = require('../internals/well-known-symbol');\nvar Iterators = require('../internals/iterators');\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar ArrayPrototype = Array.prototype;\n\n// check on default Array iterator\nmodule.exports = function (it) {\n return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it);\n};\n","var classof = require('../internals/classof');\nvar Iterators = require('../internals/iterators');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar ITERATOR = wellKnownSymbol('iterator');\n\nmodule.exports = function (it) {\n if (it != undefined) return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n","var anObject = require('../internals/an-object');\n\n// call something on iterator step with safe closing on error\nmodule.exports = function (iterator, fn, value, ENTRIES) {\n try {\n return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);\n // 7.4.6 IteratorClose(iterator, completion)\n } catch (error) {\n var returnMethod = iterator['return'];\n if (returnMethod !== undefined) anObject(returnMethod.call(iterator));\n throw error;\n }\n};\n","var anObject = require('../internals/an-object');\nvar isArrayIteratorMethod = require('../internals/is-array-iterator-method');\nvar toLength = require('../internals/to-length');\nvar bind = require('../internals/function-bind-context');\nvar getIteratorMethod = require('../internals/get-iterator-method');\nvar callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing');\n\nvar Result = function (stopped, result) {\n this.stopped = stopped;\n this.result = result;\n};\n\nvar iterate = module.exports = function (iterable, fn, that, AS_ENTRIES, IS_ITERATOR) {\n var boundFunction = bind(fn, that, AS_ENTRIES ? 2 : 1);\n var iterator, iterFn, index, length, result, next, step;\n\n if (IS_ITERATOR) {\n iterator = iterable;\n } else {\n iterFn = getIteratorMethod(iterable);\n if (typeof iterFn != 'function') throw TypeError('Target is not iterable');\n // optimisation for array iterators\n if (isArrayIteratorMethod(iterFn)) {\n for (index = 0, length = toLength(iterable.length); length > index; index++) {\n result = AS_ENTRIES\n ? boundFunction(anObject(step = iterable[index])[0], step[1])\n : boundFunction(iterable[index]);\n if (result && result instanceof Result) return result;\n } return new Result(false);\n }\n iterator = iterFn.call(iterable);\n }\n\n next = iterator.next;\n while (!(step = next.call(iterator)).done) {\n result = callWithSafeIterationClosing(iterator, boundFunction, step.value, AS_ENTRIES);\n if (typeof result == 'object' && result && result instanceof Result) return result;\n } return new Result(false);\n};\n\niterate.stop = function (result) {\n return new Result(true, result);\n};\n","module.exports = function (it, Constructor, name) {\n if (!(it instanceof Constructor)) {\n throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');\n } return it;\n};\n","var wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n var called = 0;\n var iteratorWithReturn = {\n next: function () {\n return { done: !!called++ };\n },\n 'return': function () {\n SAFE_CLOSING = true;\n }\n };\n iteratorWithReturn[ITERATOR] = function () {\n return this;\n };\n // eslint-disable-next-line no-throw-literal\n Array.from(iteratorWithReturn, function () { throw 2; });\n} catch (error) { /* empty */ }\n\nmodule.exports = function (exec, SKIP_CLOSING) {\n if (!SKIP_CLOSING && !SAFE_CLOSING) return false;\n var ITERATION_SUPPORT = false;\n try {\n var object = {};\n object[ITERATOR] = function () {\n return {\n next: function () {\n return { done: ITERATION_SUPPORT = true };\n }\n };\n };\n exec(object);\n } catch (error) { /* empty */ }\n return ITERATION_SUPPORT;\n};\n","var redefine = require('../internals/redefine');\n\nmodule.exports = function (target, src, options) {\n for (var key in src) redefine(target, key, src[key], options);\n return target;\n};\n","'use strict';\nvar defineProperty = require('../internals/object-define-property').f;\nvar create = require('../internals/object-create');\nvar redefineAll = require('../internals/redefine-all');\nvar bind = require('../internals/function-bind-context');\nvar anInstance = require('../internals/an-instance');\nvar iterate = require('../internals/iterate');\nvar defineIterator = require('../internals/define-iterator');\nvar setSpecies = require('../internals/set-species');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar fastKey = require('../internals/internal-metadata').fastKey;\nvar InternalStateModule = require('../internals/internal-state');\n\nvar setInternalState = InternalStateModule.set;\nvar internalStateGetterFor = InternalStateModule.getterFor;\n\nmodule.exports = {\n getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) {\n var C = wrapper(function (that, iterable) {\n anInstance(that, C, CONSTRUCTOR_NAME);\n setInternalState(that, {\n type: CONSTRUCTOR_NAME,\n index: create(null),\n first: undefined,\n last: undefined,\n size: 0\n });\n if (!DESCRIPTORS) that.size = 0;\n if (iterable != undefined) iterate(iterable, that[ADDER], that, IS_MAP);\n });\n\n var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME);\n\n var define = function (that, key, value) {\n var state = getInternalState(that);\n var entry = getEntry(that, key);\n var previous, index;\n // change existing entry\n if (entry) {\n entry.value = value;\n // create new entry\n } else {\n state.last = entry = {\n index: index = fastKey(key, true),\n key: key,\n value: value,\n previous: previous = state.last,\n next: undefined,\n removed: false\n };\n if (!state.first) state.first = entry;\n if (previous) previous.next = entry;\n if (DESCRIPTORS) state.size++;\n else that.size++;\n // add to index\n if (index !== 'F') state.index[index] = entry;\n } return that;\n };\n\n var getEntry = function (that, key) {\n var state = getInternalState(that);\n // fast case\n var index = fastKey(key);\n var entry;\n if (index !== 'F') return state.index[index];\n // frozen object case\n for (entry = state.first; entry; entry = entry.next) {\n if (entry.key == key) return entry;\n }\n };\n\n redefineAll(C.prototype, {\n // 23.1.3.1 Map.prototype.clear()\n // 23.2.3.2 Set.prototype.clear()\n clear: function clear() {\n var that = this;\n var state = getInternalState(that);\n var data = state.index;\n var entry = state.first;\n while (entry) {\n entry.removed = true;\n if (entry.previous) entry.previous = entry.previous.next = undefined;\n delete data[entry.index];\n entry = entry.next;\n }\n state.first = state.last = undefined;\n if (DESCRIPTORS) state.size = 0;\n else that.size = 0;\n },\n // 23.1.3.3 Map.prototype.delete(key)\n // 23.2.3.4 Set.prototype.delete(value)\n 'delete': function (key) {\n var that = this;\n var state = getInternalState(that);\n var entry = getEntry(that, key);\n if (entry) {\n var next = entry.next;\n var prev = entry.previous;\n delete state.index[entry.index];\n entry.removed = true;\n if (prev) prev.next = next;\n if (next) next.previous = prev;\n if (state.first == entry) state.first = next;\n if (state.last == entry) state.last = prev;\n if (DESCRIPTORS) state.size--;\n else that.size--;\n } return !!entry;\n },\n // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)\n // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)\n forEach: function forEach(callbackfn /* , that = undefined */) {\n var state = getInternalState(this);\n var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);\n var entry;\n while (entry = entry ? entry.next : state.first) {\n boundFunction(entry.value, entry.key, this);\n // revert to the last existing entry\n while (entry && entry.removed) entry = entry.previous;\n }\n },\n // 23.1.3.7 Map.prototype.has(key)\n // 23.2.3.7 Set.prototype.has(value)\n has: function has(key) {\n return !!getEntry(this, key);\n }\n });\n\n redefineAll(C.prototype, IS_MAP ? {\n // 23.1.3.6 Map.prototype.get(key)\n get: function get(key) {\n var entry = getEntry(this, key);\n return entry && entry.value;\n },\n // 23.1.3.9 Map.prototype.set(key, value)\n set: function set(key, value) {\n return define(this, key === 0 ? 0 : key, value);\n }\n } : {\n // 23.2.3.1 Set.prototype.add(value)\n add: function add(value) {\n return define(this, value = value === 0 ? 0 : value, value);\n }\n });\n if (DESCRIPTORS) defineProperty(C.prototype, 'size', {\n get: function () {\n return getInternalState(this).size;\n }\n });\n return C;\n },\n setStrong: function (C, CONSTRUCTOR_NAME, IS_MAP) {\n var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator';\n var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME);\n var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME);\n // add .keys, .values, .entries, [@@iterator]\n // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11\n defineIterator(C, CONSTRUCTOR_NAME, function (iterated, kind) {\n setInternalState(this, {\n type: ITERATOR_NAME,\n target: iterated,\n state: getInternalCollectionState(iterated),\n kind: kind,\n last: undefined\n });\n }, function () {\n var state = getInternalIteratorState(this);\n var kind = state.kind;\n var entry = state.last;\n // revert to the last existing entry\n while (entry && entry.removed) entry = entry.previous;\n // get next entry\n if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) {\n // or finish the iteration\n state.target = undefined;\n return { value: undefined, done: true };\n }\n // return step by kind\n if (kind == 'keys') return { value: entry.key, done: false };\n if (kind == 'values') return { value: entry.value, done: false };\n return { value: [entry.key, entry.value], done: false };\n }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);\n\n // add [@@species], 23.1.2.2, 23.2.2.2\n setSpecies(CONSTRUCTOR_NAME);\n }\n};\n","'use strict';\nvar charAt = require('../internals/string-multibyte').charAt;\nvar InternalStateModule = require('../internals/internal-state');\nvar defineIterator = require('../internals/define-iterator');\n\nvar STRING_ITERATOR = 'String Iterator';\nvar setInternalState = InternalStateModule.set;\nvar getInternalState = InternalStateModule.getterFor(STRING_ITERATOR);\n\n// `String.prototype[@@iterator]` method\n// https://tc39.github.io/ecma262/#sec-string.prototype-@@iterator\ndefineIterator(String, 'String', function (iterated) {\n setInternalState(this, {\n type: STRING_ITERATOR,\n string: String(iterated),\n index: 0\n });\n// `%StringIteratorPrototype%.next` method\n// https://tc39.github.io/ecma262/#sec-%stringiteratorprototype%.next\n}, function next() {\n var state = getInternalState(this);\n var string = state.string;\n var index = state.index;\n var point;\n if (index >= string.length) return { value: undefined, done: true };\n point = charAt(string, index);\n state.index += point.length;\n return { value: point, done: false };\n});\n","'use strict';\nvar $ = require('../internals/export');\nvar global = require('../internals/global');\nvar isForced = require('../internals/is-forced');\nvar redefine = require('../internals/redefine');\nvar InternalMetadataModule = require('../internals/internal-metadata');\nvar iterate = require('../internals/iterate');\nvar anInstance = require('../internals/an-instance');\nvar isObject = require('../internals/is-object');\nvar fails = require('../internals/fails');\nvar checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar inheritIfRequired = require('../internals/inherit-if-required');\n\nmodule.exports = function (CONSTRUCTOR_NAME, wrapper, common) {\n var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1;\n var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1;\n var ADDER = IS_MAP ? 'set' : 'add';\n var NativeConstructor = global[CONSTRUCTOR_NAME];\n var NativePrototype = NativeConstructor && NativeConstructor.prototype;\n var Constructor = NativeConstructor;\n var exported = {};\n\n var fixMethod = function (KEY) {\n var nativeMethod = NativePrototype[KEY];\n redefine(NativePrototype, KEY,\n KEY == 'add' ? function add(value) {\n nativeMethod.call(this, value === 0 ? 0 : value);\n return this;\n } : KEY == 'delete' ? function (key) {\n return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);\n } : KEY == 'get' ? function get(key) {\n return IS_WEAK && !isObject(key) ? undefined : nativeMethod.call(this, key === 0 ? 0 : key);\n } : KEY == 'has' ? function has(key) {\n return IS_WEAK && !isObject(key) ? false : nativeMethod.call(this, key === 0 ? 0 : key);\n } : function set(key, value) {\n nativeMethod.call(this, key === 0 ? 0 : key, value);\n return this;\n }\n );\n };\n\n // eslint-disable-next-line max-len\n if (isForced(CONSTRUCTOR_NAME, typeof NativeConstructor != 'function' || !(IS_WEAK || NativePrototype.forEach && !fails(function () {\n new NativeConstructor().entries().next();\n })))) {\n // create collection constructor\n Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER);\n InternalMetadataModule.REQUIRED = true;\n } else if (isForced(CONSTRUCTOR_NAME, true)) {\n var instance = new Constructor();\n // early implementations not supports chaining\n var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;\n // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false\n var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });\n // most early implementations doesn't supports iterables, most modern - not close it correctly\n // eslint-disable-next-line no-new\n var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); });\n // for early implementations -0 and +0 not the same\n var BUGGY_ZERO = !IS_WEAK && fails(function () {\n // V8 ~ Chromium 42- fails only with 5+ elements\n var $instance = new NativeConstructor();\n var index = 5;\n while (index--) $instance[ADDER](index, index);\n return !$instance.has(-0);\n });\n\n if (!ACCEPT_ITERABLES) {\n Constructor = wrapper(function (dummy, iterable) {\n anInstance(dummy, Constructor, CONSTRUCTOR_NAME);\n var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor);\n if (iterable != undefined) iterate(iterable, that[ADDER], that, IS_MAP);\n return that;\n });\n Constructor.prototype = NativePrototype;\n NativePrototype.constructor = Constructor;\n }\n\n if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {\n fixMethod('delete');\n fixMethod('has');\n IS_MAP && fixMethod('get');\n }\n\n if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);\n\n // weak collections should not contains .clear method\n if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear;\n }\n\n exported[CONSTRUCTOR_NAME] = Constructor;\n $({ global: true, forced: Constructor != NativeConstructor }, exported);\n\n setToStringTag(Constructor, CONSTRUCTOR_NAME);\n\n if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP);\n\n return Constructor;\n};\n","'use strict';\nvar collection = require('../internals/collection');\nvar collectionStrong = require('../internals/collection-strong');\n\n// `Map` constructor\n// https://tc39.github.io/ecma262/#sec-map-objects\nmodule.exports = collection('Map', function (init) {\n return function Map() { return init(this, arguments.length ? arguments[0] : undefined); };\n}, collectionStrong);\n","/**\r\n * 生成随机图表id\r\n */\r\nfunction generateRandomKey(prefix) {\r\n if (prefix == null) {\r\n prefix = 'chart'\r\n }\r\n\r\n var userAgent = window.navigator.userAgent\r\n .replace(/[^a-zA-Z0-9]/g, '')\r\n .split('')\r\n var mid = ''\r\n for (var i = 0; i < 12; i++) {\r\n mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))]\r\n }\r\n var time = new Date().getTime()\r\n\r\n return prefix + '_' + mid + '_' + time\r\n}\r\n/**\r\n * 深度克隆数据,包括对象,数组,map\r\n * @param {*} obj 对象,数组,map\r\n */\r\nfunction deepCopy(obj) {\r\n if (!isObject(obj) && !isMap(obj)) {\r\n return obj;\r\n }\r\n\r\n let cloneObj;\r\n if (isMap(obj)) {\r\n cloneObj = new Map();\r\n for (let key of obj.keys()) {\r\n let value = obj.get(key);\r\n if (isMap(value) || isObject(value) || Array.isArray(obj)) {\r\n let copyVal = deepCopy(value);\r\n cloneObj.set(key, copyVal);\r\n } else {\r\n cloneObj.set(key, value);\r\n }\r\n }\r\n } else if (typeof obj === \"function\") {\r\n cloneObj = obj\r\n } else {\r\n cloneObj = Array.isArray(obj) ? [] : {};\r\n if (obj instanceof HTMLElement) {\r\n cloneObj = obj.cloneNode(true)\r\n } else {\r\n for (let key in obj) {\r\n // if (obj.hasOwnProperty(key)) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n cloneObj[key] =\r\n isMap(obj[key]) || isObject(obj[key])\r\n ? deepCopy(obj[key])\r\n : obj[key];\r\n }\r\n }\r\n\r\n }\r\n }\r\n return cloneObj;\r\n}\r\n\r\n/**\r\n * 判断参数是否是Object类型\r\n * @param {*} o \r\n */\r\nfunction isObject(o) {\r\n return (\r\n !isMap(o) &&\r\n (typeof o === 'object' || typeof o === 'function') &&\r\n o !== null\r\n );\r\n}\r\n\r\n/**\r\n * 判断参数是否是Map类型\r\n * @param {*} obj \r\n */\r\nfunction isMap(obj) {\r\n if (obj instanceof Map) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n}\r\n\r\n// 替换temp中的${xxx}为指定内容 ,temp:字符串,这里指html代码,dataarry:一个对象{\"xxx\":\"替换的内容\"}\r\n// 例:luckysheet.replaceHtml(\"${image}\",{\"image\":\"abc\",\"jskdjslf\":\"abc\"}) ==> abc\r\nfunction replaceHtml(temp, dataarry) {\r\n return temp.replace(/\\$\\{([\\w]+)\\}/g, function (s1, s2) { var s = dataarry[s2]; if (typeof (s) != \"undefined\") { return s; } else { return s1; } });\r\n}\r\n\r\nfunction hasChinaword(s) {\r\n var patrn = /[\\u4E00-\\u9FA5]|[\\uFE30-\\uFFA0]/gi;\r\n if (!patrn.exec(s)) {\r\n return false;\r\n }\r\n else {\r\n return true;\r\n }\r\n}\r\n\r\nexport {\r\n isMap,\r\n isObject,\r\n deepCopy,\r\n generateRandomKey,\r\n replaceHtml\r\n}","import { getObjType } from '../utils/util';\r\nimport { isRealNum, isRealNull, valueIsError } from './validate';\r\nimport { update } from './format';\r\nimport formula from './formula';\r\nimport dayjs from \"dayjs\";\r\n\r\nconst error = {\r\n v: \"#VALUE!\", //错误的参数或运算符\r\n n: \"#NAME?\", //公式名称错误\r\n na: \"#N/A\", //函数或公式中没有可用数值\r\n r: \"#REF!\", //删除了由其他公式引用的单元格\r\n d: \"#DIV/0!\", //除数是0或空单元格\r\n nm: \"#NUM!\", //当公式或函数中某个数字有问题时\r\n nl: \"#NULL!\", //交叉运算符(空格)使用不正确\r\n sp: \"#SPILL!\" //数组范围有其它值\r\n}\r\n\r\nconst func_methods = {\r\n //单元格数据生成一维数组\r\n getCellDataArr: function(rangeObj, nullCellType, isNeglectNullCell){\r\n let dataArr = [];\r\n\r\n if(rangeObj.data == null){\r\n if(!isNeglectNullCell){\r\n if(nullCellType === \"number\"){\r\n dataArr.push(0);\r\n }\r\n else if(nullCellType === \"text\"){\r\n dataArr.push(\"\");\r\n }\r\n }\r\n }\r\n else{\r\n if(getObjType(rangeObj.data) === \"array\"){\r\n for(let i = 0; i < rangeObj.data.length; i++){\r\n for(let j = 0; j < rangeObj.data[i].length; j++){\r\n let cell = rangeObj.data[i][j];\r\n let value = cell\r\n\r\n if(getObjType(cell) === 'object'){\r\n value = cell.v\r\n }\r\n\r\n if(value == null ){\r\n if(!isNeglectNullCell){\r\n if(nullCellType === \"number\"){\r\n value = 0;\r\n }\r\n else if(nullCellType === \"text\"){\r\n value = '';\r\n }\r\n\r\n dataArr.push(value);\r\n }\r\n }\r\n else{\r\n dataArr.push(value);\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n if(isRealNull(rangeObj.data.v)){\r\n if(!isNeglectNullCell){\r\n if(nullCellType == \"number\"){\r\n dataArr.push(0);\r\n }\r\n else if(nullCellType == \"text\"){\r\n dataArr.push(\"\");\r\n }\r\n }\r\n }\r\n else{\r\n dataArr.push(rangeObj.data.v);\r\n }\r\n }\r\n }\r\n\r\n return dataArr;\r\n },\r\n //单元格数据生成二维数组\r\n getCellDataDyadicArr: function(rangeObj, nullCellType){\r\n let dataArr = [];\r\n\r\n if(rangeObj.data == null){\r\n let rowArr = [];\r\n\r\n if(nullCellType == \"number\"){\r\n rowArr.push(0);\r\n }\r\n else if(nullCellType == \"text\"){\r\n rowArr.push(\"\");\r\n }\r\n\r\n dataArr.push(rowArr);\r\n }\r\n else{\r\n if(getObjType(rangeObj.data) == \"array\"){\r\n for(let i = 0; i < rangeObj.data.length; i++){\r\n let rowArr = [];\r\n\r\n for(let j = 0; j < rangeObj.data[i].length; j++){\r\n let cell = rangeObj.data[i][j];\r\n let value = cell;\r\n\r\n if(getObjType(cell) === 'object'){\r\n value = cell.v\r\n }\r\n\r\n if(value == null){\r\n if(nullCellType === \"number\"){\r\n value = 0;\r\n }\r\n else if(nullCellType === \"text\"){\r\n value = '';\r\n }\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n dataArr.push(rowArr);\r\n }\r\n }\r\n else{\r\n let rowArr = [];\r\n\r\n let value = rangeObj.data.v;\r\n\r\n if(isRealNull(value)){\r\n if(nullCellType == \"number\"){\r\n value = 0;\r\n }\r\n else if(nullCellType == \"text\"){\r\n value = \"\";\r\n }\r\n }\r\n\r\n rowArr.push(value);\r\n\r\n dataArr.push(rowArr);\r\n }\r\n }\r\n\r\n return dataArr;\r\n },\r\n //数组数据生成一维数组\r\n getDataArr: function(arr, isNeglectNaN){\r\n let dataArr = [];\r\n\r\n if(isNeglectNaN == null){\r\n isNeglectNaN = false;\r\n }\r\n\r\n if(getObjType(arr[0]) == \"array\"){\r\n for(let i = 0; i < arr.length; i++){\r\n for(let j = 0; j < arr[i].length; j++){\r\n if(isNeglectNaN && !isRealNum(arr[i][j])){\r\n continue;\r\n }\r\n\r\n dataArr.push(arr[i][j]);\r\n }\r\n }\r\n }\r\n else{\r\n for(let i = 0; i < arr.length; i++){\r\n if(isNeglectNaN && !isRealNum(arr[i])){\r\n continue;\r\n }\r\n\r\n dataArr.push(arr[i]);\r\n }\r\n }\r\n\r\n return dataArr;\r\n },\r\n getDataDyadicArr: function(arr){\r\n let dataArr = [];\r\n\r\n if(getObjType(arr[0]) == \"array\"){\r\n for(let i = 0; i < arr.length; i++){\r\n let rowArr = [];\r\n\r\n for(let j = 0; j < arr[i].length; j++){\r\n rowArr.push(arr[i][j]);\r\n }\r\n\r\n dataArr.push(rowArr);\r\n }\r\n }\r\n else{\r\n let rowArr = [];\r\n\r\n for(let i = 0; i < arr.length; i++){\r\n rowArr.push(arr[i]);\r\n }\r\n\r\n dataArr.push(rowArr);\r\n }\r\n\r\n return dataArr;\r\n },\r\n //是否是规则二维数组\r\n isDyadicArr: function(arr){\r\n let isDyadic = true;\r\n\r\n if(arr.length > 1){\r\n let collen = arr[0].length;\r\n\r\n for(let i = 1; i < arr.length; i++){\r\n if(arr[i].length != collen){\r\n isDyadic = false;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return isDyadic;\r\n },\r\n //获取单个单元格数据,数组第一个值\r\n getFirstValue: function(data, nullCellType){\r\n let _this = this;\r\n\r\n if(nullCellType == null){\r\n nullCellType = \"number\";\r\n }\r\n\r\n let value;\r\n\r\n if(getObjType(data) == \"array\"){\r\n if(getObjType(data[0]) == \"array\"){\r\n if(!_this.isDyadicArr(data)){\r\n return error.v;\r\n }\r\n\r\n value = data[0][0];\r\n }\r\n else{\r\n value = data[0];\r\n }\r\n }\r\n else if(getObjType(data) == \"object\" && data.startCell != null){\r\n if(data.data == null){\r\n if(nullCellType == \"number\"){\r\n value = 0;\r\n }\r\n else if(nullCellType == \"text\"){\r\n value = \"\";\r\n }\r\n }\r\n else{\r\n let cell_r = window.luckysheetCurrentRow;\r\n let cell_c = window.luckysheetCurrentColumn;\r\n\r\n if(data.rowl == 1 && data.coll == 1){\r\n value = data.data;\r\n\r\n if(value == null || isRealNull(value.v)){\r\n if(nullCellType == \"number\"){\r\n value = 0;\r\n }\r\n else if(nullCellType == \"text\"){\r\n value = \"\";\r\n }\r\n }\r\n else{\r\n value = value.v;\r\n }\r\n }\r\n else{\r\n if(data.data[0][0].mc != null && data.data[0][0].mc.rs == data.rowl && data.data[0][0].mc.cs == data.coll){\r\n value = data.data[0][0];\r\n\r\n if(value == null || isRealNull(value.v)){\r\n if(nullCellType == \"number\"){\r\n value = 0;\r\n }\r\n else if(nullCellType == \"text\"){\r\n value = \"\";\r\n }\r\n }\r\n else{\r\n value = value.v;\r\n }\r\n }\r\n else if(data.rowl == 1 || data.coll == 1){\r\n let cellrange = formula.getcellrange(data.startCell);\r\n let str = cellrange.row[0],\r\n edr = str + data.rowl - 1,\r\n stc = cellrange.column[0],\r\n edc = stc + data.coll - 1;\r\n\r\n if(data.rowl == 1){\r\n if(cell_c < stc || cell_c > edc){\r\n return error.v;\r\n }\r\n\r\n value = data.data[0][cell_c - stc];\r\n }\r\n else if(data.coll == 1){\r\n if(cell_r < str || cell_r > edr){\r\n return error.v;\r\n }\r\n\r\n value = data.data[cell_r - str][0];\r\n }\r\n\r\n if(value == null || isRealNull(value.v) || value.mc != null){\r\n if(nullCellType == \"number\"){\r\n value = 0;\r\n }\r\n else if(nullCellType == \"text\"){\r\n value = \"\";\r\n }\r\n }\r\n else{\r\n value = value.v;\r\n }\r\n }\r\n else{\r\n return error.v;\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n value = data;\r\n }\r\n\r\n return value;\r\n },\r\n //获取单元格的逻辑值\r\n getCellBoolen: function(data){\r\n let _this = this;\r\n\r\n let cumulative = _this.getFirstValue(data);\r\n\r\n if(valueIsError(cumulative)){\r\n return cumulative;\r\n }\r\n\r\n if(getObjType(cumulative) == \"boolean\"){\r\n\r\n }\r\n else if(getObjType(cumulative) == \"string\" && (cumulative.toLowerCase() == \"true\" || cumulative.toLowerCase() == \"false\")){\r\n if(cumulative.toLowerCase() == \"true\"){\r\n cumulative = true;\r\n }\r\n else if(cumulative.toLowerCase() == \"false\"){\r\n cumulative = false;\r\n }\r\n }\r\n else if(isRealNum(cumulative)){\r\n cumulative = parseFloat(cumulative);\r\n\r\n cumulative = cumulative == 0 ? false : true;\r\n }\r\n else{\r\n return error.v;\r\n }\r\n\r\n return cumulative;\r\n },\r\n //获取单元格的日期\r\n getCellDate: function(data){\r\n let _this = this;\r\n\r\n let date_text;\r\n\r\n if(getObjType(data) == \"array\"){\r\n if(getObjType(data[0]) == \"array\"){\r\n if(!_this.isDyadicArr(data)){\r\n return error.v;\r\n }\r\n\r\n date_text = data[0][0];\r\n }\r\n else{\r\n date_text = data[0];\r\n }\r\n }\r\n else if(getObjType(data) == \"object\" && data.startCell != null){\r\n if(data.data == null || getObjType(data.data) == \"array\" || isRealNull(data.data.v)){\r\n return error.v;\r\n }\r\n\r\n date_text = data.data.v;\r\n\r\n if(data.data.ct != null && data.data.ct.t == \"d\"){\r\n date_text = update(\"YYYY-MM-DD h:mm:ss\", date_text);\r\n }\r\n }\r\n else{\r\n date_text = data;\r\n }\r\n\r\n return date_text;\r\n },\r\n getCellrangeDate: function(data){\r\n let _this = this;\r\n\r\n let date = [];\r\n\r\n if(getObjType(data) == \"array\"){\r\n if(getObjType(data[0]) == \"array\" && !_this.isDyadicArr(data)){\r\n return error.v;\r\n }\r\n\r\n date = date.concat(_this.getDataArr(data, false));\r\n }\r\n else if(getObjType(data) == \"object\" && data.startCell != null){\r\n if(data.data == null){\r\n date.push(0);\r\n }\r\n else{\r\n if(getObjType(data.data) == \"array\"){\r\n for(let i = 0; i < data.data.length; i++){\r\n for(let j = 0; j < data.data[i].length; j++){\r\n if(data.data[i][j] != null && !isRealNull(data.data[i][j].v)){\r\n let value = data.data[i][j].v;\r\n\r\n if(data.data[i][j].ct != null && data.data[i][j].ct.t == \"d\"){\r\n value = update(\"YYYY-MM-DD h:mm:ss\", value);\r\n }\r\n\r\n date.push(value);\r\n }\r\n else{\r\n date.push(0);\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n let value = data.data.v;\r\n\r\n if(data.data.ct != null && data.data.ct.t == \"d\"){\r\n value = update(\"YYYY-MM-DD h:mm:ss\", value);\r\n }\r\n\r\n date.push(value);\r\n }\r\n }\r\n }\r\n else{\r\n date.push(data);\r\n }\r\n\r\n return date;\r\n },\r\n //获取正则字符串(处理 . * ? ~* ~?)\r\n getRegExpStr: function(str){\r\n return str.replace(\"~*\", \"\\\\*\").replace(\"~?\", \"\\\\?\").replace(\".\", \"\\\\.\").replace(\"*\", \".*\").replace(\"?\", \".\");\r\n },\r\n //阶乘\r\n factorial: function(num){\r\n if (num == 0 || num == 1) {\r\n return 1;\r\n }\r\n else {\r\n return (num * this.factorial(num - 1));\r\n }\r\n },\r\n //双阶乘\r\n factorialDouble: function(num){\r\n if (num <= 0) {\r\n return 1;\r\n }\r\n else {\r\n return (num * this.factorialDouble(num - 2));\r\n }\r\n },\r\n //总体方差\r\n variance: function(num_arr){\r\n let sum = 0, count = 0;\r\n\r\n for(let i = 0; i < num_arr.length; i++){\r\n let number = num_arr[i];\r\n\r\n sum += number;\r\n count++;\r\n }\r\n\r\n let avg = sum / count;\r\n\r\n let sum_variance = 0;\r\n\r\n for(let j = 0; j < num_arr.length; j++){\r\n let number = num_arr[j];\r\n\r\n sum_variance += (number - avg) * (number - avg);\r\n }\r\n\r\n return sum_variance / count;\r\n },\r\n //样本方差\r\n variance_s: function(num_arr){\r\n let sum = 0, count = 0;\r\n\r\n for(let i = 0; i < num_arr.length; i++){\r\n let number = num_arr[i];\r\n\r\n sum += number;\r\n count++;\r\n }\r\n\r\n let avg = sum / count;\r\n\r\n let sum_variance = 0;\r\n\r\n for(let j = 0; j < num_arr.length; j++){\r\n let number = num_arr[j];\r\n\r\n sum_variance += (number - avg) * (number - avg);\r\n }\r\n\r\n return sum_variance / (count - 1);\r\n },\r\n //总体标准偏差\r\n standardDeviation: function(num_arr){\r\n let sum = 0, count = 0;\r\n\r\n for(let i = 0; i < num_arr.length; i++){\r\n let number = num_arr[i];\r\n\r\n sum += number;\r\n count++;\r\n }\r\n\r\n let avg = sum / count;\r\n\r\n let sum_variance = 0;\r\n\r\n for(let j = 0; j < num_arr.length; j++){\r\n let number = num_arr[j];\r\n\r\n sum_variance += (number - avg) * (number - avg);\r\n }\r\n\r\n return Math.sqrt(sum_variance / count);\r\n },\r\n //样本标准偏差\r\n standardDeviation_s: function(num_arr){\r\n let sum = 0, count = 0;\r\n\r\n for(let i = 0; i < num_arr.length; i++){\r\n let number = num_arr[i];\r\n\r\n sum += number;\r\n count++;\r\n }\r\n\r\n let avg = sum / count;\r\n\r\n let sum_variance = 0;\r\n\r\n for(let j = 0; j < num_arr.length; j++){\r\n let number = num_arr[j];\r\n\r\n sum_variance += (number - avg) * (number - avg);\r\n }\r\n\r\n return Math.sqrt(sum_variance / (count - 1));\r\n },\r\n //是否是闰年\r\n isLeapYear: function(year){\r\n return new Date(year, 1, 29).getMonth() === 1;\r\n },\r\n //2月是否有29\r\n feb29Between: function(date1, date2){\r\n let _this = this;\r\n\r\n let year1 = dayjs(date1).year();\r\n let mar1year1 = dayjs().set({ 'year': year1, 'month': 2, 'date': 1 });\r\n\r\n if (_this.isLeapYear(year1) && dayjs(date1) < dayjs(mar1year1) && dayjs(date2) >= dayjs(mar1year1)) {\r\n return true;\r\n }\r\n\r\n let year2 = dayjs(date2).year();\r\n let mar1year2 = dayjs().set({ 'year': year2, 'month': 2, 'date': 1 });\r\n\r\n return (_this.isLeapYear(year2) && dayjs(date2) >= dayjs(mar1year2) && dayjs(date1) < dayjs(mar1year2));\r\n },\r\n //SQL 查询\r\n findResultIndex: function(database, criterias){\r\n let matches = {};\r\n\r\n for (let i = 1; i < database[0].length; ++i) {\r\n matches[i] = true;\r\n }\r\n\r\n let maxCriteriaLength = criterias[0].length;\r\n\r\n for (i = 1; i < criterias.length; ++i) {\r\n if (criterias[i].length > maxCriteriaLength) {\r\n maxCriteriaLength = criterias[i].length;\r\n }\r\n }\r\n\r\n for (let k = 1; k < database.length; ++k) {\r\n for (let l = 1; l < database[k].length; ++l) {\r\n let currentCriteriaResult = false;\r\n let hasMatchingCriteria = false;\r\n\r\n for (let j = 0; j < criterias.length; ++j) {\r\n let criteria = criterias[j];\r\n\r\n if (criteria.length < maxCriteriaLength) {\r\n continue;\r\n }\r\n\r\n let criteriaField = criteria[0];\r\n\r\n if (database[k][0] !== criteriaField) {\r\n continue;\r\n }\r\n\r\n hasMatchingCriteria = true;\r\n\r\n for (let p = 1; p < criteria.length; ++p) {\r\n currentCriteriaResult = currentCriteriaResult || (new Function(\"return \" + database[k][l] + criteria[p])()); // jshint ignore:line\r\n }\r\n }\r\n\r\n if (hasMatchingCriteria) {\r\n matches[l] = matches[l] && currentCriteriaResult;\r\n }\r\n }\r\n }\r\n\r\n let result = [];\r\n\r\n for (let n = 0; n < database[0].length; ++n) {\r\n if (matches[n]) {\r\n result.push(n - 1);\r\n }\r\n }\r\n\r\n return result;\r\n },\r\n findField: function(database, title){\r\n let index = null;\r\n\r\n for (let i = 0; i < database.length; i++) {\r\n if (database[i][0] == title) {\r\n index = i;\r\n break;\r\n }\r\n }\r\n\r\n if (index == null) {\r\n return error.v;\r\n }\r\n\r\n return index;\r\n },\r\n rest: function(array, idx){\r\n idx = idx || 1;\r\n\r\n if (!array || typeof array.slice !== 'function') {\r\n return array;\r\n }\r\n\r\n return array.slice(idx);\r\n },\r\n compact: function(array){\r\n if (!array) {\r\n return array;\r\n }\r\n\r\n let result = [];\r\n\r\n for (let i = 0; i < array.length; ++i) {\r\n if (!array[i]) {\r\n continue;\r\n }\r\n\r\n result.push(array[i]);\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n\r\nexport default func_methods;\r\n","var matrix = ({});\r\n\r\nvar init = function init(matrix){\r\n var sylvester_matrix = function() {};\r\n\r\n sylvester_matrix.precision = 1e-6;\r\n\r\n sylvester_matrix.create = function(elements) {\r\n var M = new sylvester_matrix();\r\n return M.setElements(elements);\r\n };\r\n var $M = sylvester_matrix.create;\r\n \r\n sylvester_matrix.I = function(n) {\r\n var els = [], i = n, j;\r\n while (i--) { j = n;\r\n els[i] = [];\r\n while (j--) {\r\n els[i][j] = (i === j) ? 1 : 0;\r\n }\r\n }\r\n return sylvester_matrix.create(els);\r\n };\r\n\r\n sylvester_matrix.prototype = {\r\n e: function(i,j) {\r\n if (i < 1 || i > this.elements.length || j < 1 || j > this.elements[0].length) { return null; }\r\n return this.elements[i-1][j-1];\r\n },\r\n dimensions: function() {\r\n var cols = (this.elements.length === 0) ? 0 : this.elements[0].length;\r\n return {rows: this.elements.length, cols: cols};\r\n },\r\n rows: function() {\r\n return this.elements.length;\r\n },\r\n cols: function() {\r\n if (this.elements.length === 0) { return 0; }\r\n return this.elements[0].length;\r\n },\r\n eql: function(matrix) {\r\n var M = matrix.elements || matrix;\r\n if (!M[0] || typeof(M[0][0]) === 'undefined') { M = sylvester_matrix.create(M).elements; }\r\n if (this.elements.length === 0 || M.length === 0) {\r\n return this.elements.length === M.length;\r\n }\r\n if (this.elements.length !== M.length) { return false; }\r\n if (this.elements[0].length !== M[0].length) { return false; }\r\n var i = this.elements.length, nj = this.elements[0].length, j;\r\n while (i--) { j = nj;\r\n while (j--) {\r\n if (Math.abs(this.elements[i][j] - M[i][j]) > sylvester_matrix.precision) { return false; }\r\n }\r\n }\r\n return true;\r\n },\r\n dup: function() {\r\n return sylvester_matrix.create(this.elements);\r\n },\r\n map: function(fn, context) {\r\n if (this.elements.length === 0) { \r\n return sylvester_matrix.create([]); \r\n }\r\n var els = [], i = this.elements.length, nj = this.elements[0].length, j;\r\n while (i--) { \r\n j = nj;\r\n els[i] = [];\r\n while (j--) {\r\n els[i][j] = fn.call(context, this.elements[i][j], i + 1, j + 1);\r\n }\r\n }\r\n return sylvester_matrix.create(els);\r\n },\r\n isSameSizeAs: function(matrix) {\r\n var M = matrix.elements || matrix;\r\n if (typeof(M[0][0]) === 'undefined') { \r\n M = sylvester_matrix.create(M).elements; \r\n }\r\n if (this.elements.length === 0) { \r\n return M.length === 0; \r\n }\r\n return (this.elements.length === M.length && this.elements[0].length === M[0].length);\r\n },\r\n add: function(matrix) {\r\n if (this.elements.length === 0) return this.map(function(x) { return x });\r\n var M = matrix.elements || matrix;\r\n if (typeof(M[0][0]) === 'undefined') { M = sylvester_matrix.create(M).elements; }\r\n if (!this.isSameSizeAs(M)) { return null; }\r\n return this.map(function(x, i, j) { return x + M[i-1][j-1]; });\r\n },\r\n subtract: function(matrix) {\r\n if (this.elements.length === 0) return this.map(function(x) { return x });\r\n var M = matrix.elements || matrix;\r\n if (typeof(M[0][0]) === 'undefined') { M = sylvester_matrix.create(M).elements; }\r\n if (!this.isSameSizeAs(M)) { return null; }\r\n return this.map(function(x, i, j) { return x - M[i-1][j-1]; });\r\n },\r\n canMultiplyFromLeft: function(matrix) {\r\n if (this.elements.length === 0) { return false; }\r\n var M = matrix.elements || matrix;\r\n if (typeof(M[0][0]) === 'undefined') { M = sylvester_matrix.create(M).elements; }\r\n // this.columns should equal matrix.rows\r\n return (this.elements[0].length === M.length);\r\n },\r\n multiply: function(matrix) {\r\n if (this.elements.length === 0) { return null; }\r\n if (!matrix.elements) {\r\n return this.map(function(x) { return x * matrix; });\r\n }\r\n var returnVector = matrix.modulus ? true : false;\r\n var M = matrix.elements || matrix;\r\n if (typeof(M[0][0]) === 'undefined') { M = sylvester_matrix.create(M).elements; }\r\n if (!this.canMultiplyFromLeft(M)) { return null; }\r\n var i = this.elements.length, nj = M[0].length, j;\r\n var cols = this.elements[0].length, c, elements = [], sum;\r\n while (i--) { j = nj;\r\n elements[i] = [];\r\n while (j--) { c = cols;\r\n sum = 0;\r\n while (c--) {\r\n sum += this.elements[i][c] * M[c][j];\r\n }\r\n elements[i][j] = sum;\r\n }\r\n }\r\n var M = sylvester_matrix.create(elements);\r\n return returnVector ? M.col(1) : M;\r\n },\r\n minor: function(a, b, c, d) {\r\n if (this.elements.length === 0) { return null; }\r\n var elements = [], ni = c, i, nj, j;\r\n var rows = this.elements.length, cols = this.elements[0].length;\r\n while (ni--) { i = c - ni - 1;\r\n elements[i] = [];\r\n nj = d;\r\n while (nj--) { j = d - nj - 1;\r\n elements[i][j] = this.elements[(a+i-1)%rows][(b+j-1)%cols];\r\n }\r\n }\r\n return sylvester_matrix.create(elements);\r\n },\r\n transpose: function() {\r\n if (this.elements.length === 0) return sylvester_matrix.create([]);\r\n var rows = this.elements.length, i, cols = this.elements[0].length, j;\r\n var elements = [], i = cols;\r\n while (i--) { j = rows;\r\n elements[i] = [];\r\n while (j--) {\r\n elements[i][j] = this.elements[j][i];\r\n }\r\n }\r\n return sylvester_matrix.create(elements);\r\n },\r\n isSquare: function() {\r\n var cols = (this.elements.length === 0) ? 0 : this.elements[0].length;\r\n return (this.elements.length === cols);\r\n },\r\n max: function() {\r\n if (this.elements.length === 0) { return null; }\r\n var m = 0, i = this.elements.length, nj = this.elements[0].length, j;\r\n while (i--) { j = nj;\r\n while (j--) {\r\n if (Math.abs(this.elements[i][j]) > Math.abs(m)) { m = this.elements[i][j]; }\r\n }\r\n }\r\n return m;\r\n },\r\n indexOf: function(x) {\r\n if (this.elements.length === 0) { return null; }\r\n var index = null, ni = this.elements.length, i, nj = this.elements[0].length, j;\r\n for (i = 0; i < ni; i++) {\r\n for (j = 0; j < nj; j++) {\r\n if (this.elements[i][j] === x) { return {i: i+1, j: j+1}; }\r\n }\r\n }\r\n return null;\r\n },\r\n diagonal: function() {\r\n if (!this.isSquare) { return null; }\r\n var els = [], n = this.elements.length;\r\n for (var i = 0; i < n; i++) {\r\n els.push(this.elements[i][i]);\r\n }\r\n return sylvester_matrix.create(els);\r\n },\r\n toRightTriangular: function() {\r\n if (this.elements.length === 0) return sylvester_matrix.create([]);\r\n var M = this.dup(), els;\r\n var n = this.elements.length, i, j, np = this.elements[0].length, p;\r\n for (i = 0; i < n; i++) {\r\n if (M.elements[i][i] === 0) {\r\n for (j = i + 1; j < n; j++) {\r\n if (M.elements[j][i] !== 0) {\r\n els = [];\r\n for (p = 0; p < np; p++) { \r\n els.push(M.elements[i][p] + M.elements[j][p]); \r\n }\r\n M.elements[i] = els;\r\n break;\r\n }\r\n }\r\n }\r\n if (M.elements[i][i] !== 0) {\r\n for (j = i + 1; j < n; j++) {\r\n var multiplier = M.elements[j][i] / M.elements[i][i];\r\n els = [];\r\n for (p = 0; p < np; p++) {\r\n // Elements with column numbers up to an including the number of the\r\n // row that we're subtracting can safely be set straight to zero,\r\n // since that's the point of this routine and it avoids having to\r\n // loop over and correct rounding errors later\r\n els.push(p <= i ? 0 : M.elements[j][p] - M.elements[i][p] * multiplier);\r\n }\r\n M.elements[j] = els;\r\n }\r\n }\r\n }\r\n return M;\r\n },\r\n determinant: function() {\r\n if (this.elements.length === 0) { return 1; }\r\n if (!this.isSquare()) { return null; }\r\n var M = this.toRightTriangular();\r\n var det = M.elements[0][0], n = M.elements.length;\r\n for (var i = 1; i < n; i++) {\r\n det = det * M.elements[i][i];\r\n }\r\n return det;\r\n },\r\n isSingular: function() {\r\n return (this.isSquare() && this.determinant() === 0);\r\n },\r\n trace: function() {\r\n if (this.elements.length === 0) { return 0; }\r\n if (!this.isSquare()) { return null; }\r\n var tr = this.elements[0][0], n = this.elements.length;\r\n for (var i = 1; i < n; i++) {\r\n tr += this.elements[i][i];\r\n }\r\n return tr;\r\n },\r\n rank: function() {\r\n if (this.elements.length === 0) { return 0; }\r\n var M = this.toRightTriangular(), rank = 0;\r\n var i = this.elements.length, nj = this.elements[0].length, j;\r\n while (i--) { j = nj;\r\n while (j--) {\r\n if (Math.abs(M.elements[i][j]) > sylvester_matrix.precision) { rank++; break; }\r\n }\r\n }\r\n return rank;\r\n },\r\n augment: function(matrix) {\r\n if (this.elements.length === 0) { return this.dup(); }\r\n var M = matrix.elements || matrix;\r\n if (typeof(M[0][0]) === 'undefined') { M = sylvester_matrix.create(M).elements; }\r\n var T = this.dup(), cols = T.elements[0].length;\r\n var i = T.elements.length, nj = M[0].length, j;\r\n if (i !== M.length) { return null; }\r\n while (i--) { \r\n j = nj;\r\n while (j--) {\r\n T.elements[i][cols + j] = M[i][j];\r\n }\r\n }\r\n return T;\r\n },\r\n inverse: function() {\r\n if (this.elements.length === 0) { return null; }\r\n if (!this.isSquare() || this.isSingular()) { return null; }\r\n var n = this.elements.length, i= n, j;\r\n var M = this.augment(sylvester_matrix.I(n)).toRightTriangular();\r\n var np = M.elements[0].length, p, els, divisor;\r\n var inverse_elements = [], new_element;\r\n // Sylvester.Matrix is non-singular so there will be no zeros on the\r\n // diagonal. Cycle through rows from last to first.\r\n while (i--) {\r\n // First, normalise diagonal elements to 1\r\n els = [];\r\n inverse_elements[i] = [];\r\n divisor = M.elements[i][i];\r\n for (p = 0; p < np; p++) {\r\n new_element = M.elements[i][p] / divisor;\r\n els.push(new_element);\r\n // Shuffle off the current row of the right hand side into the results\r\n // array as it will not be modified by later runs through this loop\r\n if (p >= n) { inverse_elements[i].push(new_element); }\r\n }\r\n M.elements[i] = els;\r\n // Then, subtract this row from those above it to give the identity matrix\r\n // on the left hand side\r\n j = i;\r\n while (j--) {\r\n els = [];\r\n for (p = 0; p < np; p++) {\r\n els.push(M.elements[j][p] - M.elements[i][p] * M.elements[j][i]);\r\n }\r\n M.elements[j] = els;\r\n }\r\n }\r\n return sylvester_matrix.create(inverse_elements);\r\n },\r\n round: function() {\r\n return this.map(function(x) { return Math.round(x); });\r\n },\r\n snapTo: function(x) {\r\n return this.map(function(p) {\r\n return (Math.abs(p - x) <= sylvester_matrix.precision) ? x : p;\r\n });\r\n },\r\n setElements: function(els) {\r\n var i, j, elements = els.elements || els;\r\n if (elements[0] && typeof(elements[0][0]) !== 'undefined') {\r\n i = elements.length;\r\n this.elements = [];\r\n while (i--) { j = elements[i].length;\r\n this.elements[i] = [];\r\n while (j--) {\r\n this.elements[i][j] = elements[i][j];\r\n }\r\n }\r\n return this;\r\n }\r\n var n = elements.length;\r\n this.elements = [];\r\n for (i = 0; i < n; i++) {\r\n this.elements.push([elements[i]]);\r\n }\r\n return this;\r\n }\r\n };\r\n\r\n matrix.sylvester_matrix = sylvester_matrix;\r\n}\r\ninit(matrix);\r\n\r\nexport function inverse(els){\r\n var M = matrix.sylvester_matrix.create(els);\r\n return M.inverse().elements;\r\n}","import func_methods from '../global/func_methods';\r\nimport formula from '../global/formula';\r\nimport tooltip from '../global/tooltip';\r\nimport { isRealNum, valueIsError,error } from '../global/validate';\r\nimport { getdatabyselectionD } from '../global/getdata';\r\nimport { genarate } from '../global/format';\r\nimport { inverse } from '../function/matrix_methods';\r\nimport { getSheetIndex, getluckysheetfile, getRangetxt } from '../methods/get';\r\nimport { getObjType, ABCatNum } from '../utils/util';\r\nimport Store from '../store';\r\nimport numeral from 'numeral';\r\n\r\n//函数功能:比较或运算\r\nfunction luckysheet_compareWith() {\r\n //第一个参数和第三个参数,返回比较结果的布尔值或者运算值\r\n //formula.operatorjson; 存储运算符和比较符\r\n let sp = arguments[1]; //操作符\r\n\r\n //参数一\r\n let data_fp = arguments[0];\r\n let fp;\r\n if(getObjType(data_fp) == \"object\" && data_fp.startCell != null){ //参数是选区\r\n if(sp == \"&\"){\r\n fp = func_methods.getCellDataDyadicArr(data_fp, \"text\");\r\n }\r\n else{\r\n fp = func_methods.getCellDataDyadicArr(data_fp, \"number\");\r\n }\r\n\r\n if(fp.length == 1 && fp[0].length == 1){\r\n fp = fp[0][0];\r\n }\r\n }\r\n else{\r\n fp = data_fp;\r\n }\r\n\r\n //参数二\r\n let data_tp = arguments[2];\r\n let tp;\r\n if(getObjType(data_tp) == \"object\" && data_tp.startCell != null){ //参数是选区\r\n if(sp == \"&\"){\r\n tp = func_methods.getCellDataDyadicArr(data_tp, \"text\");\r\n }\r\n else{\r\n tp = func_methods.getCellDataDyadicArr(data_tp, \"number\");\r\n }\r\n\r\n if(tp.length == 1 && tp[0].length == 1){\r\n tp = tp[0][0];\r\n }\r\n }\r\n else{\r\n tp = data_tp;\r\n }\r\n\r\n if(valueIsError(fp)){\r\n return fp;\r\n }\r\n\r\n if(valueIsError(tp)){\r\n return tp;\r\n }\r\n\r\n //参数是不规则二维数组 时 return #VALUE! 错误\r\n if(getObjType(fp) == \"array\" && getObjType(fp[0]) == \"array\" && !func_methods.isDyadicArr(fp)){\r\n return error.v; \r\n }\r\n\r\n if(getObjType(tp) == \"array\" && getObjType(tp[0]) == \"array\" && !func_methods.isDyadicArr(tp)){\r\n return error.v; \r\n }\r\n\r\n if(sp == \"<>\"){\r\n sp = \"!=\";\r\n }\r\n\r\n if(sp == \"=\"){\r\n sp = \"==\";\r\n }\r\n\r\n if(fp==null && tp==null){\r\n return \"#INVERSE!\";\r\n }\r\n else if(fp==\"#INVERSE!\"){\r\n fp =0;\r\n if(sp==\"-\"){\r\n sp = \"+\";\r\n }\r\n else if(sp==\"+\"){\r\n sp = \"-\";\r\n }\r\n }\r\n else if(sp == \"-\" && fp == null){\r\n fp = 0;\r\n }\r\n else if(sp == \"/\" && (tp == 0 || tp == null)){\r\n return error.d;\r\n }\r\n\r\n //计算result\r\n function booleanOperation(a, operator, b){\r\n if(isRealNum(a)){\r\n a = parseFloat(a);\r\n }\r\n\r\n if(isRealNum(b)){\r\n b = parseFloat(b);\r\n }\r\n\r\n if(operator == \"==\"){\r\n if(a == b){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n else if(operator == \"!=\"){\r\n if(a != b){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n else if(operator == \">=\"){\r\n if(a >= b){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n else if(operator == \"<=\"){\r\n if(a <= b){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n else if(operator == \">\"){\r\n if(a > b){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n else if(operator == \"<\"){\r\n if(a < b){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n //布尔值对应数字(true = 1, false = 1)\r\n function booleanToNum(v){\r\n if(v == null){\r\n return v;\r\n }\r\n\r\n if(v.toString().toLowerCase() == \"true\"){\r\n return 1;\r\n }\r\n\r\n if(v.toString().toLowerCase() == \"false\"){\r\n return 0;\r\n }\r\n\r\n return v;\r\n }\r\n \r\n if(sp == \"*\"){ //乘\r\n if(getObjType(fp) == \"array\" && getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\" && getObjType(tp[0]) == \"array\"){\r\n //二维数组相乘(m*n 与 m*n 等于 m*n;m*p 与 p*n 等于 m*n;其它错误) \r\n if(fp.length == tp.length && fp[0].length == tp[0].length){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[m][n])){\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp[m][n]);//parseFloat(fp[m][n]) * parseFloat(tp[m][n]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(fp[0].length == tp.length){\r\n let rowlen = fp.length;\r\n let collen = tp[0].length;\r\n\r\n for(let m = 0; m < rowlen; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < collen; n++){\r\n let value = 0;\r\n\r\n for(let p = 0; p < fp[0].length; p++){\r\n fp[m][p] = booleanToNum(fp[m][p]);\r\n tp[p][n] = booleanToNum(tp[p][n]);\r\n\r\n if(isRealNum(fp[m][p]) && isRealNum(tp[p][n])){\r\n value += luckysheet_calcADPMM(fp[m][p], sp, tp[p][n]);//parseFloat(fp[m][p]) * parseFloat(tp[p][n]);\r\n }\r\n else{\r\n value += error.v;\r\n }\r\n }\r\n\r\n if(value.toString() == \"NaN\"){\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(fp.length == tp[0].length){\r\n let rowlen = tp.length;\r\n let collen = fp[0].length;\r\n\r\n for(let m = 0; m < rowlen; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < collen; n++){\r\n let value = 0;\r\n\r\n for(let p = 0; p < tp[0].length; p++){\r\n fp[p][n] = booleanToNum(fp[p][n]);\r\n tp[m][p] = booleanToNum(tp[m][p]);\r\n\r\n if(isRealNum(tp[m][p]) && isRealNum(fp[p][n])){\r\n value += luckysheet_calcADPMM(fp[p][n], sp, tp[m][p]);//parseFloat(tp[m][p]) * parseFloat(fp[p][n]);\r\n }\r\n else{\r\n value += error.v;\r\n }\r\n }\r\n\r\n if(value.toString() == \"NaN\"){\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n return error.na;\r\n }\r\n }\r\n else if(getObjType(fp[0]) == \"array\"){\r\n //二维数组与一维数组相乘(m*n 与 n 等于 m*n;m*1 与 n 等于 m*n;其它错误)\r\n if(fp[0].length == tp.length){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[n])){\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp[n]);//parseFloat(fp[m][n]) * parseFloat(tp[n]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(fp[0].length == 1){\r\n let rowlen = fp.length;\r\n let collen = tp.length;\r\n\r\n for(let m = 0; m < rowlen; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < collen; n++){\r\n fp[m][0] = booleanToNum(fp[m][0]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][0]) && isRealNum(tp[n])){\r\n value = luckysheet_calcADPMM(fp[m][0], sp, tp[n]);// parseFloat(fp[m][0]) * parseFloat(tp[n]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n return error.na;\r\n }\r\n }\r\n else if(getObjType(tp[0]) == \"array\"){\r\n //二维数组与一维数组相乘(m*n 与 n 等于 m*n;m*1 与 n 等于 m*n;其它错误)\r\n if(tp[0].length == fp.length){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[m][n])){\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[m][n]);// parseFloat(fp[n]) * parseFloat(tp[m][n]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(tp[0].length == 1){\r\n let rowlen = tp.length;\r\n let collen = fp.length;\r\n\r\n for(let m = 0; m < rowlen; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < collen; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[m][0] = booleanToNum(tp[m][0]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[m][0])){\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[m][0]);//parseFloat(fp[n]) * parseFloat(tp[m][0]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n return error.na;\r\n }\r\n }\r\n else{\r\n //一维数组与一维数组相乘时,数组大小不一样是错误\r\n if(fp.length != tp.length){\r\n return error.na; \r\n }\r\n\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[n])){\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[n]);// parseFloat(fp[n]) * parseFloat(tp[n]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(fp) == \"array\"){\r\n tp = booleanToNum(tp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\"){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp)){\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp);// parseFloat(fp[m][n]) * parseFloat(tp);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp)){\r\n value = luckysheet_calcADPMM(fp[n], sp, tp);// parseFloat(fp[n]) * parseFloat(tp);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(tp) == \"array\"){\r\n fp = booleanToNum(fp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(tp[0]) == \"array\"){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[m][n])){\r\n value = luckysheet_calcADPMM(fp, sp, tp[m][n]);// parseFloat(fp) * parseFloat(tp[m][n]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < tp.length; n++){\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[n])){\r\n value = luckysheet_calcADPMM(fp, sp, tp[n]);//parseFloat(fp) * parseFloat(tp[n]);\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else{\r\n fp = booleanToNum(fp);\r\n tp = booleanToNum(tp);\r\n\r\n let result;\r\n if(isRealNum(fp) && isRealNum(tp)){\r\n result = luckysheet_calcADPMM(fp, sp, tp);//parseFloat(fp) * parseFloat(tp);\r\n }\r\n else{\r\n result = error.v;\r\n }\r\n\r\n return result;\r\n }\r\n }\r\n else if(sp == \"/\"){ //除\r\n if(getObjType(fp) == \"array\" && getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\" && getObjType(tp[0]) == \"array\"){\r\n //二维数组相除(m*n 与 m*n 等于 m*n;m*p 与 p*n 等于 m*n;其它错误) \r\n if(fp.length == tp.length && fp[0].length == tp[0].length){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[m][n])){\r\n if(parseFloat(tp[m][n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp[m][n]);// parseFloat(fp[m][n]) / parseFloat(tp[m][n]); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(fp[0].length == tp.length){\r\n let tp_inverse = inverse(tp);\r\n\r\n let rowlen = fp.length;\r\n let collen = tp_inverse[0].length;\r\n\r\n for(let m = 0; m < rowlen; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < collen; n++){\r\n let value = 0;\r\n\r\n for(let p = 0; p < fp[0].length; p++){\r\n fp[m][p] = booleanToNum(fp[m][p]);\r\n tp_inverse[p][n] = booleanToNum(tp_inverse[p][n]);\r\n\r\n if(isRealNum(fp[m][p]) && isRealNum(tp_inverse[p][n])){\r\n value += luckysheet_calcADPMM(fp[m][p], \"*\", tp_inverse[p][n]);// parseFloat(fp[m][p]) * parseFloat(tp_inverse[p][n]);\r\n }\r\n else{\r\n value += error.v;\r\n }\r\n }\r\n\r\n if(value.toString() == \"NaN\"){\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n return error.na;\r\n }\r\n }\r\n else if(getObjType(fp[0]) == \"array\"){\r\n //二维数组与一维数组相除(m*n 与 n 等于 m*n;m*1 与 n 等于 m*n;其它错误)\r\n if(fp[0].length == tp.length){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[n])){\r\n if(parseFloat(tp[n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp[n]);// parseFloat(fp[m][n]) / parseFloat(tp[n]);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(fp[0].length == 1){\r\n let rowlen = fp.length;\r\n let collen = tp.length;\r\n\r\n for(let m = 0; m < rowlen; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < collen; n++){\r\n fp[m][0] = booleanToNum(fp[m][0]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][0]) && isRealNum(tp[n])){\r\n if(parseFloat(tp[n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[m][0], sp, tp[n]);// parseFloat(fp[m][0]) / parseFloat(tp[n]);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n return error.na;\r\n }\r\n }\r\n else if(getObjType(tp[0]) == \"array\"){\r\n //二维数组与一维数组相除(m*n 与 n 等于 m*n;m*1 与 n 等于 m*n;其它错误)\r\n if(tp[0].length == fp.length){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[m][n])){\r\n if(parseFloat(tp[m][n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[m][n]);//parseFloat(fp[n]) / parseFloat(tp[m][n]);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(tp[0].length == 1){\r\n let rowlen = tp.length;\r\n let collen = fp.length;\r\n\r\n for(let m = 0; m < rowlen; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < collen; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[m][0] = booleanToNum(tp[m][0]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[m][0])){\r\n if(parseFloat(tp[m][0]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[m][0]);//parseFloat(fp[n]) / parseFloat(tp[m][0]);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n return error.na;\r\n }\r\n }\r\n else{\r\n //一维数组与一维数组相除时,数组大小不一样是错误\r\n if(fp.length != tp.length){\r\n return error.na; \r\n }\r\n\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[n])){\r\n if(parseFloat(tp[n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[n]);//parseFloat(fp[n]) / parseFloat(tp[n]);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(fp) == \"array\"){\r\n tp = booleanToNum(tp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\"){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp)){\r\n if(parseFloat(tp) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp);//parseFloat(fp[m][n]) / parseFloat(tp);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp)){\r\n if(parseFloat(tp) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[n], sp, tp);//parseFloat(fp[n]) / parseFloat(tp);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(tp) == \"array\"){\r\n fp = booleanToNum(fp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(tp[0]) == \"array\"){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[m][n])){\r\n if(parseFloat(tp[m][n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp, sp, tp[m][n]);//parseFloat(fp) / parseFloat(tp[m][n]);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < tp.length; n++){\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[n])){\r\n if(parseFloat(tp[n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp, sp, tp[n]);//parseFloat(fp) / parseFloat(tp[n]);\r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else{\r\n fp = booleanToNum(fp);\r\n tp = booleanToNum(tp);\r\n\r\n let result;\r\n if(isRealNum(fp) && isRealNum(tp)){\r\n if(parseFloat(tp) == 0){\r\n result = error.d;\r\n }\r\n else{\r\n result = luckysheet_calcADPMM(fp, sp, tp);//parseFloat(fp) / parseFloat(tp);\r\n }\r\n }\r\n else{\r\n result = error.v;\r\n }\r\n\r\n return result;\r\n }\r\n }\r\n else if(sp == \"+\" || sp == \"-\" || sp == \"%\"){ //加 减 取余\r\n if(getObjType(fp) == \"array\" && getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\" && getObjType(tp[0]) == \"array\"){\r\n if(fp.length != tp.length && fp[0].length != tp[0].length){\r\n return error.na; \r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[m][n])){\r\n if(sp == \"%\" && parseFloat(tp[m][n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp[m][n]);// eval(parseFloat(fp[m][n]) + sp + parseFloat(tp[m][n])); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(fp[0]) == \"array\"){\r\n if(fp[0].length != tp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[n])){\r\n if(sp == \"%\" && parseFloat(tp[n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp[n]);//eval(parseFloat(fp[m][n]) + sp + parseFloat(tp[n])); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(tp[0]) == \"array\"){\r\n if(tp[0].length != fp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[m][n])){\r\n if(sp == \"%\" && parseFloat(tp[m][n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[m][n]);//eval(parseFloat(fp[n]) + sp + parseFloat(tp[m][n])); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n if(fp.length != tp.length){\r\n return error.na; \r\n }\r\n\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[n])){\r\n if(sp == \"%\" && parseFloat(tp[n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[n], sp, tp[n]);//eval(parseFloat(fp[n]) + sp + \"(\" + parseFloat(tp[n]) + \")\" ); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(fp) == \"array\"){\r\n tp = booleanToNum(tp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\"){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp)){\r\n if(sp == \"%\" && parseFloat(tp) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[m][n], sp, tp);//eval(parseFloat(fp[m][n]) + sp + parseFloat(tp)); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp)){\r\n if(sp == \"%\" && parseFloat(tp) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp[n], sp, tp);//eval(parseFloat(fp[n]) + sp + parseFloat(tp)); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(tp) == \"array\"){\r\n fp = booleanToNum(fp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(tp[0]) == \"array\"){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[m][n])){\r\n if(sp == \"%\" && parseFloat(tp[m][n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp, sp, tp[m][n]);//eval(parseFloat(fp) + sp + parseFloat(tp[m][n])); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < tp.length; n++){\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[n])){\r\n if(sp == \"%\" && parseFloat(tp[n]) == 0){\r\n value = error.d;\r\n }\r\n else{\r\n value = luckysheet_calcADPMM(fp, sp, tp[n]);//eval(parseFloat(fp) + sp + parseFloat(tp[n])); \r\n }\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else{\r\n fp = booleanToNum(fp);\r\n tp = booleanToNum(tp);\r\n\r\n let result;\r\n if(isRealNum(fp) && isRealNum(tp)){\r\n if(sp == \"%\" && parseFloat(tp) == 0){\r\n result = error.d;\r\n }\r\n else{\r\n result = luckysheet_calcADPMM(fp, sp, tp);//eval(parseFloat(fp) + sp + \"(\" + parseFloat(tp) + \")\"); \r\n }\r\n }\r\n else{\r\n result = error.v;\r\n }\r\n\r\n return result;\r\n }\r\n }\r\n else if(sp == \"==\" || sp == \"!=\" || sp == \">=\" || sp == \"<=\" || sp == \">\" || sp == \"<\"){ //比较运算符\r\n if(getObjType(fp) == \"array\" && getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\" && getObjType(tp[0]) == \"array\"){\r\n if(fp.length != tp.length && fp[0].length != tp[0].length){\r\n return error.na; \r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n let value = booleanOperation(fp[m][n], sp, tp[m][n]);\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(fp[0]) == \"array\"){\r\n if(fp[0].length != tp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n let value = booleanOperation(fp[m][n], sp, tp[n]);\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(tp[0]) == \"array\"){\r\n if(tp[0].length != fp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n let value = booleanOperation(fp[n], sp, tp[m][n]);\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n if(fp.length != tp.length){\r\n return error.na; \r\n }\r\n\r\n for(let n = 0; n < fp.length; n++){\r\n let value = booleanOperation(fp[n], sp, tp[n]);\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(fp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\"){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n let value = booleanOperation(fp[m][n], sp, tp);\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < fp.length; n++){\r\n let value = booleanOperation(fp[n], sp, tp);\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(tp[0]) == \"array\"){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n let value = booleanOperation(fp, sp, tp[m][n]);\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < tp.length; n++){\r\n let value = booleanOperation(fp, sp, tp[n]);\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else{\r\n return booleanOperation(fp, sp, tp);\r\n }\r\n }\r\n else if(sp == \"&\"){ //连接符\r\n if(getObjType(fp) == \"array\" && getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\" && getObjType(tp[0]) == \"array\"){\r\n if(fp.length != tp.length && fp[0].length != tp[0].length){\r\n return error.na; \r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n rowArr.push(fp[m][n] + \"\" + tp[m][n]);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(fp[0]) == \"array\"){\r\n if(fp[0].length != tp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n rowArr.push(fp[m][n] + \"\" + tp[n]);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(tp[0]) == \"array\"){\r\n if(tp[0].length != fp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n rowArr.push(fp[n] + \"\" + tp[m][n]);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n if(fp.length != tp.length){\r\n return error.na; \r\n }\r\n\r\n for(let n = 0; n < fp.length; n++){\r\n result.push(fp[n] + \"\" + tp[n]);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(fp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\"){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n rowArr.push(fp[m][n] + \"\" + tp);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < fp.length; n++){\r\n result.push(fp[n] + \"\" + tp);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(tp[0]) == \"array\"){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n rowArr.push(fp + \"\" + tp[m][n]);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < tp.length; n++){\r\n result.push(fp + \"\" + tp[n]);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else{\r\n return fp + \"\" + tp;\r\n }\r\n }\r\n else if(sp == \"^\"){ //幂\r\n if(getObjType(fp) == \"array\" && getObjType(tp) == \"array\"){\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\" && getObjType(tp[0]) == \"array\"){\r\n if(fp.length != tp.length && fp[0].length != tp[0].length){\r\n return error.na; \r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[m][n])){\r\n value = Math.pow(parseFloat(fp[m][n]), parseFloat(tp[m][n]));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(fp[0]) == \"array\"){\r\n if(fp[0].length != tp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp[n])){\r\n value = Math.pow(parseFloat(fp[m][n]), parseFloat(tp[n]));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else if(getObjType(tp[0]) == \"array\"){\r\n if(tp[0].length != fp.length){\r\n return error.na;\r\n }\r\n\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[m][n])){\r\n value = Math.pow(parseFloat(fp[n]), parseFloat(tp[m][n]));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n if(fp.length != tp.length){\r\n return error.na; \r\n }\r\n\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp[n])){\r\n value = Math.pow(parseFloat(fp[n]), parseFloat(tp[n]));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(fp) == \"array\"){\r\n tp = booleanToNum(tp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(fp[0]) == \"array\"){\r\n for(let m = 0; m < fp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < fp[m].length; n++){\r\n fp[m][n] = booleanToNum(fp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp[m][n]) && isRealNum(tp)){\r\n value = Math.pow(parseFloat(fp[m][n]), parseFloat(tp));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < fp.length; n++){\r\n fp[n] = booleanToNum(fp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp[n]) && isRealNum(tp)){\r\n value = Math.pow(parseFloat(fp[n]), parseFloat(tp));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else if(getObjType(tp) == \"array\"){\r\n fp = booleanToNum(fp);\r\n\r\n let result = [];\r\n\r\n if(getObjType(tp[0]) == \"array\"){\r\n for(let m = 0; m < tp.length; m++){\r\n let rowArr = [];\r\n\r\n for(let n = 0; n < tp[m].length; n++){\r\n tp[m][n] = booleanToNum(tp[m][n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[m][n])){\r\n value = Math.pow(parseFloat(fp), parseFloat(tp[m][n]));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n rowArr.push(value);\r\n }\r\n\r\n result.push(rowArr);\r\n }\r\n }\r\n else{\r\n for(let n = 0; n < tp.length; n++){\r\n tp[n] = booleanToNum(tp[n]);\r\n\r\n let value;\r\n if(isRealNum(fp) && isRealNum(tp[n])){\r\n value = Math.pow(parseFloat(fp), parseFloat(tp[n]));\r\n }\r\n else{\r\n value = error.v;\r\n }\r\n\r\n result.push(value);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n else{\r\n fp = booleanToNum(fp);\r\n tp = booleanToNum(tp);\r\n\r\n let result;\r\n if(isRealNum(fp) && isRealNum(tp)){\r\n result = Math.pow(parseFloat(fp), parseFloat(tp));\r\n }\r\n else{\r\n result = error.v;\r\n }\r\n\r\n return result;\r\n }\r\n }\r\n}\r\n\r\n//解析 公式中{1,2,3;2,3,4} 为数组[[1,2,3],[2,3,4]]\r\nfunction luckysheet_getarraydata() {\r\n let fp = arguments[0];\r\n\r\n fp = fp.replace(\"{\", \"\").replace(\"}\", \"\").replace(/\\\"/g, '');\r\n\r\n let arr = [];\r\n\r\n if(fp.indexOf(\";\") > -1){\r\n arr = fp.split(\";\");\r\n\r\n for(let i = 0; i < arr.length; i++){\r\n arr[i] = arr[i].split(\",\");\r\n }\r\n }\r\n else{\r\n arr = fp.split(\",\"); \r\n }\r\n\r\n return arr;\r\n}\r\n\r\nfunction luckysheet_calcADPMM(fp, sp, tp){\r\n let value;\r\n if(sp==\"+\"){\r\n value = numeral(fp).add(tp).value();\r\n }\r\n else if(sp==\"-\"){\r\n value = numeral(fp).subtract(tp).value();\r\n }\r\n else if(sp==\"%\"){\r\n value = new Function(\"return \" + parseFloat(fp) + sp + \"(\" + parseFloat(tp) + \")\" )();\r\n }\r\n else if(sp==\"/\"){\r\n value = numeral(fp).divide(tp).value();\r\n }\r\n else if(sp==\"*\"){\r\n value = numeral(fp).multiply(tp).value();\r\n }\r\n return value;\r\n}\r\n\r\nfunction luckysheet_getcelldata(txt) {\r\n if (window.luckysheet_getcelldata_cache == null) {\r\n window.luckysheet_getcelldata_cache = {};\r\n }\r\n\r\n if (txt in window.luckysheet_getcelldata_cache) {\r\n return window.luckysheet_getcelldata_cache[txt];\r\n }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n let val = txt.split(\"!\");\r\n let sheettxt = \"\",\r\n rangetxt = \"\",\r\n sheetIndex = -1,\r\n sheetdata = null;\r\n \r\n if (val.length > 1) {\r\n sheettxt = val[0].replace(/''/g,\"'\");\r\n rangetxt = val[1];\r\n\r\n if(sheettxt.substr(0,1)==\"'\" && sheettxt.substr(sheettxt.length-1,1)==\"'\"){\r\n sheettxt = sheettxt.substring(1,sheettxt.length-1);\r\n }\r\n \r\n for (let i in luckysheetfile) {\r\n if (sheettxt == luckysheetfile[i].name) {\r\n sheetIndex = luckysheetfile[i].index;\r\n sheetdata = luckysheetfile[i].data;\r\n break;\r\n }\r\n }\r\n\r\n if (sheetIndex == -1) {\r\n sheetIndex = 0;\r\n }\r\n } \r\n else {\r\n let index = getSheetIndex(Store.calculateSheetIndex);\r\n sheettxt = luckysheetfile[index].name;\r\n sheetIndex = luckysheetfile[index].index;\r\n // sheetdata = Store.flowdata;\r\n sheetdata = luckysheetfile[index].data;\r\n rangetxt = val[0];\r\n\r\n // 取消execFunctionGroupData,改用execFunctionGlobalData\r\n // if (formula.execFunctionGroupData != null) {\r\n // sheetdata = formula.execFunctionGroupData;\r\n // }\r\n }\r\n\r\n if (rangetxt.indexOf(\":\") == -1) {\r\n let row = parseInt(rangetxt.replace(/[^0-9]/g, \"\")) - 1;\r\n let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, \"\"));\r\n\r\n if (!isNaN(row) && !isNaN(col)) {\r\n let ret = getdatabyselectionD(sheetdata, {\r\n \"row\": [row, row],\r\n \"column\": [col, col]\r\n })[0][0];\r\n\r\n if (formula.execFunctionGlobalData != null) {\r\n let ef = formula.execFunctionGlobalData[row+\"_\"+col+\"_\"+sheetIndex];\r\n if(ef!=null){\r\n ret = ef;\r\n }\r\n }\r\n\r\n //范围的长宽\r\n let rowl = 1;\r\n let coll = 1;\r\n let retAll= {\r\n \"sheetName\": sheettxt,\r\n \"startCell\": rangetxt,\r\n \"rowl\": rowl,\r\n \"coll\": coll,\r\n \"data\": ret\r\n };\r\n\r\n window.luckysheet_getcelldata_cache[txt] = retAll;\r\n\r\n return retAll;\r\n } \r\n else {\r\n return [];\r\n }\r\n } \r\n else {\r\n rangetxt = rangetxt.split(\":\");\r\n let row = [], col = [];\r\n row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, \"\")) - 1;\r\n row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, \"\")) - 1;\r\n \r\n if (isNaN(row[0])) {\r\n row[0] = 0;\r\n }\r\n\r\n if (isNaN(row[1])) {\r\n row[1] = sheetdata.length - 1;\r\n }\r\n\r\n if (row[0] > row[1]) {\r\n tooltip.info(\"选择失败\", \"输入范围错误!\");\r\n return [];\r\n }\r\n\r\n col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, \"\"));\r\n col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, \"\"));\r\n \r\n if (isNaN(col[0])) {\r\n col[0] = 0;\r\n }\r\n\r\n if (isNaN(col[1])) {\r\n col[1] = sheetdata[0].length - 1;\r\n }\r\n\r\n if (col[0] > col[1]) {\r\n tooltip.info(\"选择失败\", \"输入范围错误!\");\r\n return [];\r\n }\r\n \r\n let ret = getdatabyselectionD(sheetdata, {\r\n \"row\": row,\r\n \"column\": col\r\n });\r\n\r\n if(formula.execFunctionGlobalData!=null){\r\n for(let r=row[0];r<=row[1];r++){\r\n for(let c=col[0];c<=col[1];c++){\r\n let ef = formula.execFunctionGlobalData[r+\"_\"+c+\"_\"+sheetIndex];\r\n if(ef!=null){\r\n ret[r-row[0]][c-col[0]] = ef;\r\n }\r\n }\r\n }\r\n }\r\n\r\n \r\n //范围的长宽\r\n let rowl = row[1] - row[0] + 1;\r\n let coll = col[1] - col[0] + 1;\r\n let retAll= {\r\n \"sheetName\": sheettxt,\r\n \"startCell\": rangetxt[0],\r\n \"rowl\": rowl,\r\n \"coll\": coll,\r\n \"data\": ret\r\n };\r\n \r\n window.luckysheet_getcelldata_cache[txt] = retAll;\r\n\r\n return retAll;\r\n }\r\n}\r\n\r\n//解析单个取得的值,有字符串,数字,引用单元格或者函数\r\nfunction luckysheet_parseData(value) {\r\n if(typeof value === \"object\" ){\r\n if(value == null){\r\n return \"\";\r\n }\r\n else if(Array.isArray(value)){ //函数返回的带期望格式的数组,可提取格式\r\n let v = genarate(value[0]);\r\n return v[2];\r\n }\r\n else{ //getcelldat引用单元格对象,带有格式\r\n if(Array.isArray(value.data)){ //单元格区域\r\n return error.v; \r\n }\r\n else{ //单个单元格\r\n if(value.data.v === undefined){\r\n return \"\";\r\n }\r\n else{\r\n return value.data.v;\r\n }\r\n }\r\n }\r\n }\r\n else if(!formula.isCompareOperator(value).flag){\r\n let v = genarate(value);\r\n return v[2];\r\n }\r\n else if(typeof value === \"string\" || typeof value === \"number\"){\r\n return value;\r\n }\r\n\r\n return error.v;\r\n}\r\n\r\nfunction luckysheet_getValue() {\r\n //解析获取函数参数,无格式,且可包含带操作符的\">5\"\r\n //数据类型:1.手动输入或函数返回的字符串,普通字符串或数字直接取值,特殊格式需转化 如:\"2019-1-1\"(特殊格式转化为数字)、\">5\"或数字\r\n //2.引用单元格对象,取得二维数组或单个的v 如:A1\r\n //3.函数返回的带期望格式的数组,取得第一个参数,转化为数字 如:[\"2019-1-1\",true]\r\n let args = arguments[0];\r\n\r\n for(let i = 0; i < args.length; i++){\r\n let value = args[i];\r\n\r\n if(typeof value === \"object\" ){\r\n if(value == null){\r\n value = \"\";\r\n }\r\n else if(Array.isArray(value)){ //函数返回的带期望格式的数组,可提取格式\r\n let v = genarate(value[0]);\r\n value = v[2];\r\n }\r\n else{ //getcelldat引用单元格对象,带有格式\r\n if(Array.isArray(value.data)){ //单元格区域\r\n value = value.data; \r\n }\r\n else{ //单个单元格\r\n if(value.data.v === undefined){ //空白单元格\r\n value = \"\";\r\n }\r\n else{\r\n value = value.data.v;\r\n }\r\n }\r\n }\r\n }\r\n else if(!formula.isCompareOperator(value).flag){\r\n let v = genarate(value);\r\n value = v[2];\r\n }\r\n \r\n args[i] = value;\r\n }\r\n}\r\n\r\n\r\nfunction luckysheet_indirect_check() {\r\n let cellTxt = arguments[0];\r\n if (cellTxt == null || cellTxt.length == 0) {\r\n return null;\r\n }\r\n return cellTxt;\r\n}\r\n\r\nfunction luckysheet_indirect_check_return(txt) {\r\n return txt;\r\n}\r\n\r\nfunction luckysheet_offset_check() {\r\n if (!(getObjType(arguments[0]) == \"object\" && arguments[0].startCell != null)) {\r\n return formula.error.v;\r\n }\r\n\r\n var reference = arguments[0].startCell;\r\n\r\n //要偏移的行数\r\n var rows = func_methods.getFirstValue(arguments[1]);\r\n if (valueIsError(rows)) {\r\n return rows;\r\n }\r\n\r\n if (!isRealNum(rows)) {\r\n return formula.error.v;\r\n }\r\n\r\n rows = parseInt(rows);\r\n\r\n //要偏移的列数\r\n var cols = func_methods.getFirstValue(arguments[2]);\r\n if (valueIsError(cols)) {\r\n return cols;\r\n }\r\n\r\n if (!isRealNum(cols)) {\r\n return formula.error.v;\r\n }\r\n\r\n cols = parseInt(cols);\r\n\r\n //要从偏移目标开始返回的范围的高度\r\n var height = arguments[0].rowl;\r\n if (arguments.length >= 4) {\r\n height = func_methods.getFirstValue(arguments[3]);\r\n if (valueIsError(height)) {\r\n return height;\r\n }\r\n\r\n if (!isRealNum(height)) {\r\n return formula.error.v;\r\n }\r\n\r\n height = parseInt(height);\r\n }\r\n\r\n //要从偏移目标开始返回的范围的宽度\r\n var width = arguments[0].coll;\r\n if (arguments.length == 5) {\r\n width = func_methods.getFirstValue(arguments[4]);\r\n if (valueIsError(width)) {\r\n return width;\r\n }\r\n\r\n if (!isRealNum(width)) {\r\n return formula.error.v;\r\n }\r\n\r\n width = parseInt(width);\r\n }\r\n\r\n if (height < 1 || width < 1) {\r\n return formula.error.r;\r\n }\r\n\r\n //计算\r\n var cellrange = formula.getcellrange(reference);\r\n var cellRow0 = cellrange[\"row\"][0];\r\n var cellCol0 = cellrange[\"column\"][0];\r\n\r\n cellRow0 += rows;\r\n cellCol0 += cols;\r\n\r\n var cellRow1 = cellRow0 + height - 1;\r\n var cellCol1 = cellCol0 + width - 1;\r\n\r\n if (cellRow0 < 0 || cellRow1 >= Store.flowdata.length || cellCol0 < 0 || cellCol1 >= Store.flowdata[0].length) {\r\n return formula.error.r;\r\n }\r\n\r\n return getRangetxt(Store.calculateSheetIndex, {\r\n row: [cellRow0, cellRow1],\r\n column: [cellCol0, cellCol1]\r\n });\r\n}\r\n\r\n\r\nfunction luckysheet_getSpecialReference(isCellFirst, param1, param2) {\r\n let functionRange, rangeTxt;\r\n if(isCellFirst){\r\n rangeTxt = param1;\r\n functionRange = param2;\r\n }\r\n else{\r\n functionRange = param1;\r\n rangeTxt = param2;\r\n }\r\n\r\n if(functionRange.startCell.indexOf(\":\")>-1 || rangeTxt.indexOf(\":\")>-1){\r\n return error.v;\r\n }\r\n\r\n\r\n if(isCellFirst){\r\n return luckysheet_getcelldata(rangeTxt + \":\" +functionRange.startCell);\r\n }\r\n else{\r\n let rangeT = rangeTxt, sheetName=\"\";\r\n if(rangeTxt.indexOf(\"!\")>-1){\r\n let rangetxtArr = rangeTxt.split(\"!\");\r\n sheetName = rangetxtArr[0] + \"!\";\r\n rangeT = rangetxtArr[1];\r\n }\r\n return luckysheet_getcelldata(sheetName + functionRange.startCell + \":\" + rangeT);\r\n }\r\n\r\n \r\n\r\n}\r\n\r\nexport {\r\n luckysheet_compareWith,\r\n luckysheet_getarraydata,\r\n luckysheet_getcelldata,\r\n luckysheet_parseData,\r\n luckysheet_getValue,\r\n luckysheet_indirect_check,\r\n luckysheet_indirect_check_return,\r\n luckysheet_offset_check,\r\n luckysheet_calcADPMM,\r\n luckysheet_getSpecialReference\r\n}","import { seriesLoadScripts, loadLinks, $$, arrayRemoveItem } from '../../utils/util'\r\nimport { generateRandomKey, replaceHtml } from '../../utils/chartUtil'\r\nimport { getdatabyselection, getcellvalue } from '../../global/getdata';\r\nimport chartInfo from '../../store'\r\nimport formula from '../../global/formula';\r\nimport { luckysheet_getcelldata } from '../../function/func';\r\nimport { getSheetIndex, getRangetxt, getvisibledatacolumn, getvisibledatarow } from '../../methods/get'\r\nimport { rowLocation, colLocation, mouseposition } from '../../global/location'\r\nimport { setluckysheet_scroll_status } from '../../methods/set'\r\nimport {\r\n luckysheetMoveHighlightCell,\r\n luckysheetMoveHighlightCell2, \r\n luckysheetMoveHighlightRange,\r\n luckysheetMoveHighlightRange2,\r\n luckysheetMoveEndCell\r\n} from '../../controllers/sheetMove';\r\nimport { isEditMode } from '../../global/validate';\r\nimport luckysheetsizeauto from '../../controllers/resize';\r\nlet _rowLocation = rowLocation\r\nlet _colLocation = colLocation\r\n\r\n// Dynamically load dependent scripts and styles\r\nconst dependScripts = [\r\n 'https://cdn.jsdelivr.net/npm/vue@2.6.11',\r\n 'https://unpkg.com/vuex@3.4.0',\r\n 'https://cdn.bootcdn.net/ajax/libs/element-ui/2.13.2/index.js',\r\n 'https://cdn.bootcdn.net/ajax/libs/echarts/4.8.0/echarts.min.js',\r\n 'expendPlugins/chart/chartmix.umd.min.js',\r\n // 'http://26.26.26.1:8000/chartmix.umd.js'\r\n]\r\n\r\nconst dependLinks = [\r\n 'https://cdn.bootcdn.net/ajax/libs/element-ui/2.13.2/theme-chalk/index.css',\r\n 'expendPlugins/chart/chartmix.css',\r\n // 'http://26.26.26.1:8000/chartmix.css'\r\n]\r\n\r\n// Initialize the chart component\r\nfunction chart(data, isDemo) {\r\n loadLinks(dependLinks);\r\n\r\n seriesLoadScripts(dependScripts, null, function () {\r\n const store = new Vuex.Store()\r\n console.info('chartmix::', chartmix.default)\r\n\r\n Vue.use(chartmix.default, { store })\r\n let outDom = document.getElementsByTagName('body')[0]\r\n chartmix.default.initChart(outDom, chartInfo.lang)\r\n\r\n $('.chartSetting').css({\r\n top: '1px',\r\n bottom: '1px',\r\n position: 'absolute',\r\n right: '0px',\r\n width: '350px',\r\n background: '#fff',\r\n\r\n border: '1px solid #E5E5E5',\r\n 'z-index': 1004,\r\n 'box-shadow': '0px 2px 4px rgba(0,0,0,0.2)',\r\n '-webkit-box-shadow': '0px 2px 4px rgba(0,0,0,0.2)',\r\n '-moz-box-shadow': '0px 2px 4px rgba(0,0,0,0.2)',\r\n '-moz-user-select': 'none',\r\n '-khtml-user-select': 'none',\r\n '-webkit-user-select': 'none',\r\n '-ms-user-select': 'none',\r\n 'user-select': 'none',\r\n 'padding-left': '30px',\r\n display: 'none'\r\n })\r\n\r\n\r\n chartInfo.createChart = chartmix.default.createChart\r\n chartInfo.highlightChart = chartmix.default.highlightChart\r\n chartInfo.deleteChart = chartmix.default.deleteChart\r\n chartInfo.resizeChart = chartmix.default.resizeChart\r\n chartInfo.changeChartRange = chartmix.default.changeChartRange\r\n chartInfo.changeChartCellData = chartmix.default.changeChartCellData\r\n chartInfo.getChartJson = chartmix.default.getChartJson\r\n chartInfo.chart_selection = chart_selection()\r\n chartInfo.chartparam.jfrefreshchartall = jfrefreshchartall\r\n chartInfo.chartparam.changeChartCellData = chartmix.default.changeChartCellData\r\n chartInfo.chartparam.renderChart = chartmix.default.renderChart\r\n chartInfo.chartparam.getChartJson = chartmix.default.getChartJson\r\n chartInfo.chartparam.insertToStore = chartmix.default.insertToStore\r\n\r\n // Initialize the rendering chart\r\n for (let i = 0; i < data.length; i++) {\r\n // if (data[i].status == '1') {\r\n renderCharts(data[i].chart, isDemo)\r\n // }\r\n }\r\n\r\n for (let i = 0; i < data.length; i++) {\r\n if (data[i].status == '1') {\r\n renderChartShow(data[i].index)\r\n }\r\n }\r\n\r\n // After the chart is loaded, mark it\r\n arrayRemoveItem(chartInfo.asyncLoad,'chart');\r\n\r\n });\r\n}\r\n\r\n// rendercharts\r\nfunction renderCharts(chartLists, isDemo) {\r\n\r\n // no chart\r\n if(chartLists == undefined){\r\n return;\r\n }\r\n\r\n for (let i = 0; i < chartLists.length; i++) {\r\n let chart = chartLists[i]\r\n\r\n if (isDemo) {\r\n chartInfo.chartparam.insertToStore({ chart_id: chart.chart_id, chartOptions: chart.chartOptions })\r\n }\r\n\r\n let chart_id = chart.chart_id\r\n let chart_id_c = chart_id + '_c'\r\n let modelChartShowHTML =\r\n '
${content}
'\r\n\r\n let $t = $(\r\n replaceHtml(modelChartShowHTML, {\r\n id: chart_id_c,\r\n addclass: 'luckysheet-data-visualization-chart',\r\n title: '图表生成',\r\n content: ''\r\n })\r\n ).appendTo($('.luckysheet-cell-main'))\r\n\r\n setChartMoveableEffect($t);\r\n\r\n $(`#${chart_id_c}`).children('.luckysheet-modal-dialog-content')[0].id = chart_id\r\n\r\n let container = document.getElementById(chart_id_c)\r\n\r\n\r\n let chart_json\r\n chart_json = chartInfo.chartparam.getChartJson(chart.chart_id)\r\n\r\n chartInfo.chartparam.renderChart({ chart_id: chart.chart_id, chartOptions: chart_json })\r\n chartInfo.currentChart = chart_json\r\n\r\n //处理区域高亮框参数,当前页中,只有当前的图表的needRangShow为true,其他为false\r\n showNeedRangeShow(chart_id);\r\n\r\n // delete current chart\r\n $(`#${chart_id}_c .luckysheet-modal-controll-del`).click(function (e) {\r\n delChart(chart_id)\r\n })\r\n\r\n // edit current chart\r\n $(`#${chart_id}_c .luckysheet-modal-controll-update`).click(function (e) {\r\n showChartSettingComponent()\r\n })\r\n\r\n $t.children('.luckysheet-modal-dialog-content').mousedown(function (e) {\r\n if (!chartInfo.chartparam.luckysheetCurrentChartMaxState) {\r\n //当前图表显示区域高亮\r\n showNeedRangeShow(chart_id);\r\n }\r\n e.stopPropagation()\r\n })\r\n $t.mousedown(function (e) { // move chart\r\n\r\n if (!chartInfo.chartparam.luckysheetCurrentChartMaxState) {\r\n //当前图表显示区域高亮\r\n showNeedRangeShow(chart_id);\r\n setluckysheet_scroll_status(true);\r\n\r\n //允许拖动渲染框\r\n if (\r\n !$(e.target).is(\".luckysheet-modal-dialog-controll\") &&\r\n !$(e.target).is(\".luckysheet-modal-controll-btn\") &&\r\n !$(e.target).is(\"i\")\r\n ) {\r\n // Debounce\r\n chartInfo.chartparam.luckysheetCurrentChartMoveTimeout = setTimeout(\r\n function () {\r\n chartInfo.chartparam.luckysheetCurrentChartMove = true;\r\n },\r\n 100\r\n );\r\n }\r\n\r\n var toffset = chartInfo.chartparam.luckysheetCurrentChartMoveObj.offset();\r\n var tpsition = chartInfo.chartparam.luckysheetCurrentChartMoveObj.position();\r\n //luckysheetCurrentChartMoveXy: [鼠标点相对chart框的距离X方向,鼠标点相对chart框的距离Y方向,chart框相对cell-main的距离X方向,chart框相对cell-main的距离Y方向,水平滚动条的位置,垂直滚动条的位置]\r\n chartInfo.chartparam.luckysheetCurrentChartMoveXy = [\r\n e.pageX - toffset.left,\r\n e.pageY - toffset.top,\r\n tpsition.left,\r\n tpsition.top,\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(),\r\n $(\"#luckysheet-scrollbar-y\").scrollTop()\r\n ];\r\n chartInfo.chartparam.luckysheetCurrentChartMoveWinH = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollHeight;\r\n chartInfo.chartparam.luckysheetCurrentChartMoveWinW = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollWidth;\r\n\r\n if (\r\n !$(e.target).hasClass(\"luckysheet-mousedown-cancel\") &&\r\n $(e.target).filter(\"[class*='sp-palette']\").length == 0 &&\r\n $(e.target).filter(\"[class*='sp-thumb']\").length == 0 &&\r\n $(e.target).filter(\"[class*='sp-']\").length == 0\r\n ) {\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\"#luckysheet-cols-h-hover\").hide();\r\n $(\"#luckysheet-cols-menu-btn\").hide();\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\r\n \"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu, #luckysheet-user-menu\"\r\n ).hide();\r\n $(\r\n \"body > .luckysheet-filter-menu, body > .luckysheet-filter-submenu, body > .luckysheet-cols-menu\"\r\n ).hide();\r\n\r\n }\r\n\r\n e.stopPropagation();\r\n\r\n }\r\n\r\n }).find(\".luckysheet-modal-dialog-resize-item\")\r\n .mousedown(function (e) {\r\n if (chartInfo.chartparam.luckysheetCurrentChartActive) {\r\n chartInfo.chartparam.luckysheetCurrentChartResize = $(this).data(\"type\"); //开始状态resize\r\n\r\n var mouse = mouseposition(e.pageX, e.pageY),\r\n scrollLeft = $(\"#luckysheet-scrollbar-x\").scrollLeft(),\r\n scrollTop = $(\"#luckysheet-scrollbar-y\").scrollTop();\r\n var x = mouse[0] + scrollLeft;\r\n var y = mouse[1] + scrollTop;\r\n var position = chartInfo.chartparam.luckysheetCurrentChartResizeObj.position();\r\n //参数:x,y:鼠标位置,$t.width(), $t.height(): chart框宽高, position.left + scrollLeft, position.top + scrollTop :chart框位置 ,scrollLeft, scrollTop:滚动条位置\r\n chartInfo.chartparam.luckysheetCurrentChartResizeXy = [\r\n x,\r\n y,\r\n $t.width(),\r\n $t.height(),\r\n position.left + scrollLeft,\r\n position.top + scrollTop,\r\n scrollLeft,\r\n scrollTop\r\n ];\r\n chartInfo.chartparam.luckysheetCurrentChartResizeWinH = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollHeight;\r\n chartInfo.chartparam.luckysheetCurrentChartResizeWinW = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollWidth;\r\n\r\n chartInfo.chartparam.luckysheetCurrentChart = chart_id;\r\n\r\n e.stopPropagation();\r\n\r\n }\r\n })\r\n\r\n\r\n let width = chart.width\r\n let height = chart.height\r\n let left = chart.left\r\n let top = chart.top\r\n container.style.width = width + 'px'\r\n container.style.height = height + 'px'\r\n container.style.position = 'absolute'\r\n container.style.background = '#fff'\r\n container.style.left = left + 'px'\r\n container.style.top = top + 'px'\r\n container.style.zIndex = chartInfo.zIndex ? chartInfo.zIndex : 15\r\n chartInfo.zIndex++\r\n\r\n }\r\n}\r\n\r\nfunction jfrefreshchartall(flowdata1, r_st, r_ed, c_st, c_ed) {\r\n let chart = chartInfo.currentChart\r\n if (!chart) {\r\n return\r\n }\r\n if (chart.rangeArray.length == 1) {\r\n var row = chart.rangeArray[0].row;\r\n var column = chart.rangeArray[0].column;\r\n //不在范围内的不更新\r\n if (\r\n r_st > row[1] ||\r\n r_ed < row[0] ||\r\n c_st > column[1] ||\r\n c_ed < column[0]\r\n ) {\r\n return\r\n }\r\n //根据原有的范围取得数据\r\n var luckysheetgetcellrange = formula.getcellrange(\r\n chart.rangeTxt\r\n );\r\n var sheetIndex =\r\n luckysheetgetcellrange.sheetIndex == -1\r\n ? 0\r\n : luckysheetgetcellrange.sheetIndex; //sheetIndex为-1时,转化为0\r\n\r\n var selection = {\r\n row: luckysheetgetcellrange.row,\r\n column: luckysheetgetcellrange.column,\r\n dataSheetIndex: sheetIndex\r\n }; //数组\r\n var getcelldata = luckysheet_getcelldata(chart.rangeTxt);\r\n\r\n if (\r\n typeof getcelldata === \"object\" &&\r\n getcelldata.length != 0 &&\r\n getcelldata.data.length != null\r\n ) {\r\n //getcelldata有值,且不为空数组 && getcelldata.data为二维数组\r\n var chartData = getcelldata.data;\r\n chartInfo.chartparam.changeChartCellData(chart.chart_id, chartData);\r\n }\r\n }\r\n}\r\n\r\nfunction chart_selection() {\r\n return {\r\n create: function () {\r\n var chart_json = chartInfo.currentChart\r\n\r\n if (chart_json.rangeArray.length > 1) {\r\n return\r\n }\r\n\r\n $('#luckysheet-chart-rangeShow').empty()\r\n $('#luckysheet-cell-selected-boxs').hide()\r\n $('#luckysheet-cell-selected-focus').hide()\r\n $('#luckysheet-rows-h-selected').empty()\r\n $('#luckysheet-cols-h-selected').empty()\r\n $('#luckysheet-row-count-show').hide()\r\n $('#luckysheet-column-count-show').hide()\r\n\r\n var st_r = chart_json.rangeArray[0].row[0]\r\n var st_c = chart_json.rangeArray[0].column[0]\r\n\r\n var rangeSplitArray = chart_json.rangeSplitArray\r\n\r\n //首行是否标题\r\n var rangeRowCheck = chart_json.rangeRowCheck\r\n\r\n if (rangeRowCheck.exits) {\r\n var chart_rowtitle_html = getRangeShowHtml(\r\n 'rowtitle',\r\n rangeSplitArray.rowtitle.row[0] + st_r,\r\n rangeSplitArray.rowtitle.row[1] + st_r,\r\n rangeSplitArray.rowtitle.column[0] + st_c,\r\n rangeSplitArray.rowtitle.column[1] + st_c\r\n )\r\n } else {\r\n var chart_rowtitle_html = ''\r\n }\r\n\r\n //首列是否标题\r\n var rangeColCheck = chart_json.rangeColCheck\r\n\r\n if (rangeColCheck.exits) {\r\n var chart_coltitle_html = getRangeShowHtml(\r\n 'coltitle',\r\n rangeSplitArray.coltitle.row[0] + st_r,\r\n rangeSplitArray.coltitle.row[1] + st_r,\r\n rangeSplitArray.coltitle.column[0] + st_c,\r\n rangeSplitArray.coltitle.column[1] + st_c\r\n )\r\n } else {\r\n var chart_coltitle_html = ''\r\n }\r\n\r\n //内容块\r\n var chart_content_html = getRangeShowHtml(\r\n 'content',\r\n rangeSplitArray.content.row[0] + st_r,\r\n rangeSplitArray.content.row[1] + st_r,\r\n rangeSplitArray.content.column[0] + st_c,\r\n rangeSplitArray.content.column[1] + st_c\r\n )\r\n\r\n $('#luckysheet-chart-rangeShow').append(\r\n chart_rowtitle_html + chart_coltitle_html + chart_content_html\r\n )\r\n\r\n function getRangeShowHtml(type, r1, r2, c1, c2) {\r\n var visibledatarow = getvisibledatarow()\r\n var visibledatacolumn = getvisibledatacolumn()\r\n\r\n var row = visibledatarow[r2],\r\n row_pre = r1 - 1 == -1 ? 0 : visibledatarow[r1 - 1]\r\n var col = visibledatacolumn[c2],\r\n col_pre = c1 - 1 == -1 ? 0 : visibledatacolumn[c1 - 1]\r\n\r\n if (type == 'rowtitle') {\r\n var color = '#C65151'\r\n }\r\n\r\n if (type == 'coltitle') {\r\n var color = '#9667C0'\r\n }\r\n\r\n if (type == 'content') {\r\n var color = '#4970D1'\r\n }\r\n\r\n var html =\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
'\r\n\r\n return html\r\n }\r\n },\r\n rangeMove: false,\r\n rangeMovexy: null,\r\n rangeMoveIndex: null,\r\n rangeMoveObj: null,\r\n rangeMoveDraging: function (event, sheetBarHeight, statisticBarHeight) {\r\n var chart_json = chartInfo.currentChart\r\n var st_r = chart_json.rangeArray[0].row[0]\r\n var st_c = chart_json.rangeArray[0].column[0]\r\n var rangeRowCheck = chart_json.rangeRowCheck\r\n var rangeColCheck = chart_json.rangeColCheck\r\n var rangeSplitArray = chart_json.rangeSplitArray\r\n\r\n var mouse = mouseposition(event.pageX, event.pageY)\r\n var scrollLeft = $('#luckysheet-cell-main').scrollLeft()\r\n var scrollTop = $('#luckysheet-cell-main').scrollTop()\r\n\r\n var x = mouse[0] + scrollLeft\r\n var y = mouse[1] + scrollTop\r\n\r\n var winH =\r\n $(window).height() + scrollTop - sheetBarHeight - statisticBarHeight,\r\n winW = $(window).width() + scrollLeft\r\n\r\n var rowLocation = _rowLocation(y),\r\n row_index = rowLocation[2]\r\n var colLocation = _colLocation(x),\r\n col_index = colLocation[2]\r\n\r\n var visibledatarow = getvisibledatarow()\r\n var visibledatacolumn = getvisibledatacolumn()\r\n\r\n var $id = chartInfo.chart_selection.rangeMoveObj.attr('id')\r\n\r\n if ($id == 'luckysheet-chart-rangeShow-content') {\r\n //行\r\n var row_s =\r\n chartInfo.chart_selection.rangeMoveIndex[0] -\r\n chartInfo.chart_selection.rangeMovexy[0] +\r\n row_index\r\n\r\n if (rangeRowCheck.exits) {\r\n if (row_s < st_r + rangeRowCheck.range[1] + 1 || y < 0) {\r\n row_s = st_r + rangeRowCheck.range[1] + 1\r\n }\r\n } else {\r\n if (row_s < 0 || y < 0) {\r\n row_s = 0\r\n }\r\n }\r\n\r\n var row_e =\r\n rangeSplitArray.content.row[1] - rangeSplitArray.content.row[0] + row_s\r\n\r\n if (row_e >= visibledatarow.length - 1 || y > winH) {\r\n row_s =\r\n visibledatarow.length -\r\n 1 -\r\n rangeSplitArray.content.row[1] +\r\n rangeSplitArray.content.row[0]\r\n row_e = visibledatarow.length - 1\r\n }\r\n\r\n //列\r\n var col_s =\r\n chartInfo.chart_selection.rangeMoveIndex[1] -\r\n chartInfo.chart_selection.rangeMovexy[1] +\r\n col_index\r\n if (rangeColCheck.exits) {\r\n if (col_s < st_c + rangeColCheck.range[1] + 1 || x < 0) {\r\n col_s = st_c + rangeColCheck.range[1] + 1\r\n }\r\n } else {\r\n if (col_s < 0 || x < 0) {\r\n col_s = 0\r\n }\r\n }\r\n\r\n var col_e =\r\n rangeSplitArray.content.column[1] -\r\n rangeSplitArray.content.column[0] +\r\n col_s\r\n\r\n if (col_e >= visibledatacolumn.length - 1 || x > winW) {\r\n col_s =\r\n visibledatacolumn.length -\r\n 1 -\r\n rangeSplitArray.content.column[1] +\r\n rangeSplitArray.content.column[0]\r\n col_e = visibledatacolumn.length - 1\r\n }\r\n\r\n //更新\r\n if (rangeRowCheck.exits && rangeColCheck.exits) {\r\n chart_json.rangeArray = [{ row: [st_r, row_e], column: [st_c, col_e] }]\r\n chart_json.rangeSplitArray.range = {\r\n row: [st_r, row_e],\r\n column: [st_c, col_e]\r\n }\r\n\r\n chart_json.rangeSplitArray.content = {\r\n row: [row_s - st_r, row_e - st_r],\r\n column: [col_s - st_c, col_e - st_c]\r\n }\r\n\r\n chart_json.rangeSplitArray.rowtitle = {\r\n row: chart_json.rangeSplitArray.rowtitle.row,\r\n column: [col_s - st_c, col_e - st_c]\r\n }\r\n\r\n chart_json.rangeSplitArray.coltitle = {\r\n row: [row_s - st_r, row_e - st_r],\r\n column: chart_json.rangeSplitArray.coltitle.column\r\n }\r\n } else if (rangeRowCheck.exits) {\r\n chart_json.rangeArray = [{ row: [st_r, row_e], column: [col_s, col_e] }]\r\n chart_json.rangeSplitArray.range = {\r\n row: [st_r, row_e],\r\n column: [col_s, col_e]\r\n }\r\n\r\n chart_json.rangeSplitArray.content = {\r\n row: [row_s - st_r, row_e - st_r],\r\n column: chart_json.rangeSplitArray.content.column\r\n }\r\n } else if (rangeColCheck.exits) {\r\n chart_json.rangeArray = [{ row: [row_s, row_e], column: [st_c, col_e] }]\r\n chart_json.rangeSplitArray.range = {\r\n row: [row_s, row_e],\r\n column: [st_c, col_e]\r\n }\r\n\r\n chart_json.rangeSplitArray.content = {\r\n row: chart_json.rangeSplitArray.content.row,\r\n column: [col_s - st_c, col_e - st_c]\r\n }\r\n } else {\r\n chart_json.rangeArray = [\r\n { row: [row_s, row_e], column: [col_s, col_e] }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: [row_s, row_e],\r\n column: [col_s, col_e]\r\n }\r\n }\r\n } else if ($id == 'luckysheet-chart-rangeShow-rowtitle') {\r\n //列\r\n var col_s =\r\n chartInfo.chart_selection.rangeMoveIndex[1] -\r\n chartInfo.chart_selection.rangeMovexy[1] +\r\n col_index\r\n\r\n if (rangeColCheck.exits) {\r\n if (col_s < st_c + rangeColCheck.range[1] + 1 || x < 0) {\r\n col_s = st_c + rangeColCheck.range[1] + 1\r\n }\r\n } else {\r\n if (col_s < 0 || x < 0) {\r\n col_s = 0\r\n }\r\n }\r\n\r\n var col_e =\r\n rangeSplitArray.rowtitle.column[1] -\r\n rangeSplitArray.rowtitle.column[0] +\r\n col_s\r\n\r\n if (col_e >= visibledatacolumn.length - 1 || x > winW) {\r\n col_s =\r\n visibledatacolumn.length -\r\n 1 -\r\n rangeSplitArray.rowtitle.column[1] +\r\n rangeSplitArray.rowtitle.column[0]\r\n col_e = visibledatacolumn.length - 1\r\n }\r\n\r\n //更新\r\n if (rangeColCheck.exits) {\r\n chart_json.rangeArray = [\r\n { row: chart_json.rangeArray[0].row, column: [st_c, col_e] }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: chart_json.rangeArray[0].row,\r\n column: [st_c, col_e]\r\n }\r\n\r\n chart_json.rangeSplitArray.rowtitle = {\r\n row: chart_json.rangeSplitArray.rowtitle.row,\r\n column: [col_s - st_c, col_e - st_c]\r\n }\r\n chart_json.rangeSplitArray.content = {\r\n row: chart_json.rangeSplitArray.content.row,\r\n column: [col_s - st_c, col_e - st_c]\r\n }\r\n } else {\r\n chart_json.rangeArray = [\r\n { row: chart_json.rangeArray[0].row, column: [col_s, col_e] }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: chart_json.rangeArray[0].row,\r\n column: [col_s, col_e]\r\n }\r\n }\r\n } else if ($id == 'luckysheet-chart-rangeShow-coltitle') {\r\n //行\r\n var row_s =\r\n chartInfo.chart_selection.rangeMoveIndex[0] -\r\n chartInfo.chart_selection.rangeMovexy[0] +\r\n row_index\r\n if (rangeRowCheck.exits) {\r\n if (row_s < st_r + rangeRowCheck.range[1] + 1 || y < 0) {\r\n row_s = st_r + rangeRowCheck.range[1] + 1\r\n }\r\n } else {\r\n if (row_s < 0 || y < 0) {\r\n row_s = 0\r\n }\r\n }\r\n\r\n //更新\r\n var row_e =\r\n rangeSplitArray.coltitle.row[1] -\r\n rangeSplitArray.coltitle.row[0] +\r\n row_s\r\n\r\n if (row_e >= visibledatarow.length - 1 || y > winH) {\r\n row_s =\r\n visibledatarow.length -\r\n 1 -\r\n rangeSplitArray.coltitle.row[1] +\r\n rangeSplitArray.coltitle.row[0]\r\n row_e = visibledatarow.length - 1\r\n }\r\n\r\n if (rangeRowCheck.exits) {\r\n chart_json.rangeArray = [\r\n { row: [st_r, row_e], column: chart_json.rangeArray[0].column }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: [st_r, row_e],\r\n column: chart_json.rangeArray[0].column\r\n }\r\n\r\n chart_json.rangeSplitArray.coltitle = {\r\n row: [row_s - st_r, row_e - st_r],\r\n column: chart_json.rangeSplitArray.coltitle.column\r\n }\r\n chart_json.rangeSplitArray.content = {\r\n row: [row_s - st_r, row_e - st_r],\r\n column: chart_json.rangeSplitArray.content.column\r\n }\r\n } else {\r\n chart_json.rangeArray = [\r\n { row: [row_s, row_e], column: chart_json.rangeArray[0].column }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: [row_s, row_e],\r\n column: chart_json.rangeArray[0].column\r\n }\r\n }\r\n }\r\n\r\n chartInfo.chart_selection.create()\r\n },\r\n rangeMoveDragged: function () {\r\n chartInfo.chart_selection.rangeMove = false\r\n\r\n var updateJson = chartInfo.currentChart\r\n\r\n updateJson.rangeTxt = getRangetxt(\r\n chartInfo.currentSheetIndex,\r\n updateJson.rangeArray[0],\r\n chartInfo.currentSheetIndex\r\n )\r\n updateJson.chartData = getdatabyselection(\r\n updateJson.rangeArray[0],\r\n chartInfo.currentSheetIndex\r\n )\r\n // 渲染\r\n chartInfo.changeChartRange(updateJson.chart_id, updateJson.chartData, updateJson.rangeArray, updateJson.rangeTxt)\r\n },\r\n rangeResize: false,\r\n rangeResizexy: null,\r\n rangeResizeIndex: null,\r\n rangeResizeObj: null,\r\n rangeResizeDraging: function (event, sheetBarHeight, statisticBarHeight) {\r\n var chart_json = chartInfo.currentChart\r\n\r\n var st_r = chart_json.rangeArray[0].row[0]\r\n var st_c = chart_json.rangeArray[0].column[0]\r\n var rangeRowCheck = chart_json.rangeRowCheck\r\n var rangeColCheck = chart_json.rangeColCheck\r\n var rangeSplitArray = chart_json.rangeSplitArray\r\n\r\n var mouse = mouseposition(event.pageX, event.pageY)\r\n var scrollLeft = $('#luckysheet-cell-main').scrollLeft()\r\n var scrollTop = $('#luckysheet-cell-main').scrollTop()\r\n\r\n var x = mouse[0] + scrollLeft\r\n var y = mouse[1] + scrollTop\r\n\r\n var winH =\r\n $(window).height() + scrollTop - sheetBarHeight - statisticBarHeight,\r\n winW = $(window).width() + scrollLeft\r\n\r\n var rowLocation = _rowLocation(y),\r\n row_index = rowLocation[2]\r\n var colLocation = _colLocation(x),\r\n col_index = colLocation[2]\r\n\r\n var visibledatarow = getvisibledatarow()\r\n var visibledatacolumn = getvisibledatacolumn()\r\n\r\n var $id = chartInfo.chart_selection.rangeResizeObj.attr('id')\r\n\r\n if ($id == 'luckysheet-chart-rangeShow-content') {\r\n var r1, r2, c1, c2\r\n\r\n if (chartInfo.chart_selection.rangeResize == 'lt') {\r\n r1 = chartInfo.chart_selection.rangeResizeIndex.row[0]\r\n c1 = chartInfo.chart_selection.rangeResizeIndex.column[0]\r\n\r\n r2 = chartInfo.chart_selection.rangeResizeIndex.row[1]\r\n c2 = chartInfo.chart_selection.rangeResizeIndex.column[1]\r\n } else if (chartInfo.chart_selection.rangeResize == 'lb') {\r\n r1 = chartInfo.chart_selection.rangeResizeIndex.row[1]\r\n c1 = chartInfo.chart_selection.rangeResizeIndex.column[0]\r\n\r\n r2 = chartInfo.chart_selection.rangeResizeIndex.row[0]\r\n c2 = chartInfo.chart_selection.rangeResizeIndex.column[1]\r\n } else if (chartInfo.chart_selection.rangeResize == 'rt') {\r\n r1 = chartInfo.chart_selection.rangeResizeIndex.row[0]\r\n c1 = chartInfo.chart_selection.rangeResizeIndex.column[1]\r\n\r\n r2 = chartInfo.chart_selection.rangeResizeIndex.row[1]\r\n c2 = chartInfo.chart_selection.rangeResizeIndex.column[0]\r\n } else if (chartInfo.chart_selection.rangeResize == 'rb') {\r\n r1 = chartInfo.chart_selection.rangeResizeIndex.row[1]\r\n c1 = chartInfo.chart_selection.rangeResizeIndex.column[1]\r\n\r\n r2 = chartInfo.chart_selection.rangeResizeIndex.row[0]\r\n c2 = chartInfo.chart_selection.rangeResizeIndex.column[0]\r\n }\r\n\r\n //行\r\n if (rangeRowCheck.exits) {\r\n var row_s = r1 - chartInfo.chart_selection.rangeResizexy[0] + row_index\r\n\r\n if (row_s < st_r + rangeRowCheck.range[1] + 1 || y < 0) {\r\n row_s = st_r + rangeRowCheck.range[1] + 1\r\n } else if (row_s >= visibledatarow.length - 1 || y > winH) {\r\n row_s = visibledatarow.length - 1\r\n }\r\n } else {\r\n var row_s = st_r - chartInfo.chart_selection.rangeResizexy[0] + row_index\r\n\r\n if (row_s < 0 || y < 0) {\r\n row_s = 0\r\n } else if (row_s >= visibledatarow.length - 1 || y > winH) {\r\n row_s = visibledatarow.length - 1\r\n }\r\n }\r\n\r\n //列\r\n if (rangeColCheck.exits) {\r\n var col_s = c1 - chartInfo.chart_selection.rangeResizexy[1] + col_index\r\n\r\n if (col_s < st_c + rangeColCheck.range[1] + 1 || x < 0) {\r\n col_s = st_c + rangeColCheck.range[1] + 1\r\n } else if (col_s >= visibledatacolumn.length - 1 || x > winW) {\r\n col_s = visibledatacolumn.length - 1\r\n }\r\n } else {\r\n var col_s = st_c - chartInfo.chart_selection.rangeResizexy[1] + col_index\r\n\r\n if (col_s < 0 || x < 0) {\r\n col_s = 0\r\n } else if (col_s >= visibledatacolumn.length - 1 || x > winW) {\r\n col_s = visibledatacolumn.length - 1\r\n }\r\n }\r\n\r\n var obj_r1, obj_r2, obj_c1, obj_c2\r\n\r\n if (row_s > r2) {\r\n obj_r1 = r2\r\n obj_r2 = row_s\r\n } else {\r\n obj_r1 = row_s\r\n obj_r2 = r2\r\n }\r\n\r\n if (col_s > c2) {\r\n obj_c1 = c2\r\n obj_c2 = col_s\r\n } else {\r\n obj_c1 = col_s\r\n obj_c2 = c2\r\n }\r\n\r\n if (!rangeRowCheck.exits && !rangeColCheck.exits) {\r\n chart_json.rangeArray = [\r\n { row: [obj_r1, obj_r2], column: [obj_c1, obj_c2] }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: [obj_r1, obj_r2],\r\n column: [obj_c1, obj_c2]\r\n }\r\n } else {\r\n chart_json.rangeArray = [\r\n { row: [st_r, obj_r2], column: [st_c, obj_c2] }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: [st_r, obj_r2],\r\n column: [st_c, obj_c2]\r\n }\r\n\r\n chart_json.rangeSplitArray.content = {\r\n row: [obj_r1 - st_r, obj_r2 - st_r],\r\n column: [obj_c1 - st_c, obj_c2 - st_c]\r\n }\r\n\r\n if (rangeRowCheck.exits) {\r\n chart_json.rangeSplitArray.rowtitle = {\r\n row: chart_json.rangeSplitArray.rowtitle.row,\r\n column: [obj_c1 - st_c, obj_c2 - st_c]\r\n }\r\n }\r\n\r\n if (rangeColCheck.exits) {\r\n chart_json.rangeSplitArray.coltitle = {\r\n row: [obj_r1 - st_r, obj_r2 - st_r],\r\n column: chart_json.rangeSplitArray.coltitle.column\r\n }\r\n }\r\n }\r\n } else if ($id == 'luckysheet-chart-rangeShow-rowtitle') {\r\n var c1, c2\r\n\r\n if (\r\n chartInfo.chart_selection.rangeResize == 'lt' ||\r\n chartInfo.chart_selection.rangeResize == 'lb'\r\n ) {\r\n c1 = chartInfo.chart_selection.rangeResizeIndex.column[0]\r\n c2 = chartInfo.chart_selection.rangeResizeIndex.column[1]\r\n } else if (\r\n chartInfo.chart_selection.rangeResize == 'rt' ||\r\n chartInfo.chart_selection.rangeResize == 'rb'\r\n ) {\r\n c1 = chartInfo.chart_selection.rangeResizeIndex.column[1]\r\n c2 = chartInfo.chart_selection.rangeResizeIndex.column[0]\r\n }\r\n\r\n //列\r\n if (rangeColCheck.exits) {\r\n var col_s = c1 - chartInfo.chart_selection.rangeResizexy[1] + col_index\r\n\r\n if (col_s < st_c + rangeColCheck.range[1] + 1 || x < 0) {\r\n col_s = st_c + rangeColCheck.range[1] + 1\r\n } else if (col_s >= visibledatacolumn.length - 1 || x > winW) {\r\n col_s = visibledatacolumn.length - 1\r\n }\r\n } else {\r\n var col_s = st_c - chartInfo.chart_selection.rangeResizexy[1] + col_index\r\n\r\n if (col_s < 0 || x < 0) {\r\n col_s = 0\r\n } else if (col_s >= visibledatacolumn.length - 1 || x > winW) {\r\n col_s = visibledatacolumn.length - 1\r\n }\r\n }\r\n\r\n var obj_c1, obj_c2\r\n\r\n if (col_s > c2) {\r\n obj_c1 = c2\r\n obj_c2 = col_s\r\n } else {\r\n obj_c1 = col_s\r\n obj_c2 = c2\r\n }\r\n\r\n //更新\r\n if (!rangeColCheck.exits) {\r\n chart_json.rangeArray = [\r\n { row: chart_json.rangeArray[0].row, column: [obj_c1, obj_c2] }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: chart_json.rangeArray[0].row,\r\n column: [obj_c1, obj_c2]\r\n }\r\n } else {\r\n chart_json.rangeArray = [\r\n { row: chart_json.rangeArray[0].row, column: [st_c, obj_c2] }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: chart_json.rangeArray[0].row,\r\n column: [st_c, obj_c2]\r\n }\r\n\r\n chart_json.rangeSplitArray.rowtitle = {\r\n row: chart_json.rangeSplitArray.rowtitle.row,\r\n column: [obj_c1 - st_c, obj_c2 - st_c]\r\n }\r\n chart_json.rangeSplitArray.content = {\r\n row: chart_json.rangeSplitArray.content.row,\r\n column: [obj_c1 - st_c, obj_c2 - st_c]\r\n }\r\n }\r\n } else if ($id == 'luckysheet-chart-rangeShow-coltitle') {\r\n var r1, r2\r\n\r\n if (\r\n chartInfo.chart_selection.rangeResize == 'lt' ||\r\n chartInfo.chart_selection.rangeResize == 'rt'\r\n ) {\r\n r1 = chartInfo.chart_selection.rangeResizeIndex.row[0]\r\n r2 = chartInfo.chart_selection.rangeResizeIndex.row[1]\r\n } else if (\r\n chartInfo.chart_selection.rangeResize == 'lb' ||\r\n chartInfo.chart_selection.rangeResize == 'rb'\r\n ) {\r\n r1 = chartInfo.chart_selection.rangeResizeIndex.row[1]\r\n r2 = chartInfo.chart_selection.rangeResizeIndex.row[0]\r\n }\r\n\r\n //行\r\n if (rangeRowCheck.exits) {\r\n var row_s = r1 - chartInfo.chart_selection.rangeResizexy[0] + row_index\r\n\r\n if (row_s < st_r + rangeRowCheck.range[1] + 1 || y < 0) {\r\n row_s = st_r + rangeRowCheck.range[1] + 1\r\n } else if (row_s >= visibledatarow.length - 1 || y > winH) {\r\n row_s = visibledatarow.length - 1\r\n }\r\n } else {\r\n var row_s = st_r - chartInfo.chart_selection.rangeResizexy[0] + row_index\r\n\r\n if (row_s < 0 || y < 0) {\r\n row_s = 0\r\n } else if (row_s >= visibledatarow.length - 1 || y > winH) {\r\n row_s = visibledatarow.length - 1\r\n }\r\n }\r\n\r\n var obj_r1, obj_r2\r\n\r\n if (row_s > r2) {\r\n obj_r1 = r2\r\n obj_r2 = row_s\r\n } else {\r\n obj_r1 = row_s\r\n obj_r2 = r2\r\n }\r\n\r\n //更新\r\n if (!rangeRowCheck.exits) {\r\n chart_json.rangeArray = [\r\n { row: [obj_r1, obj_r2], column: chart_json.rangeArray[0].column }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: [obj_r1, obj_r2],\r\n column: chart_json.rangeArray[0].column\r\n }\r\n } else {\r\n chart_json.rangeArray = [\r\n { row: [st_r, obj_r2], column: chart_json.rangeArray[0].column }\r\n ]\r\n chart_json.rangeSplitArray.range = {\r\n row: [st_r, obj_r2],\r\n column: chart_json.rangeArray[0].column\r\n }\r\n\r\n chart_json.rangeSplitArray.coltitle = {\r\n row: [obj_r1 - st_r, obj_r2 - st_r],\r\n column: chart_json.rangeSplitArray.coltitle.column\r\n }\r\n chart_json.rangeSplitArray.content = {\r\n row: [obj_r1 - st_r, obj_r2 - st_r],\r\n column: chart_json.rangeSplitArray.content.column\r\n }\r\n }\r\n }\r\n\r\n chartInfo.chart_selection.create()\r\n },\r\n rangeResizeDragged: function () {\r\n chartInfo.chart_selection.rangeResize = null\r\n var updateJson = chartInfo.currentChart\r\n\r\n updateJson.rangeTxt = getRangetxt(\r\n chartInfo.currentSheetIndex,\r\n updateJson.rangeArray[0],\r\n chartInfo.currentSheetIndex\r\n )\r\n updateJson.chartData = getdatabyselection(\r\n updateJson.rangeArray[0],\r\n chartInfo.currentSheetIndex\r\n )\r\n // 渲染\r\n chartInfo.changeChartRange(updateJson.chart_id, updateJson.chartData, updateJson.rangeArray, updateJson.rangeTxt)\r\n\r\n }\r\n }\r\n}\r\n\r\n// create chart\r\nfunction createLuckyChart(width, height, left, top) {\r\n //如果只选中一个单元格,则自动填充选取\r\n var jfgird_select_save = luckysheet.getluckysheet_select_save();\r\n if (\r\n jfgird_select_save.length == 1 &&\r\n jfgird_select_save[0].row[0] == jfgird_select_save[0].row[1] &&\r\n jfgird_select_save[0].column[0] == jfgird_select_save[0].column[1]\r\n ) {\r\n luckysheetMoveHighlightRange2(\"right\", \"rangeOfSelect\");\r\n\r\n luckysheetMoveHighlightRange2(\"down\", \"rangeOfSelect\");\r\n\r\n jfgird_select_save = luckysheet.getluckysheet_select_save();\r\n }\r\n //处理右边的空白单元格,自动略过并修改选区 ---------------start\r\n var shiftpositon_row = -1;\r\n\r\n var row_ed =\r\n jfgird_select_save[0][\"row\"][1] - jfgird_select_save[0][\"row\"][0];\r\n for (\r\n var r = jfgird_select_save[0][\"row\"][0];\r\n r <= jfgird_select_save[0][\"row\"][1];\r\n r++\r\n ) {\r\n for (\r\n var c = jfgird_select_save[0][\"column\"][0];\r\n c <= jfgird_select_save[0][\"column\"][1];\r\n c++\r\n ) {\r\n var value = getcellvalue(r, c, luckysheet.flowdata());\r\n //console.log(\"value,r,c\",value,r,c);\r\n if (value != null && value.toString().length > 0) {\r\n shiftpositon_row = r;\r\n break;\r\n }\r\n }\r\n\r\n if (shiftpositon_row !== -1) {\r\n break;\r\n }\r\n }\r\n\r\n if (shiftpositon_row == -1) {\r\n shiftpositon_row = 0;\r\n }\r\n\r\n jfgird_select_save[0][\"row\"] = [shiftpositon_row, shiftpositon_row];\r\n luckysheet.setluckysheet_select_save(jfgird_select_save);\r\n\r\n chartInfo.luckysheet_shiftpositon = $.extend(true, {}, jfgird_select_save[0]);\r\n luckysheetMoveEndCell(\"down\", \"range\", false, row_ed);\r\n jfgird_select_save = luckysheet.getluckysheet_select_save();\r\n\r\n var shiftpositon_col = -1;\r\n var column_ed =\r\n jfgird_select_save[0][\"column\"][1] - jfgird_select_save[0][\"column\"][0];\r\n for (\r\n var c = jfgird_select_save[0][\"column\"][0];\r\n c <= jfgird_select_save[0][\"column\"][1];\r\n c++\r\n ) {\r\n for (\r\n var r = jfgird_select_save[0][\"row\"][0];\r\n r <= jfgird_select_save[0][\"row\"][1];\r\n r++\r\n ) {\r\n var value = getcellvalue(r, c, luckysheet.flowdata());\r\n if (value != null && value.toString().length > 0) {\r\n shiftpositon_col = c;\r\n break;\r\n }\r\n }\r\n\r\n if (shiftpositon_col !== -1) {\r\n break;\r\n }\r\n }\r\n\r\n if (shiftpositon_col == -1) {\r\n shiftpositon_col = 0;\r\n }\r\n\r\n jfgird_select_save[0][\"column\"] = [shiftpositon_col, shiftpositon_col];\r\n luckysheet.setluckysheet_select_save(jfgird_select_save);\r\n\r\n chartInfo.luckysheet_shiftpositon = $.extend(true, {}, jfgird_select_save[0]);\r\n luckysheetMoveEndCell(\"right\", \"range\", false, column_ed);\r\n jfgird_select_save = luckysheet.getluckysheet_select_save()\r\n\r\n var rangeArray = $.extend(true, [], jfgird_select_save);\r\n\r\n var rangeTxt = getRangetxt(chartInfo.currentSheetIndex, rangeArray[0], chartInfo.currentSheetIndex)\r\n\r\n\r\n let chartData = getdatabyselection()\r\n console.dir(chartData)\r\n\r\n let chart_id = generateRandomKey('chart')\r\n\r\n let chart_id_c = chart_id + '_c'\r\n\r\n let modelChartShowHTML =\r\n '
${content}
'\r\n\r\n let $t = $(\r\n replaceHtml(modelChartShowHTML, {\r\n id: chart_id_c,\r\n addclass: 'luckysheet-data-visualization-chart',\r\n title: '图表生成',\r\n content: ''\r\n })\r\n ).appendTo($('.luckysheet-cell-main'))\r\n\r\n let container = document.getElementById(chart_id_c)\r\n\r\n let { render, chart_json } = chartInfo.createChart($(`#${chart_id_c}`).children('.luckysheet-modal-dialog-content')[0], chartData, chart_id, rangeArray, rangeTxt)\r\n // chartInfo.currentChart = chart_json.chartOptions\r\n console.dir(JSON.stringify(chart_json))\r\n\r\n width = width ? width : 400\r\n height = height ? height : 250\r\n left = left ? left : 0\r\n top = top ? top : 0\r\n container.style.width = width + 'px'\r\n container.style.height = height + 'px'\r\n container.style.position = 'absolute'\r\n container.style.background = '#fff'\r\n container.style.left = left + 'px'\r\n container.style.top = top + 'px'\r\n render.style.width = '100%'\r\n render.style.height = '100%'\r\n container.style.zIndex = chartInfo.zIndex ? chartInfo.zIndex : 15\r\n chartInfo.zIndex++\r\n\r\n // insert chartinfo\r\n let sheetFile = chartInfo.luckysheetfile[getSheetIndex(chartInfo.currentSheetIndex)];\r\n\r\n if (!sheetFile.chart) {\r\n sheetFile.chart = [];\r\n }\r\n sheetFile.chart.push({\r\n chart_id,\r\n width,\r\n height,\r\n left,\r\n top,\r\n sheetIndex: sheetFile.index\r\n })\r\n\r\n //处理区域高亮框参数,当前页中,只有当前的图表的needRangShow为true,其他为false\r\n showNeedRangeShow(chart_id);\r\n\r\n // delete current chart\r\n $(`#${chart_id}_c .luckysheet-modal-controll-del`).click(function (e) {\r\n delChart(chart_id)\r\n })\r\n\r\n setChartMoveableEffect($t);\r\n\r\n // edit current chart\r\n $(`#${chart_id}_c .luckysheet-modal-controll-update`).click(function (e) {\r\n showChartSettingComponent()\r\n })\r\n\r\n $t.children('.luckysheet-modal-dialog-content').mousedown(function (e) {\r\n if (!chartInfo.chartparam.luckysheetCurrentChartMaxState) {\r\n //当前图表显示区域高亮\r\n showNeedRangeShow(chart_id);\r\n }\r\n e.stopPropagation()\r\n })\r\n $t.mousedown(function (e) { //move chart\r\n\r\n if (!chartInfo.chartparam.luckysheetCurrentChartMaxState) {\r\n //当前图表显示区域高亮\r\n showNeedRangeShow(chart_id);\r\n setluckysheet_scroll_status(true);\r\n\r\n //允许拖动渲染框\r\n if (\r\n !$(e.target).is(\".luckysheet-modal-dialog-controll\") &&\r\n !$(e.target).is(\".luckysheet-modal-controll-btn\") &&\r\n !$(e.target).is(\"i\")\r\n ) {\r\n // Debounce\r\n chartInfo.chartparam.luckysheetCurrentChartMoveTimeout = setTimeout(\r\n function () {\r\n chartInfo.chartparam.luckysheetCurrentChartMove = true;\r\n },\r\n 100\r\n );\r\n }\r\n\r\n var toffset = chartInfo.chartparam.luckysheetCurrentChartMoveObj.offset();\r\n var tpsition = chartInfo.chartparam.luckysheetCurrentChartMoveObj.position();\r\n //luckysheetCurrentChartMoveXy: [鼠标点相对chart框的距离X方向,鼠标点相对chart框的距离Y方向,chart框相对cell-main的距离X方向,chart框相对cell-main的距离Y方向,水平滚动条的位置,垂直滚动条的位置]\r\n chartInfo.chartparam.luckysheetCurrentChartMoveXy = [\r\n e.pageX - toffset.left,\r\n e.pageY - toffset.top,\r\n tpsition.left,\r\n tpsition.top,\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(),\r\n $(\"#luckysheet-scrollbar-y\").scrollTop()\r\n ];\r\n chartInfo.chartparam.luckysheetCurrentChartMoveWinH = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollHeight;\r\n chartInfo.chartparam.luckysheetCurrentChartMoveWinW = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollWidth;\r\n\r\n if (\r\n !$(e.target).hasClass(\"luckysheet-mousedown-cancel\") &&\r\n $(e.target).filter(\"[class*='sp-palette']\").length == 0 &&\r\n $(e.target).filter(\"[class*='sp-thumb']\").length == 0 &&\r\n $(e.target).filter(\"[class*='sp-']\").length == 0\r\n ) {\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\"#luckysheet-cols-h-hover\").hide();\r\n $(\"#luckysheet-cols-menu-btn\").hide();\r\n $(\"#luckysheet-rightclick-menu\").hide();\r\n $(\r\n \"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu, #luckysheet-user-menu\"\r\n ).hide();\r\n $(\r\n \"body > .luckysheet-filter-menu, body > .luckysheet-filter-submenu, body > .luckysheet-cols-menu\"\r\n ).hide();\r\n\r\n }\r\n\r\n e.stopPropagation();\r\n\r\n }\r\n\r\n }).find(\".luckysheet-modal-dialog-resize-item\")\r\n .mousedown(function (e) {\r\n if (chartInfo.chartparam.luckysheetCurrentChartActive) {\r\n chartInfo.chartparam.luckysheetCurrentChartResize = $(this).data(\"type\"); //开始状态resize\r\n\r\n var mouse = mouseposition(e.pageX, e.pageY),\r\n scrollLeft = $(\"#luckysheet-scrollbar-x\").scrollLeft(),\r\n scrollTop = $(\"#luckysheet-scrollbar-y\").scrollTop();\r\n var x = mouse[0] + scrollLeft;\r\n var y = mouse[1] + scrollTop;\r\n var position = chartInfo.chartparam.luckysheetCurrentChartResizeObj.position();\r\n //参数:x,y:鼠标位置,$t.width(), $t.height(): chart框宽高, position.left + scrollLeft, position.top + scrollTop :chart框位置 ,scrollLeft, scrollTop:滚动条位置\r\n chartInfo.chartparam.luckysheetCurrentChartResizeXy = [\r\n x,\r\n y,\r\n $t.width(),\r\n $t.height(),\r\n position.left + scrollLeft,\r\n position.top + scrollTop,\r\n scrollLeft,\r\n scrollTop\r\n ];\r\n chartInfo.chartparam.luckysheetCurrentChartResizeWinH = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollHeight;\r\n chartInfo.chartparam.luckysheetCurrentChartResizeWinW = $(\r\n \"#luckysheet-cell-main\"\r\n )[0].scrollWidth;\r\n\r\n chartInfo.chartparam.luckysheetCurrentChart = chart_id;\r\n\r\n e.stopPropagation();\r\n\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 设置图表可拖动区域高亮效果,鼠标经过可拖动区域时鼠标显示“十字”,不可拖动区域显示箭头\r\n * @param {JQuery} $container 图表的容器DIV\r\n */\r\nfunction setChartMoveableEffect($container) {\r\n $container.find('.luckysheet-modal-dialog-content').hover(function () {\r\n $container.removeClass(\"chart-moveable\");\r\n }, function () {\r\n $container.addClass(\"chart-moveable\");\r\n });\r\n\r\n $container.hover(function () {\r\n $container.addClass(\"chart-moveable\");\r\n }, function () {\r\n $container.removeClass(\"chart-moveable\");\r\n });\r\n}\r\n\r\n// delete chart\r\nfunction delChart(chart_id) {\r\n // delete container\r\n $(`.luckysheet-cell-main #${chart_id}_c`).remove()\r\n\r\n // Hide selected range\r\n hideAllNeedRangeShow()\r\n\r\n // delete storage\r\n let sheetFile = chartInfo.luckysheetfile[getSheetIndex(chartInfo.currentSheetIndex)]\r\n let index = sheetFile.chart.findIndex(item => item.chart_id == chart_id)\r\n sheetFile.chart.splice(index, 1)\r\n // api call\r\n chartInfo.deleteChart(chart_id)\r\n}\r\n\r\n//设置某个图表的高亮区域状态为显示,处理当前页的所有图表,只取一个图表设置为显示,其他隐藏,其他页不管\r\nfunction showNeedRangeShow(chart_id) {\r\n\r\n let chartLists = chartInfo.luckysheetfile[getSheetIndex(chartInfo.currentSheetIndex)].chart;\r\n\r\n for (let chartId in chartLists) {\r\n // if (chartLists[chartId].sheetIndex == chartInfo.currentSheetIndex) {\r\n //当前sheet的图表先设置为false\r\n chartLists[chartId].needRangeShow = false\r\n if (chartLists[chartId].chart_id == chart_id) {\r\n chartLists[chartId].needRangeShow = true;\r\n\r\n chartInfo.currentChart = chartInfo.getChartJson(chart_id)\r\n }\r\n // }\r\n\r\n }\r\n\r\n //操作DOM当前图表选择区域高亮\r\n selectRangeBorderShow(chart_id)\r\n}\r\n//隐藏当前sheet所有的图表高亮区域\r\nfunction hideAllNeedRangeShow() {\r\n let chartLists = chartInfo.luckysheetfile[getSheetIndex(chartInfo.currentSheetIndex)].chart;\r\n for (let chartId in chartLists) {\r\n // if (chartLists[chartId].sheetIndex == chartInfo.currentSheetIndex) {\r\n //当前sheet的图表设置为false\r\n chartLists[chartId].needRangeShow = false\r\n // }\r\n\r\n }\r\n\r\n //操作DOM 当前图表选择区域隐藏\r\n selectRangeBorderHide()\r\n}\r\n\r\n//选择区域高亮\r\nfunction selectRangeBorderShow(chart_id) {\r\n\r\n let $t = $('#' + chart_id + '_c')\r\n\r\n // Highlight of data range\r\n chartInfo.chart_selection.create()\r\n\r\n chartInfo.chartparam.luckysheetCurrentChartActive = true\r\n chartInfo.chartparam.luckysheetCurrentChartMoveObj = $t\r\n chartInfo.chartparam.luckysheetCurrentChartResizeObj = $t\r\n chartInfo.chartparam.luckysheetCurrentChart = chart_id\r\n\r\n //luckysheet取cell-main,后续扩展到其他的用户自定义元素\r\n $('#luckysheet-cell-main')\r\n .find('.luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize')\r\n .hide()\r\n $('#luckysheet-cell-main')\r\n .find('.luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll')\r\n .hide()\r\n\r\n $t.css('z-index', chartInfo.chartparam.luckysheetCurrentChartZIndexRank++)\r\n $t.find('.luckysheet-modal-dialog-resize').show()\r\n $t.find('.luckysheet-modal-dialog-controll').show()\r\n\r\n if (\r\n ($('.chartSetting').is(':visible') || chartInfo.chartparam.luckysheet_chart_redo_click) &&\r\n chart_id != chartInfo.chartparam.luckysheetCurrentChart\r\n ) {\r\n // TODO: 第一次创建图表时候需要初始化数据选择框 qkSelection\r\n // generator.ini(chartMixConfig)\r\n $('body .luckysheet-cols-menu').hide()\r\n }\r\n\r\n // 切换到当前图表设置项\r\n chartInfo.currentChart = chartInfo.highlightChart(chart_id)\r\n}\r\n\r\n//选择区域高亮隐藏\r\nfunction selectRangeBorderHide(settingShow) {\r\n\r\n $('#luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll').hide()\r\n $('#luckysheet-cell-main').find('.luckysheet-datavisual-selection-set div').remove()\r\n chartInfo.chartparam.luckysheetCurrentChartActive = false\r\n\r\n $('#luckysheet-chart-rangeShow').empty()\r\n\r\n //标识:是否处理设置界面\r\n if (!settingShow && $('.chartSetting').is(':visible') && !isEditMode()) {\r\n hideChartSettingComponent()\r\n }\r\n}\r\n\r\n// 显示图表设置界面\r\nfunction showChartSettingComponent(refresh, chart_id) {\r\n if (!$('.chartSetting').is(':visible')) {\r\n\r\n //隐藏设置界面\r\n $('.chartSetting').show();\r\n\r\n $('#luckysheet-cell-main').find('.luckysheet-datavisual-selection-set div').show()\r\n chartInfo.chartparam.luckysheetCurrentChartActive = true\r\n setTimeout(function () {\r\n luckysheetsizeauto()\r\n }, 0)\r\n }\r\n}\r\n\r\n// 隐藏图表设置界面\r\nfunction hideChartSettingComponent(refresh) {\r\n if ($('.chartSetting').is(':visible')) {\r\n\r\n //隐藏设置界面\r\n $('.chartSetting').hide();\r\n //.luckysheet-modal-dialog-resize为图表显示框的缩放框,.luckysheet-modal-dialog-controll为显示框右边的控制按钮\r\n $('#luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll').hide()\r\n\r\n $('#luckysheet-cell-main').find('.luckysheet-datavisual-selection-set div').remove()\r\n\r\n chartInfo.chartparam.luckysheetCurrentChartActive = false\r\n if (!isEditMode() && !refresh) {\r\n\r\n setTimeout(function () {\r\n luckysheetsizeauto()\r\n }, 0)\r\n\r\n }\r\n\r\n }\r\n}\r\n\r\n// 隐藏其他sheet的图表,显示当前sheet的图表 chartMix 切换sheet页显示隐藏图表\r\nfunction renderChartShow(index) {\r\n //传入index,图表显示隐藏\r\n selectRangeBorderHide('true') //隐藏数据高亮区域,随意传入一个字符串,表示不处理chartSetting界面\r\n\r\n const luckysheetfile = chartInfo.luckysheetfile;\r\n luckysheetfile.forEach((file) => {\r\n //切换当前页的所有图表都显示出来\r\n if (file.index == index) {\r\n\r\n const chartLists = file.chart || [];\r\n\r\n chartLists.forEach((chart) => {\r\n chart.isShow = true;\r\n $('#' + chart.chart_id + '_c').show();\r\n\r\n chartInfo.resizeChart(chart.chart_id)\r\n\r\n if (chart.needRangeShow == true) {\r\n //一个sheet页只有一个图表高亮显示,//重要!因为在store了做了存储,所以能在此处找到对应图表设置显示隐藏\r\n //操作DOM当前图表选择区域高亮\r\n chartInfo.currentChart = chartInfo.getChartJson(chart.chart_id)\r\n selectRangeBorderShow(chart.chart_id)\r\n }\r\n\r\n })\r\n\r\n }\r\n\r\n // 隐藏其他页的图表\r\n else {\r\n const chartLists = file.chart || [];\r\n\r\n chartLists.forEach((chart) => {\r\n chart.isShow = false;\r\n $('#' + chart.chart_id + '_c').hide();\r\n })\r\n }\r\n });\r\n\r\n}\r\n\r\nexport { chart, createLuckyChart, hideAllNeedRangeShow, renderChartShow }\r\n","import Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport { replaceHtml } from '../utils/util';\r\nimport sheetmanage from './sheetmanage';\r\nimport {changeSheetContainerSize} from './resize';\r\nimport { jfrefreshgrid_rhcw } from '../global/refresh';\r\nimport server from './server';\r\nimport luckysheetPostil from './postil';\r\nimport imageCtrl from './imageCtrl';\r\n\r\n\r\n\r\nlet luckysheetZoomTimeout = null;\r\n\r\nexport function zoomChange(ratio){\r\n if(Store.flowdata==null || Store.flowdata.length==0){\r\n return;\r\n }\r\n\r\n clearTimeout(luckysheetZoomTimeout);\r\n luckysheetZoomTimeout = setTimeout(() => {\r\n if (Store.clearjfundo) {\r\n Store.jfredo.push({ \r\n \"type\": \"zoomChange\", \r\n \"zoomRatio\": Store.zoomRatio, \r\n \"curZoomRatio\": ratio, \r\n \"sheetIndex\": Store.currentSheetIndex, \r\n });\r\n }\r\n \r\n Store.zoomRatio = ratio;\r\n\r\n let currentSheet = sheetmanage.getSheetByIndex();\r\n\r\n //批注\r\n luckysheetPostil.buildAllPs(currentSheet.data);\r\n\r\n //图片\r\n imageCtrl.images = currentSheet.images;\r\n imageCtrl.allImagesShow();\r\n imageCtrl.init();\r\n\r\n if(currentSheet.config==null){\r\n currentSheet.config = {};\r\n }\r\n \r\n if(currentSheet.config.sheetViewZoom==null){\r\n currentSheet.config.sheetViewZoom = {};\r\n }\r\n\r\n let type = currentSheet.config.curentsheetView;\r\n if(type==null){\r\n type = \"viewNormal\";\r\n }\r\n currentSheet.config.sheetViewZoom[type+\"ZoomScale\"] = ratio;\r\n \r\n server.saveParam(\"all\", Store.currentSheetIndex, Store.zoomRatio, { \"k\": \"zoomRatio\" });\r\n server.saveParam(\"cg\", Store.currentSheetIndex, currentSheet.config[\"sheetViewZoom\"], { \"k\": \"sheetViewZoom\" });\r\n\r\n zoomRefreshView();\r\n }, 100);\r\n \r\n}\r\n\r\nexport function zoomRefreshView(){\r\n // let $scrollLeft = $(\"#luckysheet-scrollbar-x\"), $scrollTop = $(\"#luckysheet-scrollbar-y\");\r\n // let sl = $scrollLeft.scrollLeft(), st = $scrollTop.scrollTop();\r\n\r\n // let wp = $scrollLeft.find(\"div\").width(), hp = $scrollTop.find(\"div\").height();\r\n\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n changeSheetContainerSize();\r\n\r\n // let wc = $scrollLeft.find(\"div\").width(), hc = $scrollTop.find(\"div\").height();\r\n\r\n // $scrollLeft.scrollLeft(sl+wc-wp);\r\n // $scrollTop.scrollTop(st+hc-hp);\r\n}\r\n\r\n\r\nexport function zoomInitial(){\r\n\r\n $(\"#luckysheet-zoom-minus\").click(function(){\r\n let currentRatio;\r\n if(Store.zoomRatio==null){\r\n currentRatio = Store.zoomRatio = 1;\r\n }\r\n else{\r\n currentRatio = Math.ceil(Store.zoomRatio*10)/10;\r\n }\r\n\r\n currentRatio = currentRatio-0.1;\r\n\r\n if(currentRatio==Store.zoomRatio){\r\n currentRatio = currentRatio-0.1;\r\n }\r\n\r\n if(currentRatio<=0.1){\r\n currentRatio = 0.1;\r\n }\r\n\r\n // Store.zoomRatio = currentRatio;\r\n zoomChange(currentRatio);\r\n zoomNumberDomBind(currentRatio);\r\n });\r\n\r\n $(\"#luckysheet-zoom-plus\").click(function(){\r\n let currentRatio;\r\n if(Store.zoomRatio==null){\r\n currentRatio = Store.zoomRatio = 1;\r\n }\r\n else{\r\n currentRatio = Math.floor(Store.zoomRatio*10)/10;\r\n }\r\n\r\n currentRatio = currentRatio+0.1;\r\n\r\n if(currentRatio==Store.zoomRatio){\r\n currentRatio = currentRatio+0.1;\r\n }\r\n\r\n if(currentRatio>=4){\r\n currentRatio = 4;\r\n }\r\n\r\n // Store.zoomRatio = currentRatio;\r\n zoomChange(currentRatio);\r\n zoomNumberDomBind(currentRatio);\r\n });\r\n\r\n $(\"#luckysheet-zoom-slider\").mousedown(function(e){\r\n let xoffset = $(this).offset().left, pageX = e.pageX;\r\n\r\n let currentRatio = positionToRatio(pageX-xoffset);\r\n // Store.zoomRatio = currentRatio;\r\n zoomChange(currentRatio);\r\n zoomNumberDomBind(currentRatio);\r\n });\r\n\r\n $(\"#luckysheet-zoom-cursor\").mousedown(function(e){\r\n let curentX = e.pageX,cursorLeft = parseFloat($(\"#luckysheet-zoom-cursor\").css(\"left\"));\r\n $(\"#luckysheet-zoom-cursor\").css(\"transition\",\"none\");\r\n $(document).off(\"mousemove.zoomCursor\").on(\"mousemove.zoomCursor\",function(event){\r\n let moveX = event.pageX;\r\n let offsetX = moveX - curentX;\r\n // console.log(moveX, curentX, offsetX);\r\n // curentX = moveX;\r\n // let left = parseFloat($(\"#luckysheet-zoom-cursor\").css(\"left\"));\r\n let pos = cursorLeft + offsetX; \r\n let currentRatio = positionToRatio(pos);\r\n\r\n if(currentRatio>4){\r\n currentRatio =4;\r\n pos = 100;\r\n }\r\n\r\n if(currentRatio<0.1){\r\n currentRatio =0.1;\r\n pos = 0;\r\n }\r\n\r\n // Store.zoomRatio = currentRatio;\r\n zoomChange(currentRatio);\r\n let r = Math.round(currentRatio*100) + \"%\";\r\n $(\"#luckysheet-zoom-ratioText\").html(r);\r\n $(\"#luckysheet-zoom-cursor\").css(\"left\", pos-4);\r\n });\r\n\r\n $(document).off(\"mouseup.zoomCursor\").on(\"mouseup.zoomCursor\",function(event){\r\n $(document).off(\".zoomCursor\");\r\n $(\"#luckysheet-zoom-cursor\").css(\"transition\",\"all 0.3s\");\r\n });\r\n\r\n e.stopPropagation();\r\n }).click(function(e){\r\n e.stopPropagation();\r\n });\r\n\r\n $(\"#luckysheet-zoom-ratioText\").click(function(){\r\n // Store.zoomRatio = 1;\r\n zoomChange(1);\r\n zoomNumberDomBind(1);\r\n });\r\n\r\n zoomNumberDomBind(Store.zoomRatio);\r\n}\r\n\r\n\r\nfunction zoomSlierDown(){\r\n\r\n}\r\n\r\nfunction positionToRatio(pos){\r\n let ratio = 1;\r\n if(pos<50){\r\n ratio = Math.round((pos*1.8/100 + 0.1)*100)/100;\r\n }\r\n else if(pos>50){\r\n ratio = Math.round(((pos-50)*6/100 + 1)*100)/100;\r\n }\r\n\r\n return ratio;\r\n}\r\n\r\nfunction zoomSlierDomBind(ratio){\r\n let domPos = 50;\r\n if(ratio<1){\r\n domPos = Math.round((ratio - 0.1)*100 / 0.18)/10;\r\n }\r\n else if(ratio>1){\r\n domPos = Math.round((ratio - 1)*100 / 0.6)/10+50;\r\n }\r\n $(\"#luckysheet-zoom-cursor\").css(\"left\", domPos-4);\r\n}\r\n\r\nexport function zoomNumberDomBind(ratio){\r\n let r = Math.round(ratio*100) + \"%\";\r\n $(\"#luckysheet-zoom-ratioText\").html(r);\r\n zoomSlierDomBind(ratio);\r\n}\r\n\r\n","import { isEditMode } from '../global/validate';\r\nimport cleargridelement from '../global/cleargridelement';\r\nimport { getcellvalue, datagridgrowth,getcellFormula } from '../global/getdata';\r\nimport { setcellvalue } from '../global/setdata';\r\nimport luckysheetcreatedom from '../global/createdom';\r\nimport tooltip from '../global/tooltip';\r\nimport formula from '../global/formula';\r\nimport { luckysheetrefreshgrid, jfrefreshgrid_rhcw } from '../global/refresh';\r\nimport rhchInit from '../global/rhchInit';\r\nimport editor from '../global/editor';\r\nimport { luckysheetextendtable, luckysheetdeletetable } from '../global/extend';\r\nimport { isRealNum } from '../global/validate';\r\nimport { replaceHtml, getObjType, chatatABC, arrayRemoveItem } from '../utils/util';\r\nimport { sheetHTML,luckysheetlodingHTML } from './constant';\r\nimport server from './server';\r\nimport luckysheetConfigsetting from './luckysheetConfigsetting';\r\nimport pivotTable from './pivotTable';\r\nimport luckysheetsizeauto from './resize';\r\nimport luckysheetPostil from './postil';\r\nimport imageCtrl from './imageCtrl';\r\nimport dataVerificationCtrl from './dataVerificationCtrl';\r\nimport hyperlinkCtrl from './hyperlinkCtrl';\r\nimport luckysheetFreezen from './freezen';\r\nimport { createFilterOptions, labelFilterOptionState } from './filter';\r\nimport { selectHightlightShow, selectionCopyShow } from './select';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport { renderChartShow } from '../expendPlugins/chart/plugin';\r\nimport {changeSheetContainerSize, menuToolBarWidth} from './resize';\r\nimport {zoomNumberDomBind} from './zoom';\r\nimport menuButton from './menuButton';\r\nimport method from '../global/method';\r\n\r\nconst sheetmanage = {\r\n generateRandomSheetIndex: function(prefix) {\r\n if(prefix == null){\r\n prefix = \"Sheet\";\r\n }\r\n\r\n let userAgent = window.navigator.userAgent.replace(/[^a-zA-Z0-9]/g, \"\").split(\"\");\r\n\r\n let mid = \"\";\r\n\r\n for(let i = 0; i < 12; i++){\r\n mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))];\r\n }\r\n\r\n let time = new Date().getTime();\r\n\r\n return prefix + \"_\" + mid + \"_\" + time;\r\n },\r\n generateRandomSheetName: function(file, isPivotTable) {\r\n let index = file.length;\r\n\r\n const locale_pivotTable = locale().pivotTable;\r\n const title = locale_pivotTable.title;\r\n\r\n for(let i = 0; i < file.length; i++){\r\n if(file[i].name.indexOf(\"Sheet\") > -1 || file[i].name.indexOf(title) > -1){\r\n let suffix = parseFloat(file[i].name.replace(\"Sheet\", \"\").replace(title, \"\"));\r\n\r\n if(suffix != \"NaN\" && Math.ceil(suffix) > index){\r\n index = Math.ceil(suffix);\r\n }\r\n }\r\n }\r\n\r\n if(isPivotTable){\r\n return title + (index + 1);\r\n }\r\n else{\r\n return \"Sheet\" + (index + 1);\r\n }\r\n },\r\n generateCopySheetName: function(file, name) {\r\n let copySheetName = \"\";\r\n\r\n let _locale = locale();\r\n let locale_info = _locale.info;\r\n\r\n if(name.toString().indexOf(\"(\"+locale_info.copy) > -1){\r\n let copy_i = name.toString().indexOf(\"(\"+locale_info.copy);\r\n let name2 = name.toString().substring(0, copy_i) + \"(\"+locale_info.copy;\r\n let index = null;\r\n\r\n for(let i = 0; i < file.length; i++){\r\n let fileName = file[i].name.toString();\r\n let st_i = fileName.indexOf(name2);\r\n\r\n if(st_i > -1){\r\n let ed_i = fileName.indexOf(\")\", st_i + name2.length);\r\n let num = fileName.substring(st_i + name2.length, ed_i);\r\n\r\n if(isRealNum(num)){\r\n if(index == null || parseInt(num) > index){\r\n index = parseInt(num);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(index == null){\r\n copySheetName = name2 + \"2)\";\r\n }\r\n else{\r\n index++;\r\n copySheetName = name2 + index + \")\";\r\n }\r\n }\r\n else{\r\n let index = null;\r\n let hascopy = false;\r\n let name2 = name + \"(\"+locale_info.copy;\r\n\r\n for(let i = 0; i < file.length; i++){\r\n let fileName = file[i].name.toString();\r\n let st_i = fileName.indexOf(name2);\r\n\r\n if(st_i > -1){\r\n hascopy = true;\r\n let ed_i = fileName.indexOf(\")\", st_i + name2.length);\r\n let num = fileName.substring(st_i + name2.length, ed_i);\r\n\r\n if(isRealNum(num)){\r\n if(index == null || parseInt(num) > index){\r\n index = parseInt(num);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(hascopy){\r\n if(index == null){\r\n copySheetName = name + \"(\"+ locale_info.copy +\"2)\";\r\n }\r\n else{\r\n index++;\r\n copySheetName = name + \"(\"+ locale_info.copy +\"\" + index + \")\";\r\n }\r\n }\r\n else{\r\n copySheetName = name + \"(\"+ locale_info.copy +\")\";\r\n }\r\n }\r\n\r\n return copySheetName;\r\n },\r\n getSheetByIndex: function(index) {\r\n let _this = this;\r\n\r\n if(index == null){\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n let i = _this.getSheetIndex(index);\r\n \r\n return Store.luckysheetfile[i];\r\n },\r\n getSheetByName: function(name) {\r\n let _this = this;\r\n\r\n if(name == null){\r\n return null;\r\n }\r\n\r\n for(let i=0;i {\r\n if ('undefined' === typeof item.index) {\r\n item.index = this.generateRandomSheetIndex()\r\n }\r\n if (indexs.includes(item.index)) {\r\n item.index = this.generateRandomSheetIndex()\r\n }else {\r\n indexs.push(item.index)\r\n }\r\n\r\n if ('undefined' === typeof item.status) {\r\n item.status = 0\r\n }\r\n if (item.status == 1) {\r\n if (hasActive) {\r\n item.status = 0\r\n }else {\r\n hasActive = true\r\n }\r\n }\r\n })\r\n if (!hasActive) {\r\n Store.luckysheetfile[0].status = 1\r\n }\r\n }\r\n Store.currentSheetIndex = Store.luckysheetfile[0].index;\r\n\r\n for (let i = 0; i < Store.luckysheetfile.length; i++) {\r\n if (Store.luckysheetfile[i].status == 1) {\r\n Store.currentSheetIndex = Store.luckysheetfile[i].index;\r\n break;\r\n }\r\n }\r\n \r\n return Store.currentSheetIndex;\r\n },\r\n addNewSheet: function(e, isPivotTable) {\r\n if(isEditMode() || Store.allowEdit===false){\r\n // alert(\"非编辑模式下不允许该操作!\");\r\n return;\r\n }\r\n\r\n let _this = this;\r\n\r\n let order = Store.luckysheetfile.length;\r\n let index = _this.generateRandomSheetIndex();\r\n\r\n let sheetname = _this.generateRandomSheetName(Store.luckysheetfile, isPivotTable);\r\n \r\n $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, { \"index\": index, \"active\": \"\", \"name\": sheetname, \"style\": \"\",\"colorset\":\"\" }));\r\n\r\n let sheetconfig = { \r\n \"name\": sheetname, \r\n \"color\": \"\", \r\n \"status\": \"0\", \r\n \"order\": order, \r\n \"index\": index, \r\n \"celldata\": [], \r\n \"row\": Store.defaultrowNum, \r\n \"column\": Store.defaultcolumnNum, \r\n \"config\": {}, \r\n \"pivotTable\": null, \r\n \"isPivotTable\": !!isPivotTable \r\n };\r\n Store.luckysheetfile.push(sheetconfig);\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-sheets-item\" + index).addClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-cell-main\").append('
');\r\n cleargridelement(e);\r\n\r\n server.saveParam(\"sha\", null, $.extend(true, {}, sheetconfig));\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n let redo = {};\r\n redo[\"type\"] = \"addSheet\";\r\n redo[\"sheetconfig\"] = $.extend(true, {}, sheetconfig);\r\n redo[\"index\"] = index;\r\n redo[\"currentSheetIndex\"] = Store.currentSheetIndex;\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n _this.changeSheetExec(index, isPivotTable, true);\r\n },\r\n setSheetHide: function(index) {\r\n let _this = this;\r\n let currentIdx = _this.getSheetIndex(index);\r\n Store.luckysheetfile[currentIdx].hide = 1;\r\n \r\n let luckysheetcurrentSheetitem = $(\"#luckysheet-sheets-item\" + index);\r\n luckysheetcurrentSheetitem.hide();\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n \r\n let indicator;\r\n if(luckysheetConfigsetting.showsheetbarConfig.sheet){\r\n indicator = luckysheetcurrentSheetitem.nextAll(\":visible\");\r\n if (luckysheetcurrentSheetitem.nextAll(\":visible\").length > 0) {\r\n indicator = indicator.eq(0).data(\"index\");\r\n }\r\n else {\r\n indicator = luckysheetcurrentSheetitem.prevAll(\":visible\").eq(0).data(\"index\");\r\n }\r\n }else{\r\n let nextActiveIdx , showSheetIdxs = [];\r\n Store.luckysheetfile.forEach((ele,index)=>{\r\n if(1 !== ele.hide) showSheetIdxs.push(index);\r\n });\r\n let len = showSheetIdxs.length;\r\n if(1 === len){\r\n nextActiveIdx = showSheetIdxs[0];\r\n }else{\r\n nextActiveIdx = showSheetIdxs[len-1] > currentIdx ? showSheetIdxs.find(e => e>currentIdx ) : showSheetIdxs[len-1];\r\n }\r\n\r\n indicator = Store.luckysheetfile[nextActiveIdx].index;\r\n }\r\n \r\n $(\"#luckysheet-sheets-item\" + indicator).addClass(\"luckysheet-sheets-item-active\");\r\n \r\n _this.changeSheetExec(indicator);\r\n\r\n server.saveParam(\"sh\", luckysheetcurrentSheetitem.data(\"index\"), 1, { \"op\": \"hide\", \"cur\": indicator });\r\n },\r\n setSheetShow: function(index) {\r\n let _this = this;\r\n\r\n Store.luckysheetfile[_this.getSheetIndex(index)].hide = 0;\r\n _this.changeSheetExec(index);\r\n\r\n server.saveParam(\"sh\", index, 0, {\"op\": \"show\", \"cur\": null});\r\n },\r\n sheetMaxIndex: 0,\r\n ordersheet: function(property) {\r\n return function (a, b) {\r\n let value1 = a[property];\r\n let value2 = b[property];\r\n return value1 - value2;\r\n }\r\n },\r\n getCurrentOrder: function() {\r\n let orders = {};\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").each(function (a) {\r\n let index = $(this).data(\"index\");\r\n\r\n for (let i = 0; i < Store.luckysheetfile.length; i++) {\r\n if (Store.luckysheetfile[i].index == index) {\r\n orders[index.toString()] = a;\r\n break;\r\n }\r\n }\r\n });\r\n\r\n return orders;\r\n },\r\n reOrderAllSheet: function() {\r\n let orders = {};\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").each(function (a) {\r\n let index = $(this).data(\"index\");\r\n\r\n for (let i = 0; i < Store.luckysheetfile.length; i++) {\r\n if (Store.luckysheetfile[i].index == index) {\r\n Store.luckysheetfile[i].order = a;\r\n orders[index.toString()] = a;\r\n break;\r\n }\r\n }\r\n });\r\n\r\n server.saveParam(\"shr\", null, orders);\r\n\r\n Store.luckysheetfile.sort((x, y) => {\r\n let order_x = x.order;\r\n let order_y = y.order;\r\n \r\n if(order_x != null && order_y != null){\r\n return order_x - order_y;\r\n }\r\n else if(order_x != null){\r\n return -1;\r\n }\r\n else if(order_y != null){\r\n return 1;\r\n }\r\n else{\r\n return 1;\r\n }\r\n })\r\n },\r\n createSheet: function() { //修复拖动sheet更新后台后,重新打开显示错误\r\n let _this = this;\r\n\r\n let btn = [];\r\n Store.luckysheetfile.sort(_this.ordersheet('order'));\r\n\r\n for (let i = 0; i < Store.luckysheetfile.length; i++) {\r\n let display = \"\";\r\n let sheetIndex = Store.luckysheetfile[i].index;\r\n\r\n let colorset = '';\r\n if(Store.luckysheetfile[i].color != null){\r\n colorset = '
';\r\n }\r\n\r\n if (Store.currentSheetIndex == sheetIndex) { //使用Store.luckysheetfile中的index比较,而不是order\r\n btn.push(replaceHtml(sheetHTML, { \"index\": sheetIndex, \"active\": \"luckysheet-sheets-item-active\", \"name\": Store.luckysheetfile[i].name, \"style\": \"\",\"colorset\":colorset }));\r\n }\r\n else {\r\n if (Store.luckysheetfile[i].hide == 1) {\r\n btn.push(replaceHtml(sheetHTML, { \"index\": sheetIndex, \"active\": \"\", \"name\": Store.luckysheetfile[i].name, \"style\": \"display:none;\",\"colorset\":colorset }));\r\n }\r\n else {\r\n btn.push(replaceHtml(sheetHTML, { \"index\": sheetIndex, \"active\": \"\", \"name\": Store.luckysheetfile[i].name, \"style\": \"\",\"colorset\":colorset }));\r\n }\r\n display = \"style='display:none;'\";\r\n }\r\n //Store.luckysheetfile[i].index = i; //index即为默认\r\n // if(sheetIndex > this.sheetMaxIndex){\r\n // this.sheetMaxIndex = sheetIndex;\r\n // }\r\n\r\n $(\"#luckysheet-cell-main\").append('
');\r\n }\r\n\r\n $(\"#luckysheet-sheet-container-c\").append(btn.join(\"\"));\r\n\r\n _this.locationSheet();\r\n },\r\n locationSheet: function() {\r\n let $c = $(\"#luckysheet-sheet-container-c\"), winW = $(\"#\"+Store.container).width();\r\n let $cursheet = $(\"#luckysheet-sheet-container-c > div.luckysheet-sheets-item-active\").eq(0);\r\n\r\n let scrollLeftpx = 0;\r\n let c_width = 0;\r\n\r\n $(\"#luckysheet-sheet-container-c > div.luckysheet-sheets-item:visible\").each(function(){\r\n if($(this).hasClass(\"luckysheet-sheets-item-active\")){\r\n scrollLeftpx = c_width;\r\n }\r\n c_width += $(this).outerWidth();\r\n });\r\n \r\n setTimeout(function(){\r\n $c.scrollLeft(scrollLeftpx - 10);\r\n\r\n if (c_width >= winW * 0.7) {\r\n if(luckysheetConfigsetting.showsheetbarConfig.sheet){\r\n $(\"#luckysheet-sheet-area .luckysheet-sheets-scroll\").css(\"display\", \"inline-block\");\r\n $(\"#luckysheet-sheet-container .docs-sheet-fade-left\").show();\r\n }\r\n \r\n }\r\n }, 1)\r\n },\r\n copySheet: function(copyindex, e) {\r\n if(isEditMode() || Store.allowEdit===false){\r\n // alert(\"非编辑模式下不允许该操作!\");\r\n return;\r\n }\r\n\r\n let _this = this;\r\n\r\n let order = Store.luckysheetfile.length;\r\n let index = _this.generateRandomSheetIndex();\r\n \r\n let copyarrindex = _this.getSheetIndex(copyindex);\r\n let copyjson = $.extend(true, {}, Store.luckysheetfile[copyarrindex]);\r\n copyjson.order = order;\r\n copyjson.index = index;\r\n copyjson.name = _this.generateCopySheetName(Store.luckysheetfile, copyjson.name);\r\n \r\n let colorset = '';\r\n if(copyjson.color != null){\r\n colorset = '
';\r\n }\r\n\r\n let copyobject = $(\"#luckysheet-sheets-item\" + copyindex);\r\n $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, { \"index\": copyjson.index, \"active\": \"\", \"name\": copyjson.name, \"order\": copyjson.order, \"style\": \"\", \"colorset\": colorset }));\r\n $(\"#luckysheet-sheets-item\" + copyjson.index).insertAfter(copyobject);\r\n Store.luckysheetfile.splice(copyarrindex + 1, 0, copyjson);\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-sheets-item\" + index).addClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-cell-main\").append('
');\r\n cleargridelement(e);\r\n\r\n server.saveParam(\"shc\", index, { \"copyindex\": copyindex, \"name\": copyjson.name });\r\n\r\n _this.changeSheetExec(index);\r\n _this.reOrderAllSheet();\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfredo.push({ \r\n \"type\": \"copySheet\", \r\n \"copyindex\": copyindex, \r\n \"index\": copyjson.index, \r\n \"sheetIndex\": copyjson.index \r\n });\r\n }\r\n else if (Store.jfredo.length > 0) {\r\n let jfredostr = Store.jfredo[Store.jfredo.length - 1];\r\n\r\n if (jfredostr.type == \"copySheet\") {\r\n jfredostr.index = copyjson.index;\r\n jfredostr.sheetIndex = copyjson.index;\r\n }\r\n }\r\n },\r\n hasSheet: function(index) {\r\n if (index == null) {\r\n return false;\r\n }\r\n\r\n index = this.getSheetIndex(index);\r\n \r\n if (index == null) {\r\n return false;\r\n }\r\n else {\r\n return true;\r\n }\r\n },\r\n createSheetbydata: function(data, isrenew, isBefore=true) {\r\n let _this = this;\r\n\r\n let colorset = '';\r\n if(data.color != null){\r\n colorset = '
';\r\n }\r\n\r\n $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, { \"index\": data.index, \"active\": \"\", \"name\": data.name, \"order\": data.order, \"style\": \"\", \"colorset\": colorset }));\r\n\r\n if(isBefore){\r\n let previndex = data.order;\r\n if(previndex >= Store.luckysheetfile.length){\r\n previndex = Store.luckysheetfile.length - 1;\r\n $(\"#luckysheet-sheets-item\" + data.index).insertAfter($(\"#luckysheet-sheets-item\" + Store.luckysheetfile[previndex].index));\r\n }\r\n else{\r\n $(\"#luckysheet-sheets-item\" + data.index).insertBefore($(\"#luckysheet-sheets-item\" + Store.luckysheetfile[previndex].index));\r\n }\r\n }\r\n \r\n Store.luckysheetfile.push(data);\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-sheets-item\" + data.index).addClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-cell-main\").append('
');\r\n cleargridelement();\r\n\r\n if(isrenew != null){\r\n server.saveParam(\"shre\", null, { \"reIndex\": data.index });\r\n data.hide = 0;\r\n server.saveParam(\"sh\", data.index, 0, {\"op\": \"show\", \"cur\": null});\r\n }\r\n else{\r\n server.saveParam(\"sha\", null, data);\r\n }\r\n\r\n _this.changeSheetExec(data.index, data.isPivotTable, true);\r\n _this.reOrderAllSheet();\r\n },\r\n deleteSheet: function(index) {\r\n let _this = this;\r\n\r\n if(Store.allowEdit===false){\r\n return;\r\n }\r\n\r\n let arrIndex = _this.getSheetIndex(index);\r\n _this.setSheetHide(index);\r\n\r\n $(\"#luckysheet-sheets-item\" + index).remove();\r\n $(\"#luckysheet-datavisual-selection-set-\" + index).remove();\r\n \r\n let removedsheet = Store.luckysheetfile.splice(arrIndex, 1);\r\n _this.reOrderAllSheet();\r\n\r\n server.saveParam(\"shd\", null, {\"deleIndex\": index });\r\n\r\n if (Store.clearjfundo) {\r\n removedsheet[0].type = \"deleteSheet\";\r\n Store.jfredo.push(removedsheet[0]);\r\n }\r\n },\r\n nulldata: null,\r\n getGridData: function(d) {\r\n let ret = [];\r\n\r\n for(let r = 0; r < d.length; r++){\r\n for(let c = 0; c < d[0].length; c++){\r\n if(d[r][c] == null){\r\n continue;\r\n }\r\n\r\n ret.push({r:r, c:c, v:d[r][c]});\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n buildGridData: function(file) {\r\n // 如果已经存在二维数据data,那么直接返回data;如果只有celldata,那么就转化成二维数组data,再返回\r\n let row = file.row == null ? Store.defaultrowNum : file.row, \r\n column = file.column == null ? Store.defaultcolumnNum : file.column,\r\n data = file.data && file.data.length > 0 ? file.data : datagridgrowth([], row, column),\r\n celldata = file.celldata;\r\n if (file.data && file.data.length > 0) {\r\n for (let i = 0; i < data.length; i++) {\r\n for (let j = 0; j < data[0].length; j++) {\r\n setcellvalue(i, j, data, data[i][j]);\r\n }\r\n }\r\n } else {\r\n if(celldata && celldata.length > 0){\r\n for(let i = 0; i < celldata.length; i++){\r\n let item = celldata[i];\r\n let r = item.r;\r\n let c = item.c;\r\n let v = item.v;\r\n \r\n if(r >= data.length){\r\n data = datagridgrowth(data, r - data.length + 1, 0);\r\n }\r\n if(c >= data[0].length){\r\n data = datagridgrowth(data, 0, c - data[0].length + 1);\r\n }\r\n setcellvalue(r, c, data, v);\r\n }\r\n }\r\n }\r\n\r\n //亿万格式+精确度 恢复全局初始化\r\n luckysheetConfigsetting.autoFormatw = false; \r\n luckysheetConfigsetting.accuracy = undefined;\r\n return data;\r\n },\r\n cutGridData: function(d) {\r\n let rowindex = 0;\r\n\r\n for(let r = d.length - 1; r >= 0; r--){\r\n let isnull = true;\r\n \r\n for(let c = 0; c < d[0].length; c++){\r\n let value = getcellvalue(r, c);\r\n \r\n if(value != null && $.trim(value).length > 0){\r\n isnull = false;\r\n break;\r\n }\r\n }\r\n\r\n if(!isnull){\r\n break;\r\n }\r\n else{\r\n rowindex = r;\r\n }\r\n }\r\n\r\n return d.slice(0, rowindex);\r\n },\r\n addGridData: function(celldata, row, column) {\r\n let data = datagridgrowth([], row, column);\r\n \r\n if(celldata != null){\r\n for(let i = 0; i < celldata.length; i++){\r\n let item = celldata[i];\r\n let r = item.r;\r\n let c = item.c;\r\n let v = item.v;\r\n\r\n if(r >= data.length){\r\n data = datagridgrowth(data, r - data.length + 1, 0);\r\n }\r\n\r\n if(c >= data[0].length){\r\n data = datagridgrowth(data, 0, c - data[0].length + 1);\r\n }\r\n\r\n setcellvalue(r, c, data, v)\r\n }\r\n }\r\n \r\n return data;\r\n },\r\n sheetParamRestore: function(file, data) {\r\n Store.luckysheet_select_save = file[\"luckysheet_select_save\"];\r\n if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){\r\n if(data[0] != null && data[0][0] != null && data[0][0].mc != null){\r\n Store.luckysheet_select_save = [{ \r\n \"row\": [0, data[0][0].mc.rs - 1], \r\n \"column\": [0, data[0][0].mc.cs - 1] \r\n }];\r\n }\r\n else{\r\n Store.luckysheet_select_save = [{ \r\n \"row\": [0, 0], \r\n \"column\": [0, 0] \r\n }];\r\n }\r\n }\r\n\r\n Store.luckysheet_selection_range = file[\"luckysheet_selection_range\"] == null ? [] : file[\"luckysheet_selection_range\"];\r\n Store.config = file[\"config\"] == null ? {} : file[\"config\"];\r\n\r\n Store.zoomRatio = file[\"zoomRatio\"] == null ? 1 : file[\"zoomRatio\"];\r\n\r\n if(file[\"defaultRowHeight\"]!=null){\r\n Store.defaultrowlen = parseFloat(file[\"defaultRowHeight\"]);\r\n }\r\n else{\r\n Store.defaultrowlen = luckysheetConfigsetting[\"defaultRowHeight\"];\r\n }\r\n\r\n if(file[\"defaultColWidth\"]!=null){\r\n Store.defaultcollen = parseFloat(file[\"defaultColWidth\"]);\r\n }\r\n else{\r\n Store.defaultcollen = luckysheetConfigsetting[\"defaultColWidth\"];\r\n }\r\n\r\n if(file[\"showGridLines\"]!=null){\r\n let showGridLines = file[\"showGridLines\"];\r\n if(showGridLines==0 || showGridLines==false){\r\n Store.showGridLines = false;\r\n }\r\n else{\r\n Store.showGridLines = true;\r\n }\r\n }\r\n else{\r\n Store.showGridLines = true;\r\n }\r\n },\r\n initialjfFile: function(menu, title) {\r\n let _this = this;\r\n\r\n _this.getCurSheet();\r\n let file = Store.luckysheetfile[_this.getSheetIndex(Store.currentSheetIndex)];\r\n _this.nulldata = datagridgrowth([], Store.defaultrowNum, Store.defaultcolumnNum);\r\n let data = _this.buildGridData(file);\r\n\r\n //初始化的时候 记录选区\r\n let select_save = [];\r\n file.jfgird_select_save = file.jfgird_select_save || [];\r\n file.jfgird_select_save.forEach(item=>select_save.push({\"row\":item.row,\"column\":item.column}));\r\n file.luckysheet_select_save = select_save;\r\n \r\n this.sheetParamRestore(file, data);\r\n\r\n let r2 = Store.luckysheet_select_save[0].row[1], \r\n c2 = Store.luckysheet_select_save[0].column[1];\r\n \r\n if(Store.luckysheet_select_save.length > 1){\r\n for(let i = 0; i < Store.luckysheet_select_save.length; i++){\r\n if(Store.luckysheet_select_save[i].row[1] > r2){\r\n r2 = Store.luckysheet_select_save[i].row[1];\r\n }\r\n\r\n if(Store.luckysheet_select_save[i].column[1] > c2){\r\n c2 = Store.luckysheet_select_save[i].column[1];\r\n }\r\n }\r\n }\r\n\r\n menuButton.fontInitial(Store.fontList);//initial font\r\n\r\n file.data = data;\r\n\r\n let rowheight = data.length;\r\n if(r2 > rowheight - 1){\r\n rowheight = r2 + 1;\r\n }\r\n\r\n let colwidth = data[0].length;\r\n if(c2 > colwidth - 1){\r\n colwidth = c2 + 1;\r\n }\r\n\r\n //钩子函数 表格创建之前触发\r\n if(typeof luckysheetConfigsetting.beforeCreateDom == \"function\" ){\r\n luckysheetConfigsetting.beforeCreateDom(luckysheet);\r\n }\r\n\r\n if(typeof luckysheetConfigsetting.workbookCreateBefore == \"function\"){\r\n luckysheetConfigsetting.workbookCreateBefore(luckysheet);\r\n }\r\n\r\n // Store.flowdata = data;\r\n\r\n luckysheetcreatedom(colwidth, rowheight, data, menu, title);\r\n\r\n setTimeout(function () {\r\n tooltip.createHoverTip(\"#luckysheet_info_detail\" ,\".luckysheet_info_detail_back, .luckysheet_info_detail_input, .luckysheet_info_detail_update\");\r\n tooltip.createHoverTip(\"#luckysheet-wa-editor\" ,\".luckysheet-toolbar-menu-button, .luckysheet-toolbar-button, .luckysheet-toolbar-combo-button\");\r\n\r\n Store.luckysheetTableContentHW = [\r\n $(\"#luckysheet-cell-main\").width() + Store.rowHeaderWidth - Store.cellMainSrollBarSize, \r\n $(\"#luckysheet-cell-main\").height() + Store.columnHeaderHeight - Store.cellMainSrollBarSize\r\n ];\r\n $(\"#luckysheetTableContent, #luckysheetTableContentF\").attr({ \r\n width: Math.ceil(Store.luckysheetTableContentHW[0] * Store.devicePixelRatio), \r\n height: Math.ceil(Store.luckysheetTableContentHW[1] * Store.devicePixelRatio) \r\n }).css({ \r\n width: Store.luckysheetTableContentHW[0], \r\n height: Store.luckysheetTableContentHW[1] \r\n }).get(0).getContext(\"2d\");\r\n let locale_info = locale().info;\r\n let key = server.gridKey;\r\n let cahce_key = key + \"__qkcache\";\r\n\r\n let ini = function(){\r\n file[\"load\"] = \"1\";\r\n\r\n _this.createSheet();\r\n\r\n let execF = function(){\r\n _this.mergeCalculation(file[\"index\"]);\r\n _this.setSheetParam(false);\r\n // editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n _this.storeSheetParam();\r\n _this.restoreselect();\r\n _this.CacheNotLoadControll = [];\r\n _this.restoreCache();\r\n formula.execFunctionGroupForce(luckysheetConfigsetting.forceCalculation);\r\n _this.restoreSheetAll(Store.currentSheetIndex);\r\n \r\n // luckysheetrefreshgrid(0, 0);\r\n $(\"#luckysheet_info_detail_save\").html(locale_info.detailSave);\r\n\r\n if (!!file.isPivotTable) {\r\n Store.luckysheetcurrentisPivotTable = true;\r\n // pivotTable.changePivotTable(Store.currentSheetIndex); //此方法需要注释掉,在restoreSheetAll中已经执行了刷新了数据透视表,这里就不需要了\r\n }\r\n else {\r\n Store.luckysheetcurrentisPivotTable = false;\r\n $(\"#luckysheet-modal-dialog-slider-pivot\").hide();\r\n }\r\n\r\n // Store toolbar button width value\r\n menuToolBarWidth();\r\n\r\n luckysheetsizeauto();\r\n\r\n //等待滚动条dom宽高加载完成后 初始化滚动位置\r\n if(file[\"scrollLeft\"] != null && file[\"scrollLeft\"] > 0){\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(file[\"scrollLeft\"]);\r\n }\r\n else{\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(0);\r\n }\r\n \r\n if(file[\"scrollTop\"] != null && file[\"scrollTop\"] > 0){\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(file[\"scrollTop\"]);\r\n }\r\n else{\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(0);\r\n }\r\n\r\n // 此处已经渲染完成表格,应该挪到前面\r\n // //钩子函数 表格创建之前触发\r\n // if(typeof luckysheetConfigsetting.beforeCreateDom == \"function\" ){\r\n // luckysheetConfigsetting.beforeCreateDom(luckysheet);\r\n // }\r\n\r\n // if(typeof luckysheetConfigsetting.workbookCreateBefore == \"function\"){\r\n // luckysheetConfigsetting.workbookCreateBefore(luckysheet);\r\n // }\r\n\r\n arrayRemoveItem(Store.asyncLoad,'core');\r\n\r\n if(luckysheetConfigsetting.pointEdit){\r\n setTimeout(function(){\r\n $(\"#luckysheetloadingdata\").remove();\r\n }, 0);\r\n }\r\n else{\r\n setTimeout(function(){\r\n $(\"#luckysheetloadingdata\").fadeOut().remove();\r\n }, 500);\r\n }\r\n }\r\n\r\n let loadSheetUrl = server.loadSheetUrl;\r\n \r\n if(loadSheetUrl == \"\"){\r\n // execF();\r\n // }\r\n // else if(sheetindex.length>0 && loadSheetUrl == \"\"){\r\n // for(let i = 0;i $(\"#luckysheet-scrollbar-x\")[0].offsetWidth){\r\n file[\"scrollLeft\"] = $(\"#luckysheet-scrollbar-x\").scrollLeft(); //横向滚动条\r\n }\r\n\r\n if($(\"#luckysheet-scrollbar-y\")[0].scrollHeight > $(\"#luckysheet-scrollbar-y\")[0].offsetHeight){\r\n file[\"scrollTop\"] = $(\"#luckysheet-scrollbar-y\").scrollTop(); //纵向滚动条\r\n }\r\n\r\n file[\"zoomRatio\"] = Store.zoomRatio;\r\n },\r\n setSheetParam: function(isload=true) {\r\n let index = this.getSheetIndex(Store.currentSheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n Store.flowdata = file[\"data\"];\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n\r\n // formula.execFunctionGroupData = null;\r\n formula.execFunctionGlobalData = null;\r\n window.luckysheet_getcelldata_cache = null;\r\n\r\n this.sheetParamRestore(file, Store.flowdata);\r\n\r\n if(file[\"freezen\"] == null){\r\n luckysheetFreezen.freezenhorizontaldata = null;\r\n luckysheetFreezen.freezenverticaldata = null;\r\n }\r\n else{\r\n luckysheetFreezen.freezenhorizontaldata = file[\"freezen\"].horizontal == null ? null : file[\"freezen\"].horizontal.freezenhorizontaldata;\r\n luckysheetFreezen.freezenverticaldata = file[\"freezen\"].vertical == null ? null : file[\"freezen\"].vertical.freezenverticaldata;\r\n }\r\n \r\n if(isload){\r\n rhchInit(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n\r\n //批注\r\n luckysheetPostil.buildAllPs(Store.flowdata);\r\n\r\n //图片\r\n imageCtrl.currentImgId = null;\r\n imageCtrl.images = file.images;\r\n imageCtrl.allImagesShow();\r\n imageCtrl.init();\r\n\r\n //数据验证\r\n dataVerificationCtrl.dataVerification = file.dataVerification;\r\n dataVerificationCtrl.init();\r\n\r\n //链接\r\n hyperlinkCtrl.hyperlink = file.hyperlink;\r\n hyperlinkCtrl.init();\r\n \r\n createFilterOptions(file[\"filter_select\"], file[\"filter\"]);\r\n },\r\n restoreselect: function() {\r\n let index = this.getSheetIndex(Store.currentSheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n //选区\r\n selectHightlightShow(true);\r\n\r\n //复制选区虚线框\r\n selectionCopyShow();\r\n\r\n if (file[\"scrollLeft\"] != null && file[\"scrollLeft\"] > 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(file[\"scrollLeft\"]); //列标题\r\n }\r\n else {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(0);\r\n }\r\n\r\n if (file[\"scrollTop\"] != null && file[\"scrollTop\"] > 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(file[\"scrollTop\"]); //列标题\r\n }\r\n else {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(0);\r\n }\r\n },\r\n storeSheetParamALL: function() {\r\n let _this = this;\r\n\r\n _this.storeSheetParam();\r\n let index = _this.getSheetIndex(Store.currentSheetIndex);\r\n Store.luckysheetfile[index][\"data\"] = Store.flowdata;\r\n Store.luckysheetfile[index][\"config\"] = $.extend(true, {}, Store.config);\r\n },\r\n mergeCalculationSheet:{},\r\n mergeCalculation:function(index){\r\n let file = Store.luckysheetfile[this.getSheetIndex(index)];\r\n let config = file.config, data = file.data;\r\n if(config==null){\r\n return;\r\n }\r\n let mergeConfig = config.merge;\r\n if(mergeConfig==null || index in this.mergeCalculationSheet || file[\"autoCalculationMerge\"]===false){\r\n return;\r\n }\r\n\r\n this.mergeCalculationSheet[index] = 1;\r\n\r\n for(let x in mergeConfig){\r\n let r = parseInt(x.substr(0, x.indexOf('_')));\r\n let c = parseInt(x.substr(x.indexOf('_') + 1));\r\n let mcInfo = mergeConfig[x];\r\n if(data[r][c]==null){\r\n data[r][c] = {};\r\n }\r\n\r\n data[r][c][\"mc\"] = {\r\n r:r,\r\n c:c,\r\n rs:mcInfo.rs,\r\n cs:mcInfo.cs,\r\n }\r\n\r\n for(let ir=r;ir{\r\n formula.addToCellList(formulaTxt, str);\r\n if(str.indexOf(\"!\")>-1){\r\n let name = str.substr(0, str.indexOf('!'));\r\n // dataNameList[name] = true;\r\n \r\n let sheet = this.getSheetByName(name);\r\n if(sheet!=null){\r\n let dataSheetIndex = sheet.index;\r\n dataIndexList[dataSheetIndex] = 1;\r\n \r\n formula.addToSheetIndexList(formulaTxt, dataSheetIndex);\r\n }\r\n }\r\n });\r\n\r\n if(formula.formulaContainSheetList[formulaTxt]==null){\r\n // dataIndexList[dataindex] = 1;\r\n formula.addToSheetIndexList(formulaTxt, dataindex);\r\n }\r\n }\r\n \r\n if(dataindex == null){\r\n continue;\r\n }\r\n \r\n \t\t// if(cache[dataindex.toString()] == null){\r\n \t\t// \t// ret.push(dataindex);\r\n // cache[dataindex.toString()] = 1;\r\n // this.checkLoadSheetIndexToDataIndex[dataindex] = 1;\r\n \t\t// }\r\n }\r\n \r\n for(let index in dataIndexList){\r\n // let sheet = this.getSheetByName(n);\r\n // if(sheet==null){\r\n // continue;\r\n // }\r\n\r\n // if(index == Store.currentSheetIndex){\r\n // continue;\r\n // }\r\n\r\n let dataindex = index;\r\n\r\n if(cache[dataindex.toString()] == null){\r\n \t\t\tret.push(dataindex);\r\n cache[dataindex.toString()] = 1;\r\n this.checkLoadSheetIndexToDataIndex[dataindex] = 1;\r\n \t\t}\r\n }\r\n }\r\n\r\n if(chart != null){\r\n for(let i = 0; i < chart.length; i++){\r\n let cc = chart[i];\r\n let dataindex = cc.dataSheetIndex;\r\n\r\n if(dataindex == null){\r\n continue;\r\n }\r\n\r\n if(cache[dataindex.toString()] == null){\r\n ret.push(dataindex);\r\n cache[dataindex.toString()] = 1;\r\n }\r\n } \r\n }\r\n\r\n if(pivotTable != null){\r\n let dataindex = pivotTable.pivotDataSheetIndex;\r\n \r\n \t\tif(dataindex != null && cache[dataindex.toString()] == null){\r\n \t\t\tret.push(dataindex);\r\n \t\t\tcache[dataindex.toString()] = 1;\r\n \t\t}\r\n }\r\n\r\n \treturn ret;\r\n },\r\n showSheet: function() {\r\n // changeSheetContainerSize();\r\n $(\"#luckysheet-cell-flow_0\").css({ \"width\": Store.ch_width, \"top\": \"-1px\" }); //width更新\r\n $(\"#luckysheet-sheettable_0\").css({ \"width\": Store.ch_width - 1, \"height\": Store.rh_height });\r\n $(\"#luckysheetrowHeader_0\").css(\"height\", Store.rh_height);\r\n $(\"#luckysheet-cols-h-cells_0\").css(\"width\", Store.ch_width); //width更新\r\n\r\n $(\"#luckysheet-scrollbar-x div\").width(Store.ch_width);\r\n $(\"#luckysheet-scrollbar-y div\").height(Store.rh_height + Store.columnHeaderHeight - Store.cellMainSrollBarSize - 3);\r\n\r\n //等待滚动条dom宽高计算完成后 初始化该表格滚动位置\r\n let index = this.getSheetIndex(Store.currentSheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n\r\n Store.scrollRefreshSwitch = false;\r\n \r\n if(file[\"scrollLeft\"] != null && file[\"scrollLeft\"] > 0){\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(file[\"scrollLeft\"] * Store.zoomRatio);\r\n }\r\n else{\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(0);\r\n }\r\n\r\n if(file[\"scrollTop\"] != null && file[\"scrollTop\"] > 0){\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(file[\"scrollTop\"] * Store.zoomRatio);\r\n }\r\n else{\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(0);\r\n }\r\n\r\n setTimeout(() => {\r\n Store.scrollRefreshSwitch = true;\r\n }, 0);\r\n\r\n zoomNumberDomBind(Store.zoomRatio);\r\n },\r\n setCurSheet: function(index) {\r\n for (let i = 0; i < Store.luckysheetfile.length; i++) {\r\n if (Store.luckysheetfile[i][\"index\"] == index) {\r\n Store.luckysheetfile[i].status = 1;\r\n }\r\n else {\r\n Store.luckysheetfile[i].status = 0;\r\n }\r\n }\r\n\r\n Store.currentSheetIndex = index;\r\n },\r\n getSheetIndex: function(index) {\r\n for (let i = 0; i < Store.luckysheetfile.length; i++) {\r\n if (Store.luckysheetfile[i][\"index\"] == index) {\r\n return i;\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n changeSheetExec: function(index, isPivotInitial, isNewSheet) {\r\n \r\n let $sheet = $(\"#luckysheet-sheets-item\" + index);\r\n\r\n window.luckysheet_getcelldata_cache = null;\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $sheet.addClass(\"luckysheet-sheets-item-active\").show();\r\n\r\n cleargridelement();\r\n this.changeSheet(index, isPivotInitial, isNewSheet);\r\n \r\n $(\"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu\").hide();\r\n\r\n if (formula.rangestart) {\r\n formula.createRangeHightlight();\r\n }\r\n \r\n this.sheetBarShowAndHide(index);\r\n },\r\n sheetArrowShowAndHide(){\r\n let containerW = $(\"#luckysheet-sheet-container\").width();\r\n\r\n let c_width = 0;\r\n $(\"#luckysheet-sheet-container-c > div.luckysheet-sheets-item:visible\").each(function(){\r\n c_width += $(this).outerWidth();\r\n });\r\n\r\n if (c_width >= containerW) {\r\n if(luckysheetConfigsetting.showsheetbarConfig.sheet){\r\n $(\"#luckysheet-sheet-area .luckysheet-sheets-scroll\").css(\"display\", \"inline-block\");\r\n $(\"#luckysheet-sheet-container .docs-sheet-fade-left\").show();\r\n }\r\n \r\n }\r\n else{\r\n $(\"#luckysheet-sheet-area .luckysheet-sheets-scroll\").css(\"display\", \"none\");\r\n $(\"#luckysheet-sheet-container .docs-sheet-fade-left\").hide();\r\n }\r\n },\r\n sheetBarShowAndHide(index){\r\n let $c = $(\"#luckysheet-sheet-container-c\");\r\n\r\n if(index!=null){\r\n let $sheet = $(\"#luckysheet-sheets-item\" + index);\r\n $c.scrollLeft($sheet.offset().left);\r\n }\r\n\r\n\r\n let c_width = $c.width(), c_srollwidth = $c[0].scrollWidth, scrollLeft = $c.scrollLeft();\r\n\r\n if (scrollLeft <= 0) {\r\n $(\"#luckysheet-sheet-container .docs-sheet-fade-left\").hide();\r\n }\r\n else {\r\n $(\"#luckysheet-sheet-container .docs-sheet-fade-left\").show();\r\n }\r\n\r\n if (c_width + scrollLeft >= c_srollwidth) {\r\n $(\"#luckysheet-sheet-container .docs-sheet-fade-right\").hide();\r\n }\r\n else {\r\n $(\"#luckysheet-sheet-container .docs-sheet-fade-right\").show();\r\n }\r\n },\r\n delChart: function(chart_id, sheetIndex) {\r\n let index = this.getSheetIndex(sheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n if (file.chart == null) {\r\n file.chart = [];\r\n }\r\n else {\r\n for (let i = 0; i < file.chart.length; i++) {\r\n if (file.chart[i].chart_id == chart_id) {\r\n Store.luckysheetfile[index].chart.splice(i, 1);\r\n break;\r\n }\r\n }\r\n }\r\n },\r\n saveChart: function(json) {//采用chartMix store存储,弃用Store.luckysheetfile存储,防止重复存储\r\n let index = this.getSheetIndex(json.sheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n if (file.chart == null) {\r\n file.chart = [];\r\n file.chart.push(json);\r\n }\r\n else {\r\n for (let i = 0; i < file.chart.length; i++) {\r\n if (file.chart[i].chart_id == json.chart_id) {\r\n let old = $.extend(true, {}, file.chart[i]);\r\n file.chart[i] = $.extend(true, {}, old, json);\r\n return;\r\n }\r\n }\r\n\r\n file.chart.push(json);\r\n }\r\n },\r\n getChart: function(sheetIndex, chart_id) {\r\n let index = this.getSheetIndex(sheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n if (file.chart == null) {\r\n return null;\r\n }\r\n else {\r\n for (let i = 0; i < file.chart.length; i++) {\r\n if (file.chart[i].chart_id == chart_id) {\r\n return file.chart[i];\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n },\r\n getRangetxt: function(sheetIndex, range, currentIndex) {\r\n let sheettxt = \"\";\r\n\r\n if (currentIndex == null) {\r\n currentIndex = Store.currentSheetIndex;\r\n }\r\n\r\n if (sheetIndex != currentIndex) {\r\n sheettxt = Store.luckysheetfile[this.getSheetIndex(sheetIndex)].name + \"!\";\r\n }\r\n\r\n let row0 = range[\"row\"][0], row1 = range[\"row\"][1];\r\n let column0 = range[\"column\"][0], column1 = range[\"column\"][1];\r\n\r\n if (row0 == null && row1 == null) {\r\n return sheettxt + chatatABC(column0) + \":\" + chatatABC(column1);\r\n }\r\n else if (column0 == null && column1 == null) {\r\n return sheettxt + (row0 + 1) + \":\" + (row1 + 1);\r\n }\r\n else {\r\n if (column0 == column1 && row0 == row1) {\r\n return sheettxt + chatatABC(column0) + (row0 + 1);\r\n }\r\n else {\r\n return sheettxt + chatatABC(column0) + (row0 + 1) + \":\" + chatatABC(column1) + (row1 + 1);\r\n }\r\n }\r\n },\r\n getSheetName: function(sheetIndex) {\r\n if (sheetIndex == null) {\r\n sheetIndex = Store.currentSheetIndex;\r\n }\r\n\r\n return Store.luckysheetfile[this.getSheetIndex(sheetIndex)].name;\r\n },\r\n getSheetMerge: function() {\r\n if(Store.config.merge == null){\r\n \treturn null;\r\n }\r\n\r\n return Store.config.merge;\r\n },\r\n getSheetData: function(sheetIndex) {\r\n if (sheetIndex == null) {\r\n sheetIndex = Store.currentSheetIndex;\r\n }\r\n\r\n return Store.luckysheetfile[this.getSheetIndex(sheetIndex)].data;\r\n },\r\n getSheetConfig: function(sheetIndex) {\r\n let _this = this;\r\n\r\n if (sheetIndex == null) {\r\n sheetIndex = Store.currentSheetIndex;\r\n }\r\n\r\n let config = Store.luckysheetfile[_this.getSheetIndex(sheetIndex)].config;\r\n\r\n if(config == null){\r\n \tStore.luckysheetfile[_this.getSheetIndex(sheetIndex)].config = {};\r\n }\r\n\r\n return Store.luckysheetfile[_this.getSheetIndex(sheetIndex)].config;\r\n },\r\n restoreFilter: function(sheetIndex) {\r\n let index = this.getSheetIndex(sheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n // if($('#luckysheet-filter-selected-sheet' + sheetIndex).length > 0 || file.filter_select == null || JSON.stringify(file.filter_select) == \"{}\"){\r\n // if(file.config != null && file.config.rowhidden != null){\r\n // file.config.rowhidden = {};\r\n // Store.config = file.config;\r\n\r\n // jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length,false);\r\n // }\r\n\r\n // return;\r\n // }\r\n\r\n if(getObjType(file.filter_select) == \"string\"){\r\n file.filter_select = JSON.parse(file.filter_select);\r\n }\r\n\r\n if(file.filter_select == null || file.filter_select.row == null || file.filter_select.column == null){\r\n return;\r\n }\r\n\r\n createFilterOptions(file.filter_select);\r\n\r\n if(getObjType(file.filter) != \"object\"){\r\n if(file.filter != null && getObjType(file.filter) == \"string\"){ \r\n file.filter = JSON.parse(file.filter);\r\n }\r\n }\r\n\r\n let rowhidden = {};\r\n if(file.config != null && file.config.rowhidden != null){\r\n rowhidden = file.config.rowhidden;\r\n }\r\n\r\n $(\"#luckysheet-filter-options-sheet\" + sheetIndex + \" .luckysheet-filter-options\").each(function(i){\r\n if(file.filter == null){\r\n return false;\r\n }\r\n\r\n let $top = $(this);\r\n let item = file.filter[i];\r\n\r\n if(item == null){\r\n return true;\r\n }\r\n\r\n if(getObjType(item) != \"object\"){\r\n item = JSON.parse(item);\r\n }\r\n\r\n labelFilterOptionState($top, item.optionstate, item.rowhidden, item.caljs, false, item.st_r, item.ed_r, item.cindex, item.st_c, item.ed_c);\r\n\r\n rowhidden = $.extend(true, rowhidden, item.rowhidden);\r\n });\r\n\r\n if(file.config == null){\r\n file.config = {};\r\n }\r\n\r\n file.config[\"rowhidden\"] = rowhidden;\r\n Store.config = file.config;\r\n\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length,false);\r\n },\r\n restorePivot: function(sheetIndex) {\r\n let index = this.getSheetIndex(sheetIndex);\r\n let file = Store.luckysheetfile[index];\r\n\r\n if (!file.isPivotTable) {\r\n return;\r\n }\r\n\r\n pivotTable.getCellData(sheetIndex);\r\n pivotTable.initialPivotManage(true);\r\n pivotTable.refreshPivotTable(false);\r\n },\r\n restoreSheetAll: function(sheetIndex) {\r\n let _this= this;\r\n _this.restorePivot(sheetIndex);\r\n _this.restoreFilter(sheetIndex);\r\n _this.restoreFreezen(sheetIndex);\r\n },\r\n restoreFreezen: function(sheetIndex) {\r\n luckysheetFreezen.initialFreezen(sheetIndex);\r\n },\r\n restoreCache: function() {\r\n let _this = this;\r\n \r\n let data = _this.CacheNotLoadControll;\r\n _this.CacheNotLoadControll = [];\r\n\r\n if(data.length == 0){\r\n return;\r\n }\r\n\r\n for(let i = 0; i < data.length; i++){\r\n let item = data[i];\r\n _this.execCache(item);\r\n }\r\n },\r\n CacheNotLoadControll:[],\r\n execCache: function(item) {\r\n let _this = this;\r\n\r\n let type = item.t;\r\n let index = item.i;\r\n let value = item.v;\r\n let file = Store.luckysheetfile[_this.getSheetIndex(index)];\r\n\r\n if(type == \"sha\"){\r\n Store.luckysheetfile.push(value);\r\n }\r\n else if(type == \"shc\"){\r\n let copyjson = $.extend(true, {}, Store.luckysheetfile[_this.getSheetIndex(value.copyindex)]);\r\n copyjson.index = index;\r\n Store.luckysheetfile.push(copyjson);\r\n }\r\n else if(type == \"shd\"){\r\n Store.luckysheetfile.splice(value.deleIndex, 1);\r\n }\r\n else if(type == \"shr\"){\r\n for(let pos in value){\r\n Store.luckysheetfile[_this.getSheetIndex(pos)].order = value[pos];\r\n }\r\n }\r\n\r\n if((file == null || file.load != \"1\") && !(type in {\"sha\":0, \"shc\":0, \"shd\":0, \"shr\":0}) ){\r\n _this.CacheNotLoadControll.push(item);\r\n return;\r\n }\r\n\r\n if(type == \"v\"){\r\n let r = item.r, c = item.c, v = item.v;\r\n let data = _this.getSheetData(index);\r\n file.data[r][c] = v;\r\n }\r\n else if(type == \"fc\"){\r\n let op = item.op, pos = item.pos;\r\n\r\n if(getObjType(value) != \"object\"){\r\n value = new Function(\"return \" + value)();\r\n }\r\n\r\n let r = value.r, c = value.c;\r\n\r\n if(op == \"del\" ){\r\n formula.delFunctionGroup(r, c, index);\r\n }\r\n else {\r\n formula.insertUpdateFunctionGroup(r, c, index);\r\n }\r\n }\r\n else if(type == \"cg\"){\r\n let v = value, k = item.k;\r\n let config1 = _this.getSheetConfig(index);\r\n \r\n if(!(k in config1)){\r\n config1[k] = {};\r\n }\r\n\r\n for(let key in v){\r\n config1[k][key] = v[key];\r\n }\r\n\r\n Store.config = config1;\r\n }\r\n else if(type == \"f\"){\r\n let v = value, op = item.op, pos = item.pos;\r\n let filter = file.filter;\r\n\r\n if(filter == null){\r\n filter = {};\r\n }\r\n\r\n if(op == \"upOrAdd\"){\r\n filter[pos] = v;\r\n }\r\n else if(op == \"del\"){\r\n delete filter[pos];\r\n }\r\n }\r\n else if(type == \"fsc\"){\r\n file.filter = null;\r\n file.filter_select = null;\r\n }\r\n else if(type == \"fsr\"){\r\n let v = value;\r\n file.filter = v.filter;\r\n file.filter_select = v.filter_select;\r\n }\r\n else if(type == \"sh\"){\r\n let op = item.op, cur = item.cur, v = value; \r\n if(op == \"hide\"){\r\n file.status = 0;\r\n Store.luckysheetfile[_this.getSheetIndex(cur)].status = 1;\r\n }\r\n else if(op == \"show\"){\r\n for(let i = 0; i < Store.luckysheetfile.length; i++){\r\n Store.luckysheetfile[i].status = 0;\r\n }\r\n file.status = 1;\r\n }\r\n }\r\n else if(type == \"all\"){\r\n let k = item.k, s = item.s;\r\n if(s && getObjType(value) != \"object\"){\r\n file[k] = JSON.stringify(value);\r\n }\r\n else{\r\n file[k] = value;\r\n }\r\n }\r\n else if(type == \"c\"){\r\n let op = item.op, cid = item.cid;\r\n\r\n if(op == \"add\"){\r\n file.chart.push(value);\r\n }\r\n else if(op == \"xy\" || op == \"wh\" || op == \"update\"){\r\n for(let i = 0; i < file.chart.length; i++){\r\n if(file.chart[i].chart_id == cid){\r\n for(let item in file.chart[i]){\r\n for(let vitem in value){\r\n if(item == vitem){\r\n file.chart[i][item] = value[vitem];\r\n }\r\n }\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n else if(op == \"del\"){\r\n for(let i = 0; i < file.chart.length; i++){\r\n if(file.chart[i].chart_id == cid){\r\n file.chart.splice(i, 1); \r\n return;\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"drc\"){\r\n let rc = item.rc, index = value.index, len = value.len;\r\n let celldata = file.celldata;\r\n\r\n if(rc == \"r\"){\r\n for(let i = 0; celldata.length == 0; i++){\r\n let cell = celldata[i];\r\n if(cell.r >= index && cell.r < index + len){\r\n delete celldata[i];\r\n }\r\n else if(cell.r >= index + len){\r\n cell.r -= len;\r\n }\r\n }\r\n\r\n file.row -= len;\r\n }\r\n else{\r\n for(let i = 0; celldata.length == 0; i++){\r\n let cell = celldata[i];\r\n if(cell.c >= index && cell.c < index + len){\r\n delete celldata[i];\r\n }\r\n else if(cell.c >= index + len){\r\n cell.c -= len;\r\n }\r\n }\r\n\r\n file.column -= len;\r\n }\r\n\r\n let ret = [];\r\n for(let i = 0; i < celldata.length; i++){\r\n if(celldata[i] != null){\r\n ret.push(celldata[i]);\r\n }\r\n }\r\n file.celldata = ret;\r\n \r\n let mtype, mst, med;\r\n if(rc == \"r\"){\r\n mtype = \"row\";\r\n }\r\n else{\r\n mtype = \"column\";\r\n }\r\n mst = index;\r\n med = index + len - 1;\r\n\r\n luckysheetdeletetable(mtype, mst, med, true);\r\n }\r\n else if(type==\"arc\"){\r\n let rc = item.rc, index = value.index, len = value.len;\r\n let celldata = file.celldata;\r\n\r\n if(rc == \"r\"){\r\n for(let i = 0; i < celldata.length; i++){\r\n let cell = celldata[i];\r\n if(cell.r > index){\r\n cell.r += len;\r\n }\r\n }\r\n\r\n file.row += len;\r\n }\r\n else{\r\n for(let i = 0; i < celldata.length; i++){\r\n let cell = celldata[i];\r\n if(cell.c > index){\r\n cell.c += len;\r\n }\r\n }\r\n\r\n file.column += len;\r\n }\r\n\r\n let mtype;\r\n if(rc == \"r\"){\r\n mtype = \"row\";\r\n }\r\n else{\r\n mtype = \"column\";\r\n }\r\n \r\n luckysheetextendtable(mtype, index, len, true);\r\n }\r\n else if(type == \"na\"){\r\n server.saveParam(\"na\", null, value);\r\n }\r\n else if(type == \"thumb\"){\r\n setTimeout(function(){\r\n _this.imageRequest();\r\n }, 2000);\r\n }\r\n }\r\n}\r\n\r\nexport default sheetmanage;\r\n","import { replaceHtml, getObjType, chatatABC, ABCatNum, luckysheetfontformat } from '../utils/util';\r\nimport { getSheetIndex, getRangetxt, getluckysheetfile } from '../methods/get';\r\nimport { setluckysheetfile } from '../methods/set';\r\nimport { luckyColor } from '../controllers/constant';\r\nimport sheetmanage from '../controllers/sheetmanage';\r\nimport menuButton from '../controllers/menuButton';\r\nimport server from '../controllers/server';\r\nimport luckysheetFreezen from '../controllers/freezen';\r\nimport { checkProtectionLocked, checkProtectionCellHidden } from '../controllers/protection';\r\nimport dataVerificationCtrl from '../controllers/dataVerificationCtrl';\r\nimport { seletedHighlistByindex, luckysheet_count_show } from '../controllers/select';\r\nimport { isRealNum, isRealNull, valueIsError, isEditMode } from './validate';\r\nimport { isdatetime, isdatatype } from './datecontroll';\r\nimport { getCellTextSplitArr, getCellTextInfo } from '../global/getRowlen';\r\nimport { getcellvalue, getcellFormula, getInlineStringNoStyle, getOrigincell } from './getdata';\r\nimport { setcellvalue } from './setdata';\r\nimport { genarate, valueShowEs } from './format';\r\nimport editor from './editor';\r\nimport tooltip from './tooltip';\r\nimport { rowLocation, colLocation, colLocationByIndex, mouseposition } from './location';\r\nimport { luckysheetRangeLast } from './cursorPos';\r\nimport { jfrefreshgrid } from './refresh';\r\nimport { isInlineStringCell, convertSpanToShareString } from '../controllers/inlineString';\r\n// import luckysheet_function from '../function/luckysheet_function';\r\n// import functionlist from '../function/functionlist';\r\nimport { luckysheet_compareWith, luckysheet_getarraydata, luckysheet_getcelldata, luckysheet_parseData, luckysheet_getValue, luckysheet_indirect_check, luckysheet_indirect_check_return, luckysheet_offset_check, luckysheet_calcADPMM, luckysheet_getSpecialReference } from '../function/func';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\nimport json from './json';\r\nimport method from './method';\r\n\r\nconst luckysheetformula = {\r\n error: {\r\n v: \"#VALUE!\", //错误的参数或运算符\r\n n: \"#NAME?\", //公式名称错误\r\n na: \"#N/A\", //函数或公式中没有可用数值\r\n r: \"#REF!\", //删除了由其他公式引用的单元格\r\n d: \"#DIV/0!\", //除数是0或空单元格\r\n nm: \"#NUM!\", //当公式或函数中某个数字有问题时\r\n nl: \"#NULL!\", //交叉运算符(空格)使用不正确\r\n sp: \"#SPILL!\" //数组范围有其它值\r\n },\r\n errorInfo: function (err) {\r\n return err;\r\n },\r\n errorParamCheck: function (thisp, data, i) {\r\n let type, require;\r\n let _locale = locale();\r\n let locale_formulaMore = _locale.formulaMore;\r\n if (i < thisp.length) {\r\n type = thisp[i].type;\r\n require = thisp[i].require;\r\n }\r\n else {\r\n type = thisp[thisp.length - 1].type;\r\n require = thisp[thisp.length - 1].require;\r\n }\r\n\r\n if (require == \"o\" && (data == null || data == \"\")) {\r\n return [true, locale_formulaMore.tipSuccessText];\r\n }\r\n\r\n if (type.indexOf(\"all\") > -1) {\r\n return [true, locale_formulaMore.tipSuccessText];\r\n }\r\n else {\r\n if (type.indexOf(\"range\") > -1 && (getObjType(data) == \"object\" || getObjType(data) == \"array\")) {\r\n return [true, locale_formulaMore.tipSuccessText];\r\n }\r\n\r\n if (type.indexOf(\"number\") > -1 && (isRealNum(data) || getObjType(data) == \"boolean\")) {\r\n return [true, locale_formulaMore.tipSuccessText];\r\n }\r\n\r\n if (type.indexOf(\"string\") > -1 && getObjType(data) == \"string\") {\r\n return [true, locale_formulaMore.tipSuccessText];\r\n }\r\n\r\n if (type.indexOf(\"date\") > -1 && isdatetime(data)) {\r\n return [true, locale_formulaMore.tipSuccessText];\r\n }\r\n\r\n return [false, locale_formulaMore.tipParamErrorText];\r\n }\r\n },\r\n getPureValueByData: function (data) {\r\n if (data.length == 0) {\r\n return [];\r\n }\r\n\r\n let output = [];\r\n\r\n if (getObjType(data) == \"array\") {\r\n if (getObjType(data[0]) == \"array\") {\r\n for (let r = 0; r < data.length; r++) {\r\n let row = [];\r\n\r\n for (let c = 0; c < data[0].length; c++) {\r\n let cell = data[r][c];\r\n\r\n if (getObjType(cell) == \"object\") {\r\n row.push(cell.v);\r\n }\r\n else {\r\n row.push(cell);\r\n }\r\n }\r\n\r\n output.push(row);\r\n }\r\n }\r\n else {\r\n for (let i = 0; i < data.length; i++) {\r\n let cell = data[i];\r\n\r\n if (getObjType(cell) == \"object\") {\r\n output.push(cell.v);\r\n }\r\n else {\r\n output.push(cell);\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n let cell = data;\r\n\r\n if (getObjType(cell) == \"object\") {\r\n output.push(cell.v);\r\n }\r\n else {\r\n output.push(cell);\r\n }\r\n }\r\n\r\n return output;\r\n },\r\n //sparklines添加\r\n readCellDataToOneArray: function (rangeValue) {\r\n let _this = this;\r\n\r\n if (rangeValue == null) {\r\n return [];\r\n }\r\n\r\n if (getObjType(rangeValue) != \"object\") {\r\n return [rangeValue];\r\n }\r\n\r\n let dataformat = [];\r\n let data = [];\r\n\r\n if (rangeValue != null && rangeValue.data != null) {\r\n data = rangeValue.data;\r\n }\r\n else if (rangeValue != null && !isRealNull(rangeValue.v)) {\r\n return [rangeValue.v];\r\n }\r\n else {\r\n return [];\r\n }\r\n\r\n //适配excel的动态数组格式,{1,2,3,4,5}或者{{1,2,3},{4,5,6},{7,8,9}}\r\n if (getObjType(data) == \"array\") {\r\n data = _this.getPureValueByData(data);\r\n }\r\n else if (getObjType(data) == \"object\") {\r\n data = data.v;\r\n\r\n return [data];\r\n }\r\n else {\r\n if (/\\{.*?\\}/.test(data)) {\r\n data = data.replace(/\\{/g, \"[\").replace(/\\}/g, \"]\");\r\n }\r\n\r\n data = new Function(\"return \" + data)();\r\n }\r\n\r\n //把二维数组转换为一维数组,sparklines要求数据格式为一维数组\r\n //let dataformat = [];\r\n if (getObjType(data[0]) == \"array\") {\r\n for (let i = 0; i < data.length; i++) {\r\n dataformat = dataformat.concat(data[i]);\r\n }\r\n }\r\n else {\r\n dataformat = data;\r\n }\r\n\r\n return dataformat;\r\n },\r\n //sparklines添加\r\n //获得函数里某个参数的值,使用此函数需要在函数中执行luckysheet_getValue方法\r\n getValueByFuncData: function (value, arg) {\r\n if (value == null) {\r\n return null;\r\n }\r\n\r\n let _this = this;\r\n\r\n if (getObjType(value) == \"array\") {\r\n if (arg == \"avg\") {\r\n return luckysheet_function.AVERAGE.f.apply(luckysheet_function.AVERAGE, value);\r\n }\r\n else if (arg == \"sum\") {\r\n return luckysheet_function.SUM.f.apply(luckysheet_function.SUM, value);\r\n }\r\n else {\r\n if (getObjType(value[0]) == \"object\") {\r\n return luckysheet.mask.getValueByFormat(value[0]);\r\n }\r\n else {\r\n return value[0];\r\n }\r\n }\r\n }\r\n else if (getObjType(value) == \"object\") {\r\n return luckysheet.mask.getValueByFormat(value);\r\n }\r\n else {\r\n return value;\r\n }\r\n },\r\n //sparklines添加\r\n sparklinesColorMap: function (args, len) {\r\n let _this = this;\r\n let colorLists = null;\r\n\r\n if (len == null) {\r\n len = 5;\r\n }\r\n\r\n let index = 0;\r\n\r\n if (args.length > len) {\r\n for (let i = len; i < args.length; i++) {\r\n let colorMap = args[i];\r\n let colorListArray = _this.readCellDataToOneArray(colorMap);\r\n\r\n for (let a = 0; a < colorListArray.length; a++) {\r\n let ca = colorListArray[a];\r\n\r\n if (ca.indexOf(\":\") > -1) {\r\n if (!colorLists) {\r\n colorLists = {};\r\n }\r\n\r\n let calist = ca.split(\":\");\r\n\r\n if (calist.length == 2) {\r\n colorLists[calist[0]] = calist[1];\r\n }\r\n else if (calist.length > 1) {\r\n colorLists[calist[0] + \":\" + calist[1]] = calist[2];\r\n }\r\n }\r\n else {\r\n if (!colorLists) {\r\n colorLists = [];\r\n }\r\n\r\n colorLists.push(ca);\r\n }\r\n }\r\n\r\n index++;\r\n }\r\n }\r\n\r\n return colorLists;\r\n },\r\n //sparklines添加\r\n colorList: [\"#2ec7c9\", \"#fc5c5c\", \"#5ab1ef\", \"#ffb980\", \"#d87a80\", \"#8d98b3\", \"#e5cf0d\", \"#97b552\", \"#95706d\", \"#dc69aa\", \"#07a2a4\", \"#9a7fd1\", \"#588dd5\", \"#f5994e\", \"#c05050\", \"#59678c\", \"#c9ab00\", \"#7eb00a\", \"#6f5553\", \"#c14089\"],\r\n classlist: {\r\n \"province\": {\r\n 11: \"北京\",\r\n 12: \"天津\",\r\n 13: \"河北\",\r\n 14: \"山西\",\r\n 15: \"内蒙古\",\r\n 21: \"辽宁\",\r\n 22: \"吉林\",\r\n 23: \"黑龙江\",\r\n 31: \"上海\",\r\n 32: \"江苏\",\r\n 33: \"浙江\",\r\n 34: \"安徽\",\r\n 35: \"福建\",\r\n 36: \"江西\",\r\n 37: \"山东\",\r\n 41: \"河南\",\r\n 42: \"湖北\",\r\n 43: \"湖南\",\r\n 44: \"广东\",\r\n 45: \"广西\",\r\n 46: \"海南\",\r\n 50: \"重庆\",\r\n 51: \"四川\",\r\n 52: \"贵州\",\r\n 53: \"云南\",\r\n 54: \"西藏\",\r\n 61: \"陕西\",\r\n 62: \"甘肃\",\r\n 63: \"青海\",\r\n 64: \"宁夏\",\r\n 65: \"新疆\",\r\n 71: \"台湾\",\r\n 81: \"香港\",\r\n 82: \"澳门\",\r\n 91: \"国外\"\r\n }\r\n },\r\n oldvalue: null,\r\n dontupdate: function () {\r\n let _this = this;\r\n Store.luckysheetCellUpdate.length = 0; //clear array\r\n $(\"#luckysheet-functionbox-cell, #luckysheet-rich-text-editor\").html(_this.oldvalue);\r\n _this.cancelNormalSelected();\r\n if (_this.rangetosheet != Store.currentSheetIndex) {\r\n sheetmanage.changeSheetExec(_this.rangetosheet);\r\n }\r\n },\r\n fucntionboxshow: function (r, c) {\r\n\r\n if (!checkProtectionCellHidden(r, c, Store.currentSheetIndex)) {\r\n $(\"#luckysheet-functionbox-cell\").html(\"\");\r\n return;\r\n }\r\n\r\n let _this = this;\r\n\r\n let d = Store.flowdata;\r\n let value = \"\";\r\n // && d[r][c].v != null\r\n if (d[r] != null && d[r][c] != null) {\r\n let cell = $.extend(true, {}, d[r][c]);\r\n\r\n if (isInlineStringCell(cell)) {\r\n value = getInlineStringNoStyle(r, c);\r\n }\r\n else if (cell.f != null) {\r\n value = getcellvalue(r, c, d, \"f\");\r\n }\r\n else {\r\n value = valueShowEs(r, c, d);\r\n }\r\n }\r\n\r\n _this.oldvalue = value;\r\n $(\"#luckysheet-functionbox-cell\").html(value);\r\n },\r\n //获得某个单元格或区域的偏移一定距离后的单元格( Sheet1!B6:C8 格式)\r\n cellOffset: function (range, rows, cols, height, width) {// 参数:range or cell , rows,cols,height,width\r\n let startCell = range.startCell;\r\n let rowl = range.rowl;\r\n let coll = range.coll;\r\n let startCellRow = parseInt(startCell.replace(/[^0-9]/g, \"\"));\r\n let startCellCol = ABCatNum(startCell.replace(/[^A-Za-z]/g, \"\"));\r\n\r\n let row = [], col = [], offsetRange;\r\n row[0] = startCellRow + rows;\r\n col[0] = startCellCol + cols;\r\n\r\n row[1] = row[0] + height - 1;\r\n col[1] = col[0] + width - 1;\r\n\r\n col[0] = chatatABC(col[0]);\r\n col[1] = chatatABC(col[1]);\r\n\r\n let cellF = col[0] + row[0];\r\n let cellL = col[1] + row[1];\r\n\r\n if (cellF == cellL) {\r\n offsetRange = range.sheetName + \"!\" + cellF;\r\n }\r\n else {\r\n offsetRange = range.sheetName + \"!\" + cellF + \":\" + cellL;\r\n }\r\n\r\n return offsetRange;\r\n },\r\n parseDatetoNum: function (date) { //函数中获取到时间格式或者数字形式统一转化为数字进行运算\r\n let _this = this;\r\n\r\n if (typeof (date) == \"object\" && typeof date.v == \"number\") {\r\n date = date.v;\r\n }\r\n else if (isdatatype(date) == \"num\") {\r\n date = parseFloat(date);\r\n }\r\n else if (isdatatype(date) == \"date\") {\r\n date = genarate(date)[2];\r\n }\r\n else {\r\n return _this.error.v;\r\n }\r\n\r\n return date;\r\n },\r\n //获取一维数组\r\n getRangeArray: function (range) {\r\n let rangeNow = [];\r\n let fmt = \"General\";\r\n\r\n if (range.length == 1) { //一行\r\n for (let c = 0; c < range[0].length; c++) {\r\n if (range[0][c] != null && range[0][c].v) {\r\n rangeNow.push(range[0][c].v);\r\n let f = range[0][c].ct.fa;\r\n fmt = (fmt == \"General\") ? f : fmt;\r\n }\r\n else {\r\n //若单元格为null或为空,此处推入null(待考虑是否使用\"null\")\r\n rangeNow.push(null);\r\n }\r\n }\r\n }\r\n else if (range[0].length == 1) { //一列\r\n for (let r = 0; r < range.length; r++) {\r\n if (range[r][0] != null && range[r][0].v) {\r\n rangeNow.push(range[r][0].v);\r\n let f = range[r][0].ct.fa;\r\n fmt = (fmt == \"General\") ? f : fmt;\r\n }\r\n else {\r\n rangeNow.push(null);\r\n }\r\n }\r\n }\r\n else {\r\n for (let r = 0; r < range.length; r++) {\r\n for (let c = 0; c < range[r].length; c++) {\r\n if (range[r][c] != null && range[r][c].v) {\r\n rangeNow.push(range[r][c].v);\r\n let f = range[r][c].ct.fa;\r\n fmt = (fmt == \"General\") ? f : fmt;\r\n }\r\n else {\r\n rangeNow.push(null);\r\n }\r\n }\r\n }\r\n }\r\n\r\n range = rangeNow;\r\n\r\n return [range, fmt];\r\n },\r\n //获取二维数组:qksheet格式[[{v,m,ct}] ==> [1]\r\n getRangeArrayTwo: function (range) {\r\n let data = $.extend(true, [], range);\r\n\r\n if (data.length == 1) { //一行\r\n for (let c = 0; c < data[0].length; c++) {\r\n if (data[0][c] instanceof Object) {\r\n if (data[0][c] != null && data[0][c] instanceof Object && !!data[0][c].m) {\r\n data[0][c] = data[0][c].m;\r\n }\r\n else {\r\n if (data[0][c] != null && data[0][c] instanceof Object && !!data[0][c].v) {\r\n data[0][c] = data[0][c].v;\r\n }\r\n else {\r\n data[0][c] = null;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if (data[0].length == 1) { //一列\r\n for (let r = 0; r < data.length; r++) {\r\n if (data[r][0] instanceof Object) {\r\n if (data[r][0] != null && data[r][0] instanceof Object && !!data[r][0].m) {\r\n data[r][0] = data[r][0].m;\r\n }\r\n else {\r\n if (data[r][0] != null && data[r][0] instanceof Object && !!data[r][0].v) {\r\n data[r][0] = data[r][0].v;\r\n }\r\n else {\r\n data[r][0] = null;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n for (let r = 0; r < data.length; r++) {\r\n for (let c = 0; c < data[r].length; c++) {\r\n if (data[r][c] instanceof Object) {\r\n if (data[r][c] != null && data[r][c] instanceof Object && !!data[r][c].m) {\r\n data[r][c] = data[r][c].m;\r\n }\r\n else {\r\n if (data[r][c] != null && data[r][c] instanceof Object && !!data[r][c].v) {\r\n data[r][c] = data[r][c].v;\r\n }\r\n else {\r\n data[r][c] = null;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return data;\r\n },\r\n isWildcard: function (a, b) { //正则匹配通配符: * ? ~* ~?,a目标参数,b通配符\r\n let _this = this;\r\n\r\n a = a.toString();\r\n b = b.toString();\r\n\r\n if (_this.isCompareOperator(b).flag) {\r\n b = _this.isCompareOperator(b).num;\r\n }\r\n\r\n let str = \"\";\r\n for (let i = 0; i < b.length; i++) {\r\n let v = b.charAt(i);\r\n\r\n if (v == \"*\") {\r\n str += \".*\";\r\n }\r\n else if (v == \"?\") {\r\n str += \".\";\r\n }\r\n else if (v == \"~\") {\r\n if (b.charAt(i + 1) == \"*\") {\r\n str += \"\\\\*\";\r\n i++;\r\n }\r\n else if (b.charAt(i + 1) == \"?\") {\r\n str += \"\\\\?\";\r\n i++;\r\n }\r\n else {\r\n str += \"~\";\r\n }\r\n }\r\n else {\r\n str += v;\r\n }\r\n }\r\n\r\n let reg = new RegExp(\"^\" + str + \"$\", \"g\");\r\n\r\n return !!a.match(reg);\r\n },\r\n isCompareOperator: function (str) { //判断前一个或者两个字符是否是比较运算符\r\n str = str.toString();\r\n let ope = \"\"; //存放比较运算符\r\n let num = \"\"; //截取比较运算符之后的数字用于实际比较\r\n let strOne = str.substr(0, 1);\r\n let strTwo = str.substr(1, 1);\r\n let flag = false;\r\n let ret;\r\n\r\n if (strOne == \">\") {\r\n if (strTwo == \"=\") {\r\n ope = str.substr(0, 2);\r\n num = str.substr(2);\r\n flag = true;\r\n }\r\n else if (strTwo != \"=\") {\r\n ope = str.substr(0, 1);\r\n num = str.substr(1);\r\n flag = true;\r\n }\r\n }\r\n else if (strOne == \"<\") {\r\n if (strTwo == \"=\" || strTwo == \">\") {\r\n ope = str.substr(0, 2);\r\n num = str.substr(2);\r\n flag = true;\r\n }\r\n else if (strTwo != \"=\" && strTwo != \">\") {\r\n ope = str.substr(0, 1);\r\n num = str.substr(1);\r\n flag = true;\r\n }\r\n }\r\n else if (strOne == \"=\" && strTwo != \"=\") {\r\n ope = str.substr(0, 1);\r\n num = str.substr(1);\r\n flag = true;\r\n }\r\n\r\n ret = { \"flag\": flag, \"ope\": ope, \"num\": num };\r\n\r\n return ret;\r\n },\r\n acompareb: function (a, b) { //a 与 b比较,b可为含比较符,通配符\r\n let _this = this;\r\n let flag = false;\r\n\r\n if (isRealNum(b)) {\r\n flag = luckysheet_compareWith(a, \"==\", b);\r\n }\r\n else if (typeof (b) == \"string\") { //条件输入字符串,如:\">233\"\r\n if (b.indexOf(\"*\") != -1 || b.indexOf(\"?\") != -1) { // 正则匹配:输入通配符:\"黑*\",\"白?\",以及\"白?黑*~*\"\r\n //通配符函数\r\n return _this.isWildcard(a, b);\r\n }\r\n else if (_this.isCompareOperator(b).flag) { //\"黑糖\"\r\n let ope = _this.isCompareOperator(b).ope;\r\n let num = _this.isCompareOperator(b).num;\r\n flag = luckysheet_compareWith(a, ope, num);\r\n }\r\n else {\r\n flag = luckysheet_compareWith(a, \"==\", b);\r\n }\r\n }\r\n\r\n return flag;\r\n },\r\n compareParams: function (fp, sp, sym) { //比较两个字符串或者数字的大小,支持比较对象,暂不支持数组\r\n let flag = false;\r\n\r\n //判断a和b的数据类型\r\n let classNameA = toString.call(fp),\r\n classNameB = toString.call(sp);\r\n\r\n if (sym == \">\" && fp > sp) {\r\n flag = true;\r\n }\r\n else if (sym == \">=\" && fp >= sp) {\r\n flag = true;\r\n }\r\n else if (sym == \"<\" && fp < sp) {\r\n flag = true;\r\n }\r\n else if (sym == \"<=\" && fp <= sp) {\r\n flag = true;\r\n }\r\n else if (sym == \"=\" && fp == sp) {\r\n flag = true;\r\n }\r\n else if (sym == \"<>\" && fp != sp) {\r\n flag = true;\r\n }\r\n\r\n //对象类型比较相等\r\n if (classNameA == '[object Object]' && classNameB == '[object Object]') {\r\n //获取a和b的属性长度\r\n let propsA = Object.getOwnPropertyNames(fp),\r\n propsB = Object.getOwnPropertyNames(sp);\r\n\r\n if (propsA.length != propsB.length) {\r\n return false;\r\n }\r\n\r\n for (let i = 0; i < propsA.length; i++) {\r\n let propName = propsA[i];\r\n //如果对应属性对应值不相等,则返回false\r\n if (fp[propName] !== sp[propName]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n //数组类型\r\n if (classNameA == '[object Array]' && classNameB == '[object Array]') {\r\n if (fp.toString() == sp.toString()) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n return flag;\r\n },\r\n parseDecimal: function (num) {\r\n num = parseFloat(num);\r\n let d = parseInt(num, 10);\r\n\r\n if (d == 0) {\r\n return num;\r\n }\r\n\r\n num = num % d;\r\n return num;\r\n },\r\n getcellrange: function (txt, formulaIndex) {\r\n if (txt == null || txt.length == 0) {\r\n return;\r\n }\r\n\r\n let sheettxt = \"\",\r\n rangetxt = \"\",\r\n sheetIndex = null,\r\n sheetdata = null;\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n\r\n if (txt.indexOf(\"!\") > -1) {\r\n if (txt in this.cellTextToIndexList) {\r\n return this.cellTextToIndexList[txt];\r\n }\r\n\r\n let val = txt.split(\"!\");\r\n sheettxt = val[0];\r\n rangetxt = val[1];\r\n\r\n sheettxt = sheettxt.replace(/\\\\'/g, \"'\").replace(/''/g, \"'\");\r\n if (sheettxt.substr(0, 1) == \"'\" && sheettxt.substr(sheettxt.length - 1, 1) == \"'\") {\r\n sheettxt = sheettxt.substring(1, sheettxt.length - 1);\r\n }\r\n for (let i in luckysheetfile) {\r\n if (sheettxt == luckysheetfile[i].name) {\r\n sheetIndex = luckysheetfile[i].index;\r\n sheetdata = luckysheetfile[i].data;\r\n break;\r\n }\r\n }\r\n }\r\n else {\r\n let i = formulaIndex;\r\n if (i == null) {\r\n i = Store.currentSheetIndex;\r\n }\r\n if (txt + \"_\" + i in this.cellTextToIndexList) {\r\n return this.cellTextToIndexList[txt + \"_\" + i];\r\n }\r\n let index = getSheetIndex(i);\r\n sheettxt = luckysheetfile[index].name;\r\n sheetIndex = luckysheetfile[index].index;\r\n sheetdata = Store.flowdata;\r\n rangetxt = txt;\r\n }\r\n\r\n if (rangetxt.indexOf(\":\") == -1) {\r\n let row = parseInt(rangetxt.replace(/[^0-9]/g, \"\")) - 1;\r\n let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, \"\"));\r\n\r\n if (!isNaN(row) && !isNaN(col)) {\r\n let item = {\r\n \"row\": [row, row],\r\n \"column\": [col, col],\r\n \"sheetIndex\": sheetIndex\r\n };\r\n this.addToCellIndexList(txt, item);\r\n return item;\r\n }\r\n else {\r\n return null;\r\n }\r\n }\r\n else {\r\n rangetxt = rangetxt.split(\":\");\r\n let row = [], col = [];\r\n row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, \"\")) - 1;\r\n row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, \"\")) - 1;\r\n if (isNaN(row[0])) {\r\n row[0] = 0;\r\n }\r\n if (isNaN(row[1])) {\r\n row[1] = sheetdata.length - 1;\r\n }\r\n if (row[0] > row[1]) {\r\n return null;\r\n }\r\n col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, \"\"));\r\n col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, \"\"));\r\n if (isNaN(col[0])) {\r\n col[0] = 0;\r\n }\r\n if (isNaN(col[1])) {\r\n col[1] = sheetdata[0].length - 1;\r\n }\r\n if (col[0] > col[1]) {\r\n return null;\r\n }\r\n\r\n let item = {\r\n \"row\": row,\r\n \"column\": col,\r\n \"sheetIndex\": sheetIndex\r\n };\r\n this.addToCellIndexList(txt, item);\r\n return item;\r\n }\r\n },\r\n rangeHightlightHTML: '
',\r\n createRangeHightlight: function () {\r\n let _this = this;\r\n\r\n let $span = $(\"#luckysheet-rich-text-editor\").find(\"span.luckysheet-formula-functionrange-cell\");\r\n $(\"#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight\").remove();\r\n\r\n $span.each(function () {\r\n let rangeindex = $(this).attr(\"rangeindex\"),\r\n range = $(this).text();\r\n\r\n $(\"#luckysheet-formula-functionrange\").append(replaceHtml(_this.rangeHightlightHTML, {\r\n \"id\": rangeindex\r\n }));\r\n\r\n let cellrange = _this.getcellrange(range);\r\n let rangeid = \"luckysheet-formula-functionrange-highlight-\" + rangeindex;\r\n\r\n if (cellrange == null) {\r\n\r\n }\r\n else if (cellrange.sheetIndex == Store.currentSheetIndex || (cellrange.sheetIndex == -1 && _this.rangetosheet == Store.currentSheetIndex)) {\r\n $(\"#\" + rangeid).data(\"range\", cellrange)\r\n .find(\".luckysheet-copy\")\r\n .css({ \"background\": luckyColor[rangeindex] })\r\n .end()\r\n .find(\".luckysheet-highlight\")\r\n .css({ \"background\": luckyColor[rangeindex] })\r\n .end()\r\n .find(\".luckysheet-selection-copy-hc\")\r\n .css({ \"background\": luckyColor[rangeindex] });\r\n\r\n seletedHighlistByindex(rangeid, cellrange.row[0], cellrange.row[1], cellrange.column[0], cellrange.column[1]);\r\n }\r\n });\r\n\r\n $(\"#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight\").show();\r\n },\r\n searchHTML: '
',\r\n helpHTML: '
SUM ( A2:A100, 101 )
${helpExample}
SUM ( A2:A100, 101 )
${helpAbstract}
${helpAbstract}
${param}
',\r\n getrangeseleciton: function () {\r\n let currSelection = window.getSelection();\r\n let anchor = $(currSelection.anchorNode);\r\n let anchorOffset = currSelection.anchorOffset;\r\n\r\n if (anchor.parent().is(\"span\") && anchorOffset != 0) {\r\n let txt = $.trim(anchor.text()),\r\n lasttxt = \"\";\r\n\r\n if (txt.length == 0 && anchor.parent().prev().length > 0) {\r\n let ahr = anchor.parent().prev();\r\n txt = $.trim(ahr.text());\r\n lasttxt = txt.substr(txt.length - 1, 1);\r\n return ahr;\r\n }\r\n else {\r\n lasttxt = txt.substr(anchorOffset - 1, 1);\r\n return anchor.parent();\r\n }\r\n }\r\n else if (anchor.is(\"#luckysheet-rich-text-editor\") || anchor.is(\"#luckysheet-functionbox-cell\")) {\r\n let txt = $.trim(anchor.find(\"span\").last().text());\r\n\r\n if (txt.length == 0 && anchor.find(\"span\").length > 1) {\r\n let ahr = anchor.find(\"span\");\r\n txt = $.trim(ahr.eq(ahr.length - 2).text());\r\n return ahr;\r\n }\r\n else {\r\n return anchor.find(\"span\").last();\r\n }\r\n }\r\n else if (anchor.parent().is(\"#luckysheet-rich-text-editor\") || anchor.parent().is(\"#luckysheet-functionbox-cell\") || anchorOffset == 0) {\r\n if (anchorOffset == 0) {\r\n anchor = anchor.parent();\r\n }\r\n\r\n if (anchor.prev().length > 0) {\r\n let txt = $.trim(anchor.prev().text());\r\n let lasttxt = txt.substr(txt.length - 1, 1);\r\n return anchor.prev();\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n searchFunctionPosition: function ($menu, $editor, x, y, isparam) {\r\n let winH = $(window).height(),\r\n winW = $(window).width();\r\n let menuW = $menu.outerWidth(),\r\n menuH = $menu.outerHeight();\r\n\r\n if (isparam == null) {\r\n isparam = false;\r\n }\r\n\r\n let left = x;\r\n if (x + menuW > winW) {\r\n left = x - menuW + $editor.outerWidth();\r\n }\r\n else {\r\n left = x;\r\n }\r\n\r\n let top = y;\r\n if (y + menuH > winH) {\r\n top = y - menuH;\r\n }\r\n else {\r\n top = y + $editor.outerHeight();\r\n if (!isparam) {\r\n $menu.html($menu.find(\".luckysheet-formula-search-item\").get().reverse());\r\n }\r\n }\r\n\r\n if (top < 0) {\r\n top = 0;\r\n }\r\n if (left < 0) {\r\n left = 0;\r\n }\r\n\r\n $menu.css({\r\n \"top\": top,\r\n \"left\": left\r\n }).show();\r\n },\r\n searchFunctionCell: null,\r\n searchFunction: function ($editer) {\r\n let _this = this;\r\n let functionlist = Store.functionlist;\r\n\r\n let $cell = _this.getrangeseleciton();\r\n _this.searchFunctionCell = $cell;\r\n\r\n\r\n\r\n if ($cell == null || $editer == null) {\r\n return;\r\n }\r\n let inputContent = $editer.text();\r\n let searchtxt = $cell.text().toUpperCase();\r\n let reg = /^[a-zA-Z]|[a-zA-Z_]+$/;\r\n\r\n if (!reg.test(searchtxt) || inputContent.substr(0, 1) != \"=\") {\r\n return;\r\n }\r\n\r\n let result = {\r\n \"f\": [],\r\n \"s\": [],\r\n \"t\": []\r\n },\r\n result_i = 0;\r\n\r\n for (let i = 0; i < functionlist.length; i++) {\r\n let item = functionlist[i],\r\n n = item.n;\r\n\r\n if (n == searchtxt) {\r\n result.f.unshift(item);\r\n result_i++;\r\n }\r\n else if (n.substr(0, searchtxt.length) == searchtxt) {\r\n result.s.unshift(item);\r\n result_i++;\r\n }\r\n else if (n.indexOf(searchtxt) > -1) {\r\n result.t.unshift(item);\r\n result_i++;\r\n }\r\n\r\n if (result_i >= 10) {\r\n break;\r\n }\r\n }\r\n\r\n let list = result.t.concat(result.s.concat(result.f));\r\n if (list.length <= 0) {\r\n return;\r\n }\r\n\r\n let listHTML = _this.searchFunctionHTML(list);\r\n $(\"#luckysheet-formula-search-c\").html(listHTML).show();\r\n $(\"#luckysheet-formula-help-c\").hide();\r\n\r\n let $c = $editer.parent(),\r\n offset = $c.offset();\r\n _this.searchFunctionPosition($(\"#luckysheet-formula-search-c\"), $c, offset.left, offset.top);\r\n },\r\n searchFunctionEnter: function ($obj) {\r\n let _this = this;\r\n\r\n let functxt = $obj.data(\"func\");\r\n _this.searchFunctionCell.text(functxt).after('(');\r\n _this.setCaretPosition(_this.searchFunctionCell.next().get(0), 0, 1);\r\n $(\"#luckysheet-formula-search-c\").hide();\r\n _this.helpFunctionExe(_this.searchFunctionCell.closest(\"div\"), _this.searchFunctionCell.next());\r\n },\r\n searchFunctionHTML: function (list) {\r\n let _this = this;\r\n\r\n if ($(\"#luckysheet-formula-search-c\").length == 0) {\r\n $(\"body\").append(_this.searchHTML);\r\n $(\"#luckysheet-formula-search-c\").on(\"mouseover\", \".luckysheet-formula-search-item\", function () {\r\n $(\"#luckysheet-formula-search-c\").find(\".luckysheet-formula-search-item\").removeClass(\"luckysheet-formula-search-item-active\");\r\n $(this).addClass(\"luckysheet-formula-search-item-active\");\r\n }).on(\"mouseout\", \".luckysheet-formula-search-item\", function () {\r\n\r\n }).on(\"click\", \".luckysheet-formula-search-item\", function () {\r\n if (_this.searchFunctionCell == null) {\r\n return;\r\n }\r\n _this.searchFunctionEnter($(this));\r\n });\r\n }\r\n\r\n let itemHTML = '
${n}
${a}
';\r\n let retHTML = \"\";\r\n\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n\r\n if (i == list.length - 1) {\r\n retHTML += replaceHtml(itemHTML, {\r\n \"class\": \"luckysheet-formula-search-item-active\",\r\n \"n\": item.n,\r\n \"a\": item.a\r\n });\r\n }\r\n else {\r\n retHTML += replaceHtml(itemHTML, {\r\n \"class\": \"\",\r\n \"n\": item.n,\r\n \"a\": item.a\r\n });\r\n }\r\n }\r\n\r\n return retHTML;\r\n },\r\n functionlistPosition: {},\r\n helpFunction: function ($editer, funcname, paramIndex) {\r\n let _this = this;\r\n let functionlist = Store.functionlist;\r\n\r\n let $func = functionlist[_this.functionlistPosition[$.trim(funcname).toUpperCase()]];\r\n if ($func == null) {\r\n return;\r\n }\r\n\r\n let _locale = locale();\r\n let locale_formulaMore = _locale.formulaMore;\r\n\r\n $(\"#luckysheet-formula-help-c .luckysheet-arguments-help-function-name\").html($func.n);\r\n $(\"#luckysheet-formula-help-c .luckysheet-arguments-help-parameter-content\").html($func.d);\r\n\r\n let helpformula = '${name} ( ${param} )';\r\n let helpformulaItem = '${param}';\r\n let helpformulaArg = '
${param}
${content}
';\r\n\r\n //\"n\": \"AVERAGE\",\r\n //\"t\": \"1\",\r\n //\"d\": \"返回数据集的算术平均值,对文本忽略不计。\",\r\n //\"a\": \"返回数据集的算术平均值\",\r\n //\"p\": [{ \"name\": \"数值1\", \"example\": \"A2:A100\", \"detail\": \"计算平均值时用到的第一个数值或范围。\", \"require\": \"m\", \"repeat\": \"n\", \"type\": \"rangenumber\" },\r\n // { \"name\": \"数值2\", \"example\": \"B2:B100\", \"detail\": \"计算平均值时用到的其他数值或范围。\", \"require\": \"o\", \"repeat\": \"y\", \"type\": \"rangenumber\" }\r\n //]\r\n let fht = \"\",\r\n ahf = \"\",\r\n fhcp = \"\";\r\n\r\n for (let i = 0; i < $func.p.length; i++) {\r\n let paramitem = $func.p[i];\r\n let name = paramitem.name,\r\n nameli = paramitem.name;\r\n\r\n if (paramitem.repeat == \"y\") {\r\n name += \", ...\";\r\n nameli += '...-' + locale_formulaMore.allowRepeatText + '';\r\n }\r\n if (paramitem.require == \"o\") {\r\n name = \"[\" + name + \"]\";\r\n nameli += '-[' + locale_formulaMore.allowOptionText + ']';\r\n }\r\n\r\n fht += '' + name + ', ';\r\n ahf += '' + paramitem.example + ', ';\r\n fhcp += replaceHtml(helpformulaArg, {\r\n \"param\": nameli,\r\n \"content\": paramitem.detail\r\n });\r\n }\r\n\r\n fht = fht.substr(0, fht.length - 2);\r\n ahf = ahf.substr(0, ahf.length - 2);\r\n\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-title .luckysheet-arguments-parameter-holder\").html(fht); //介绍\r\n $(\"#luckysheet-formula-help-c .luckysheet-arguments-help-formula .luckysheet-arguments-parameter-holder\").html(ahf); //示例\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-content-param\").html(fhcp); //参数\r\n\r\n if (paramIndex == null) {\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-title-formula .luckysheet-arguments-help-function-name\").css(\"font-weight\", \"bold\");\r\n }\r\n else {\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-title-formula .luckysheet-arguments-help-function-name\").css(\"font-weight\", \"normal\");\r\n let index = paramIndex >= $func.p.length ? $func.p.length - 1 : paramIndex;\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-title .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter\").removeClass(\"luckysheet-arguments-help-parameter-active\");\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-title .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter\").eq(index).addClass(\"luckysheet-arguments-help-parameter-active\");\r\n $(\"#luckysheet-formula-help-c .luckysheet-arguments-help-formula .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter\").removeClass(\"luckysheet-arguments-help-parameter-active\");\r\n $(\"#luckysheet-formula-help-c .luckysheet-arguments-help-formula .luckysheet-arguments-parameter-holder .luckysheet-arguments-help-parameter\").eq(index).addClass(\"luckysheet-arguments-help-parameter-active\");\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-content-param .luckysheet-arguments-help-section\").removeClass(\"luckysheet-arguments-help-parameter-active\");\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-content-param .luckysheet-arguments-help-section\").eq(index).addClass(\"luckysheet-arguments-help-parameter-active\");\r\n }\r\n\r\n let $c = $editer.parent(),\r\n offset = $c.offset();\r\n _this.searchFunctionPosition($(\"#luckysheet-formula-help-c\"), $c, offset.left, offset.top, true);\r\n },\r\n helpFunctionExe: function ($editer, currSelection) {\r\n let _this = this;\r\n let functionlist = Store.functionlist;\r\n let _locale = locale();\r\n let locale_formulaMore = _locale.formulaMore;\r\n if ($(\"#luckysheet-formula-help-c\").length == 0) {\r\n $(\"body\").after(replaceHtml(_this.helpHTML, {\r\n helpClose: locale_formulaMore.helpClose,\r\n helpCollapse: locale_formulaMore.helpCollapse,\r\n helpExample: locale_formulaMore.helpExample,\r\n helpAbstract: locale_formulaMore.helpAbstract,\r\n }));\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-close\").click(function () {\r\n $(\"#luckysheet-formula-help-c\").hide();\r\n });\r\n $(\"#luckysheet-formula-help-c .luckysheet-formula-help-collapse\").click(function () {\r\n let $content = $(\"#luckysheet-formula-help-c .luckysheet-formula-help-content\");\r\n $content.slideToggle(100, function () {\r\n let $c = _this.rangeResizeTo.parent(),\r\n offset = $c.offset();\r\n _this.searchFunctionPosition($(\"#luckysheet-formula-help-c\"), $c, offset.left, offset.top, true);\r\n });\r\n\r\n if ($content.is(\":hidden\")) {\r\n $(this).html('');\r\n }\r\n else {\r\n $(this).html('');\r\n }\r\n });\r\n\r\n for (let i = 0; i < functionlist.length; i++) {\r\n _this.functionlistPosition[functionlist[i].n] = i;\r\n }\r\n }\r\n\r\n if (!currSelection) {\r\n return;\r\n }\r\n\r\n let $prev = currSelection,\r\n funcLen = $editer.length,\r\n $span = $editer.find(\"span\"),\r\n currentIndex = currSelection.index(),\r\n i = currentIndex;\r\n\r\n if ($prev == null) {\r\n return;\r\n }\r\n\r\n let funcName = null, paramindex = null;\r\n\r\n if ($span.eq(i).is(\".luckysheet-formula-text-func\")) {\r\n funcName = $span.eq(i).text();\r\n }\r\n else {\r\n let $cur = null, exceptIndex = [-1, -1];\r\n\r\n while (--i > 0) {\r\n $cur = $span.eq(i);\r\n\r\n if ($cur.is(\".luckysheet-formula-text-func\") || $.trim($cur.text()).toUpperCase() in _this.functionlistPosition) {\r\n funcName = $cur.text();\r\n paramindex = null;\r\n let endstate = true;\r\n\r\n for (let a = i; a <= currentIndex; a++) {\r\n if (!paramindex) {\r\n paramindex = 0;\r\n }\r\n\r\n if (a >= exceptIndex[0] && a <= exceptIndex[1]) {\r\n continue;\r\n }\r\n\r\n $cur = $span.eq(a);\r\n if ($cur.is(\".luckysheet-formula-text-rpar\")) {\r\n exceptIndex = [i, a];\r\n funcName = null;\r\n endstate = false;\r\n break;\r\n }\r\n\r\n if ($cur.is(\".luckysheet-formula-text-comma\")) {\r\n paramindex++;\r\n }\r\n }\r\n\r\n if (endstate) {\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (funcName == null) {\r\n return;\r\n }\r\n\r\n _this.helpFunction($editer, funcName, paramindex);\r\n },\r\n rangeHightlightselected: function ($editer, kcode) {\r\n let _this = this;\r\n\r\n let currSelection = _this.getrangeseleciton();\r\n $(\"#luckysheet-formula-search-c, #luckysheet-formula-help-c\").hide();\r\n $(\"#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight .luckysheet-selection-copy-hc\").css(\"opacity\", \"0.03\");\r\n $(\"#luckysheet-formula-search-c, #luckysheet-formula-help-c\").hide();\r\n _this.helpFunctionExe($editer, currSelection);\r\n\r\n // console.log(currSelection, $(currSelection).closest(\".luckysheet-formula-functionrange-cell\").length);\r\n if ($(currSelection).closest(\".luckysheet-formula-functionrange-cell\").length == 0) {\r\n _this.searchFunction($editer);\r\n return;\r\n }\r\n\r\n let $anchorOffset = $(currSelection).closest(\".luckysheet-formula-functionrange-cell\");\r\n let rangeindex = $anchorOffset.attr(\"rangeindex\");\r\n let rangeid = \"luckysheet-formula-functionrange-highlight-\" + rangeindex;\r\n\r\n $(\"#\" + rangeid).find(\".luckysheet-selection-copy-hc\").css({\r\n \"opacity\": \"0.13\"\r\n });\r\n },\r\n updatecell: function (r, c, value, isRefresh = true) {\r\n\r\n let _this = this;\r\n\r\n let $input = $(\"#luckysheet-rich-text-editor\");\r\n let inputText = $input.text(), inputHtml = $input.html();\r\n\r\n\r\n if (_this.rangetosheet != null && _this.rangetosheet != Store.currentSheetIndex) {\r\n sheetmanage.changeSheetExec(_this.rangetosheet);\r\n }\r\n\r\n if (!checkProtectionLocked(r, c, Store.currentSheetIndex)) {\r\n return;\r\n }\r\n\r\n //数据验证 输入数据无效时禁止输入\r\n if (dataVerificationCtrl.dataVerification != null) {\r\n let dvItem = dataVerificationCtrl.dataVerification[r + '_' + c];\r\n\r\n if (dvItem != null && dvItem.prohibitInput && !dataVerificationCtrl.validateCellData(inputText, dvItem)) {\r\n let failureText = dataVerificationCtrl.getFailureText(dvItem);\r\n tooltip.info(failureText, '');\r\n _this.cancelNormalSelected();\r\n return;\r\n }\r\n }\r\n\r\n let curv = Store.flowdata[r][c];\r\n\r\n // Store old value for hook function\r\n const oldValue = JSON.stringify(curv);\r\n\r\n let isPrevInline = isInlineStringCell(curv);\r\n let isCurInline = (inputText.slice(0, 1) != \"=\" && inputHtml.substr(0, 5) == \" 0) {\r\n let splitArr = inputText.replace(/\\r\\n/g, \"_x000D_\").replace(/ /g, \"_x000D_\").replace(/\\r/g, \"_x000D_\").replace(/\\n/g, \"_x000D_\").split(\"_x000D_\");\r\n if(splitArr.length > 1) {\r\n isCopyVal = true;\r\n isCurInline = true;\r\n inputText = splitArr.join('\\r\\n');\r\n }\r\n }\r\n\r\n if (!value && !isCurInline && isPrevInline) {\r\n delete curv.ct.s;\r\n curv.ct.t = \"g\";\r\n curv.ct.fa = \"General\";\r\n value = \"\";\r\n }\r\n else if (isCurInline) {\r\n if (getObjType(curv) != \"object\") {\r\n curv = {};\r\n }\r\n delete curv.f;\r\n delete curv.v;\r\n delete curv.m;\r\n\r\n if (curv.ct == null) {\r\n curv.ct = {};\r\n curv.ct.fa = \"General\";\r\n }\r\n\r\n curv.ct.t = \"inlineStr\";\r\n curv.ct.s = convertSpanToShareString($input.find(\"span\"));\r\n if(isCopyVal) {\r\n curv.ct.s = [\r\n {\r\n v: inputText,\r\n }\r\n ];\r\n }\r\n }\r\n\r\n // API, we get value from user\r\n value = value || $input.text();\r\n\r\n // Hook function\r\n if (!method.createHookFunction(\"cellUpdateBefore\", r, c, value, isRefresh)) {\r\n _this.cancelNormalSelected();\r\n return;\r\n }\r\n\r\n if (!isCurInline) {\r\n if (isRealNull(value) && !isPrevInline) {\r\n if (curv == null || (isRealNull(curv.v) && curv.spl == null && curv.f == null)) {\r\n _this.cancelNormalSelected();\r\n return;\r\n }\r\n }\r\n else if (curv != null && curv.qp != 1) {\r\n if (getObjType(curv) == \"object\" && (value == curv.f || value == curv.v || value == curv.m)) {\r\n _this.cancelNormalSelected();\r\n return;\r\n }\r\n else if (value == curv) {\r\n _this.cancelNormalSelected();\r\n return;\r\n }\r\n }\r\n\r\n if (getObjType(value) == \"string\" && value.slice(0, 1) == \"=\" && value.length > 1) {\r\n\r\n }\r\n else if (getObjType(curv) == \"object\" && curv.ct != null && curv.ct.fa != null && curv.ct.fa != \"@\" && !isRealNull(value)) {\r\n delete curv.m;//更新时间m处理 , 会实际删除单元格数据的参数(flowdata时已删除)\r\n if (curv.f != null) { //如果原来是公式,而更新的数据不是公式,则把公式删除\r\n delete curv.f;\r\n delete curv.spl; //删除单元格的sparklines的配置串\r\n }\r\n }\r\n }\r\n\r\n window.luckysheet_getcelldata_cache = null;\r\n\r\n let isRunExecFunction = true;\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let dynamicArrayItem = null; //动态数组\r\n\r\n if (getObjType(curv) == \"object\") {\r\n\r\n if (!isCurInline) {\r\n\r\n if (getObjType(value) == \"string\" && value.slice(0, 1) == \"=\" && value.length > 1) {\r\n let v = _this.execfunction(value, r, c, undefined, true);\r\n isRunExecFunction = false;\r\n curv = $.extend(true, {}, d[r][c]);\r\n curv.v = v[1];\r\n curv.f = v[2];\r\n\r\n //打进单元格的sparklines的配置串, 报错需要单独处理。\r\n if (v.length == 4 && v[3].type == \"sparklines\") {\r\n delete curv.m;\r\n delete curv.v;\r\n\r\n let curCalv = v[3].data;\r\n\r\n if (getObjType(curCalv) == \"array\" && getObjType(curCalv[0]) != \"object\") {\r\n curv.v = curCalv[0];\r\n }\r\n else {\r\n curv.spl = v[3].data;\r\n }\r\n }\r\n else if (v.length == 4 && v[3].type == \"dynamicArrayItem\") {\r\n dynamicArrayItem = v[3].data;\r\n }\r\n }\r\n // from API setCellValue,luckysheet.setCellValue(0, 0, {f: \"=sum(D1)\", bg:\"#0188fb\"}),value is an object, so get attribute f as value\r\n else if (getObjType(value) == \"object\") {\r\n let valueFunction = value.f;\r\n\r\n if (getObjType(valueFunction) == \"string\" && valueFunction.slice(0, 1) == \"=\" && valueFunction.length > 1) {\r\n let v = _this.execfunction(valueFunction, r, c, undefined, true);\r\n isRunExecFunction = false;\r\n // get v/m/ct\r\n\r\n curv = $.extend(true, {}, d[r][c]);\r\n curv.v = v[1];\r\n curv.f = v[2];\r\n\r\n //打进单元格的sparklines的配置串, 报错需要单独处理。\r\n if (v.length == 4 && v[3].type == \"sparklines\") {\r\n delete curv.m;\r\n delete curv.v;\r\n\r\n let curCalv = v[3].data;\r\n\r\n if (getObjType(curCalv) == \"array\" && getObjType(curCalv[0]) != \"object\") {\r\n curv.v = curCalv[0];\r\n }\r\n else {\r\n curv.spl = v[3].data;\r\n }\r\n }\r\n else if (v.length == 4 && v[3].type == \"dynamicArrayItem\") {\r\n dynamicArrayItem = v[3].data;\r\n }\r\n }\r\n // from API setCellValue,luckysheet.setCellValue(0, 0, {f: \"=sum(D1)\", bg:\"#0188fb\"}),value is an object, so get attribute f as value\r\n else {\r\n for (let attr in value) {\r\n curv[attr] = value[attr];\r\n }\r\n // let valueFunction = value.f;\r\n\r\n // if(getObjType(valueFunction) == \"string\" && valueFunction.slice(0, 1) == \"=\" && valueFunction.length > 1){\r\n // let v = _this.execfunction(valueFunction, r, c, undefined, true);\r\n // isRunExecFunction = false;\r\n // // get v/m/ct\r\n // curv = d[r][c];\r\n // curv.v = v[1];\r\n // // get f\r\n // curv.f = v[2];\r\n\r\n // // get other cell style attribute\r\n // delete value.v;\r\n // delete value.m;\r\n // delete value.f;\r\n // Object.assign(curv,value);\r\n\r\n // //打进单元格的sparklines的配置串, 报错需要单独处理。\r\n // if(v.length == 4 && v[3].type == \"sparklines\"){\r\n // delete curv.m;\r\n // delete curv.v;\r\n\r\n // let curCalv = v[3].data;\r\n\r\n // if(getObjType(curCalv) == \"array\" && getObjType(curCalv[0]) != \"object\"){\r\n // curv.v = curCalv[0];\r\n // }\r\n // else{\r\n // curv.spl = v[3].data;\r\n // }\r\n // }\r\n // }\r\n\r\n }\r\n\r\n }\r\n else {\r\n _this.delFunctionGroup(r, c);\r\n _this.execFunctionGroup(r, c, value);\r\n isRunExecFunction = false;\r\n\r\n curv = $.extend(true, {}, d[r][c]);\r\n // let gd = _this.execFunctionGlobalData[r+\"_\"+c+\"_\"+Store.currentSheetIndex];\r\n // if(gd!=null){\r\n // curv.v = gd.v;\r\n // }\r\n curv.v = value;\r\n\r\n delete curv.f;\r\n delete curv.spl;\r\n\r\n if (curv.qp == 1 && ('' + value).substr(0, 1) != \"'\") {//if quotePrefix is 1, cell is force string, cell clear quotePrefix when it is updated\r\n curv.qp = 0;\r\n if (curv.ct != null) {\r\n curv.ct.fa = \"General\";\r\n curv.ct.t = \"n\";\r\n }\r\n }\r\n }\r\n }\r\n value = curv;\r\n }\r\n else {\r\n if (getObjType(value) == \"string\" && value.slice(0, 1) == \"=\" && value.length > 1) {\r\n let v = _this.execfunction(value, r, c, undefined, true);\r\n isRunExecFunction = false;\r\n value = {\r\n \"v\": v[1],\r\n \"f\": v[2]\r\n };\r\n\r\n\r\n //打进单元格的sparklines的配置串, 报错需要单独处理。\r\n if (v.length == 4 && v[3].type == \"sparklines\") {\r\n let curCalv = v[3].data;\r\n\r\n if (getObjType(curCalv) == \"array\" && getObjType(curCalv[0]) != \"object\") {\r\n value.v = curCalv[0];\r\n }\r\n else {\r\n value.spl = v[3].data;\r\n }\r\n }\r\n else if (v.length == 4 && v[3].type == \"dynamicArrayItem\") {\r\n dynamicArrayItem = v[3].data;\r\n }\r\n }\r\n // from API setCellValue,luckysheet.setCellValue(0, 0, {f: \"=sum(D1)\", bg:\"#0188fb\"}),value is an object, so get attribute f as value\r\n else if (getObjType(value) == \"object\") {\r\n let valueFunction = value.f;\r\n\r\n if (getObjType(valueFunction) == \"string\" && valueFunction.slice(0, 1) == \"=\" && valueFunction.length > 1) {\r\n let v = _this.execfunction(valueFunction, r, c, undefined, true);\r\n isRunExecFunction = false;\r\n // value = {\r\n // \"v\": v[1],\r\n // \"f\": v[2]\r\n // };\r\n\r\n // update attribute v\r\n value.v = v[1];\r\n value.f = v[2];\r\n\r\n //打进单元格的sparklines的配置串, 报错需要单独处理。\r\n if (v.length == 4 && v[3].type == \"sparklines\") {\r\n let curCalv = v[3].data;\r\n\r\n if (getObjType(curCalv) == \"array\" && getObjType(curCalv[0]) != \"object\") {\r\n value.v = curCalv[0];\r\n }\r\n else {\r\n value.spl = v[3].data;\r\n }\r\n }\r\n else if (v.length == 4 && v[3].type == \"dynamicArrayItem\") {\r\n dynamicArrayItem = v[3].data;\r\n }\r\n }\r\n else {\r\n let v = curv;\r\n if (value.v == null) {\r\n value.v = v;\r\n }\r\n }\r\n\r\n }\r\n else {\r\n _this.delFunctionGroup(r, c);\r\n _this.execFunctionGroup(r, c, value);\r\n isRunExecFunction = false;\r\n }\r\n }\r\n\r\n // value maybe an object\r\n setcellvalue(r, c, d, value);\r\n _this.cancelNormalSelected();\r\n\r\n let RowlChange = false;\r\n let cfg = $.extend(true, {}, getluckysheetfile()[getSheetIndex(Store.currentSheetIndex)][\"config\"]);\r\n if (cfg[\"rowlen\"] == null) {\r\n cfg[\"rowlen\"] = {};\r\n }\r\n\r\n if ((d[r][c].tb == \"2\" && d[r][c].v != null) || isInlineStringCell(d[r][c])) {//自动换行\r\n let defaultrowlen = Store.defaultrowlen;\r\n\r\n let canvas = $(\"#luckysheetTableContent\").get(0).getContext(\"2d\");\r\n // offlinecanvas.textBaseline = 'top'; //textBaseline以top计算\r\n\r\n // let fontset = luckysheetfontformat(d[r][c]);\r\n // offlinecanvas.font = fontset;\r\n\r\n if (cfg[\"customHeight\"] && cfg[\"customHeight\"][r] == 1) {\r\n\r\n }\r\n else {\r\n // let currentRowLen = defaultrowlen;\r\n // if(cfg[\"rowlen\"][r] != null){\r\n // currentRowLen = cfg[\"rowlen\"][r];\r\n // }\r\n\r\n let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 2;\r\n\r\n let textInfo = getCellTextInfo(d[r][c], canvas, {\r\n r: r,\r\n c: c,\r\n cellWidth: cellWidth\r\n });\r\n\r\n let currentRowLen = defaultrowlen;\r\n // console.log(\"rowlen\", textInfo);\r\n if (textInfo != null) {\r\n currentRowLen = textInfo.textHeightAll + 2;\r\n }\r\n\r\n // let strValue = getcellvalue(r, c, d).toString();\r\n // let measureText = offlinecanvas.measureText(strValue);\r\n\r\n // let textMetrics = measureText.width;\r\n // let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 4;\r\n // let oneLineTextHeight = measureText.actualBoundingBoxDescent - measureText.actualBoundingBoxAscent;\r\n\r\n // if(textMetrics > cellWidth){\r\n // let strArr = [];//文本截断数组\r\n // strArr = getCellTextSplitArr(strValue, strArr, cellWidth, offlinecanvas);\r\n\r\n // let computeRowlen = oneLineTextHeight * strArr.length + 4;\r\n // //比较计算高度和当前高度取最大高度\r\n // if(computeRowlen > currentRowLen){\r\n // currentRowLen = computeRowlen;\r\n // }\r\n // }\r\n\r\n if (currentRowLen > defaultrowlen) {\r\n cfg[\"rowlen\"][r] = currentRowLen;\r\n RowlChange = true;\r\n }\r\n }\r\n\r\n }\r\n\r\n //动态数组\r\n let dynamicArray = null;\r\n if (!!dynamicArrayItem) {\r\n // let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)];\r\n dynamicArray = $.extend(true, [], this.insertUpdateDynamicArray(dynamicArrayItem));\r\n // dynamicArray.push(dynamicArrayItem);\r\n\r\n }\r\n\r\n let allParam = {\r\n \"dynamicArray\": dynamicArray\r\n }\r\n\r\n if (RowlChange) {\r\n allParam = {\r\n \"cfg\": cfg,\r\n \"dynamicArray\": dynamicArray,\r\n \"RowlChange\": RowlChange\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n // Hook function\r\n method.createHookFunction(\"cellUpdated\", r, c, JSON.parse(oldValue), Store.flowdata[r][c], isRefresh);\r\n }, 0);\r\n\r\n if (isRefresh) {\r\n jfrefreshgrid(d, [{ \"row\": [r, r], \"column\": [c, c] }], allParam, isRunExecFunction);\r\n // Store.luckysheetCellUpdate.length = 0; //clear array\r\n _this.execFunctionGlobalData = null; //销毁\r\n }\r\n else {\r\n return {\r\n data: d,\r\n allParam: allParam\r\n };\r\n }\r\n },\r\n cancelNormalSelected: function () {\r\n let _this = this;\r\n\r\n _this.canceFunctionrangeSelected();\r\n\r\n $(\"#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight\").remove();\r\n $(\"#luckysheet-input-box\").removeAttr(\"style\");\r\n $(\"#luckysheet-input-box-index\").hide();\r\n $(\"#luckysheet-wa-functionbox-cancel, #luckysheet-wa-functionbox-confirm\").removeClass(\"luckysheet-wa-calculate-active\");\r\n\r\n _this.rangestart = false;\r\n _this.rangedrag_column_start = false;\r\n _this.rangedrag_row_start = false;\r\n },\r\n canceFunctionrangeSelected: function () {\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n $(\"#luckysheet-row-count-show, #luckysheet-column-count-show\").hide();\r\n // $(\"#luckysheet-cols-h-selected, #luckysheet-rows-h-selected\").hide();\r\n $(\"#luckysheet-formula-search-c, #luckysheet-formula-help-c\").hide();\r\n },\r\n iscellformat: function (txt) {\r\n let re_abc = /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][123456789]/;\r\n },\r\n iscelldata: function (txt) { //判断是否为单元格格式\r\n let val = txt.split(\"!\"),\r\n rangetxt;\r\n\r\n if (val.length > 1) {\r\n rangetxt = val[1];\r\n }\r\n else {\r\n rangetxt = val[0];\r\n }\r\n\r\n let reg_cell = /^(([a-zA-Z]+)|([$][a-zA-Z]+))(([0-9]+)|([$][0-9]+))$/g; //增加正则判断单元格为字母+数字的格式:如 A1:B3\r\n let reg_cellRange = /^(((([a-zA-Z]+)|([$][a-zA-Z]+))(([0-9]+)|([$][0-9]+)))|((([a-zA-Z]+)|([$][a-zA-Z]+))))$/g; //增加正则判断单元格为字母+数字或字母的格式:如 A1:B3,A:A\r\n\r\n if (rangetxt.indexOf(\":\") == -1) {\r\n let row = parseInt(rangetxt.replace(/[^0-9]/g, \"\")) - 1;\r\n let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, \"\"));\r\n\r\n if (!isNaN(row) && !isNaN(col) && rangetxt.toString().match(reg_cell)) {\r\n return true;\r\n }\r\n else if (!isNaN(row)) {\r\n return false;\r\n }\r\n else if (!isNaN(col)) {\r\n return false;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n else {\r\n reg_cellRange = /^(((([a-zA-Z]+)|([$][a-zA-Z]+))(([0-9]+)|([$][0-9]+)))|((([a-zA-Z]+)|([$][a-zA-Z]+)))|((([0-9]+)|([$][0-9]+s))))$/g;\r\n\r\n rangetxt = rangetxt.split(\":\");\r\n\r\n let row = [], col = [];\r\n row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, \"\")) - 1;\r\n row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, \"\")) - 1;\r\n if (row[0] > row[1]) {\r\n return false;\r\n }\r\n\r\n col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, \"\"));\r\n col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, \"\"));\r\n if (col[0] > col[1]) {\r\n return false;\r\n }\r\n\r\n if (rangetxt[0].toString().match(reg_cellRange) && rangetxt[1].toString().match(reg_cellRange)) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n },\r\n operator: '==|!=|<>|<=|>=|=|+|-|>|<|/|*|%|&|^',\r\n operatorjson: null,\r\n functionCopy: function (txt, mode, step) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (mode == null) {\r\n mode = \"down\";\r\n }\r\n\r\n if (step == null) {\r\n step = 1;\r\n }\r\n\r\n if (txt.substr(0, 1) == \"=\") {\r\n txt = txt.substr(1);\r\n }\r\n\r\n let funcstack = txt.split(\"\");\r\n let i = 0,\r\n str = \"\",\r\n function_str = \"\",\r\n ispassby = true;\r\n\r\n let matchConfig = {\r\n \"bracket\": 0,\r\n \"comma\": 0,\r\n \"squote\": 0,\r\n \"dquote\": 0\r\n };\r\n\r\n while (i < funcstack.length) {\r\n let s = funcstack[i];\r\n\r\n if (s == \"(\" && matchConfig.dquote == 0) {\r\n matchConfig.bracket += 1;\r\n\r\n if (str.length > 0) {\r\n function_str += str + \"(\";\r\n }\r\n else {\r\n function_str += \"(\";\r\n }\r\n\r\n str = \"\";\r\n }\r\n else if (s == \")\" && matchConfig.dquote == 0) {\r\n matchConfig.bracket -= 1;\r\n function_str += _this.functionCopy(str, mode, step) + \")\";\r\n str = \"\";\r\n }\r\n else if (s == '\"' && matchConfig.squote == 0) {\r\n if (matchConfig.dquote > 0) {\r\n function_str += str + '\"';\r\n matchConfig.dquote -= 1;\r\n str = \"\";\r\n }\r\n else {\r\n matchConfig.dquote += 1;\r\n str += '\"';\r\n }\r\n }\r\n else if (s == ',' && matchConfig.dquote == 0) {\r\n function_str += _this.functionCopy(str, mode, step) + ',';\r\n str = \"\";\r\n }\r\n else if (s == '&' && matchConfig.dquote == 0) {\r\n if (str.length > 0) {\r\n function_str += _this.functionCopy(str, mode, step) + \"&\";\r\n str = \"\";\r\n }\r\n else {\r\n function_str += \"&\";\r\n }\r\n }\r\n else if (s in _this.operatorjson && matchConfig.dquote == 0) {\r\n let s_next = \"\";\r\n\r\n if ((i + 1) < funcstack.length) {\r\n s_next = funcstack[i + 1];\r\n }\r\n\r\n let p = i - 1,\r\n s_pre = null;\r\n\r\n if (p >= 0) {\r\n do {\r\n s_pre = funcstack[p--];\r\n }\r\n while (p >= 0 && s_pre == \" \")\r\n }\r\n\r\n if ((s + s_next) in _this.operatorjson) {\r\n if (str.length > 0) {\r\n function_str += _this.functionCopy(str, mode, step) + s + s_next;\r\n str = \"\";\r\n }\r\n else {\r\n function_str += s + s_next;\r\n }\r\n\r\n i++;\r\n }\r\n else if (!(/[^0-9]/.test(s_next)) && s == \"-\" && (s_pre == \"(\" || s_pre == null || s_pre == \",\" || s_pre == \" \" || s_pre in _this.operatorjson)) {\r\n str += s;\r\n }\r\n else {\r\n if (str.length > 0) {\r\n function_str += _this.functionCopy(str, mode, step) + s;\r\n str = \"\";\r\n }\r\n else {\r\n function_str += s;\r\n }\r\n }\r\n }\r\n else {\r\n str += s;\r\n }\r\n\r\n if (i == funcstack.length - 1) {\r\n if (_this.iscelldata($.trim(str))) {\r\n if (mode == \"down\") {\r\n function_str += _this.downparam($.trim(str), step);\r\n }\r\n else if (mode == \"up\") {\r\n function_str += _this.upparam($.trim(str), step);\r\n }\r\n else if (mode == \"left\") {\r\n function_str += _this.leftparam($.trim(str), step);\r\n }\r\n else if (mode == \"right\") {\r\n function_str += _this.rightparam($.trim(str), step);\r\n }\r\n }\r\n else {\r\n function_str += $.trim(str);\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return function_str;\r\n },\r\n isfreezonFuc: function (txt) {\r\n let row = txt.replace(/[^0-9]/g, \"\");\r\n let col = txt.replace(/[^A-Za-z]/g, \"\");\r\n let row$ = txt.substr(txt.indexOf(row) - 1, 1);\r\n let col$ = txt.substr(txt.indexOf(col) - 1, 1);\r\n let ret = [false, false];\r\n\r\n if (row$ == \"$\") {\r\n ret[0] = true;\r\n }\r\n if (col$ == \"$\") {\r\n ret[1] = true;\r\n }\r\n\r\n return ret;\r\n },\r\n setfreezonFuceExe: function (rangetxt) {\r\n let row = parseInt(rangetxt.replace(/[^0-9]/g, \"\"));\r\n let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, \"\"));\r\n let $row = \"$\",\r\n $col = \"$\";\r\n\r\n if (!isNaN(row) && !isNaN(col)) {\r\n return $col + chatatABC(col) + $row + (row);\r\n }\r\n else if (!isNaN(row)) {\r\n return $row + (row);\r\n }\r\n else if (!isNaN(col)) {\r\n return $col + chatatABC(col);\r\n }\r\n else {\r\n return rangetxt;\r\n }\r\n },\r\n setfreezonFuc: function (event) {\r\n let _this = this;\r\n\r\n let obj = _this.getrangeseleciton();\r\n if (!_this.iscelldata(obj.text())) {\r\n return;\r\n }\r\n\r\n let txt = obj.text(),\r\n pos = window.getSelection().anchorOffset;\r\n let val = txt.split(\"!\"),\r\n rangetxt, prefix = \"\";\r\n\r\n if (val.length > 1) {\r\n rangetxt = val[1];\r\n prefix = val[0] + \"!\";\r\n }\r\n else {\r\n rangetxt = val[0];\r\n }\r\n\r\n let newtxt = \"\",\r\n newpos = \"\";\r\n let rangetxtIndex = rangetxt.indexOf(\":\");\r\n\r\n if (rangetxtIndex == -1) {\r\n newtxt = prefix + _this.setfreezonFuceExe(rangetxt);\r\n newpos = newtxt.length;\r\n }\r\n else {\r\n rangetxt = rangetxt.split(\":\");\r\n\r\n if (pos > rangetxtIndex) {\r\n let ret = prefix + rangetxt[0] + \":\" + _this.setfreezonFuceExe(rangetxt[1]);\r\n newtxt = ret;\r\n newpos = ret.length;\r\n }\r\n else {\r\n let firsttxt = prefix + _this.setfreezonFuceExe(rangetxt[0]);\r\n let ret = firsttxt + \":\" + rangetxt[1];\r\n newtxt = ret;\r\n newpos = firsttxt.length;\r\n }\r\n }\r\n\r\n obj.text(prefix + newtxt);\r\n _this.setCaretPosition(obj.get(0), 0, newpos);\r\n },\r\n updateparam: function (orient, txt, step) {\r\n let _this = this;\r\n\r\n let val = txt.split(\"!\"),\r\n rangetxt, prefix = \"\";\r\n\r\n if (val.length > 1) {\r\n rangetxt = val[1];\r\n prefix = val[0] + \"!\";\r\n }\r\n else {\r\n rangetxt = val[0];\r\n }\r\n\r\n if (rangetxt.indexOf(\":\") == -1) {\r\n let row = parseInt(rangetxt.replace(/[^0-9]/g, \"\"));\r\n let col = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, \"\"));\r\n let freezonFuc = _this.isfreezonFuc(rangetxt);\r\n let $row = freezonFuc[0] ? \"$\" : \"\",\r\n $col = freezonFuc[1] ? \"$\" : \"\";\r\n\r\n if (orient == \"u\" && !freezonFuc[0]) {\r\n row -= step;\r\n }\r\n else if (orient == \"r\" && !freezonFuc[1]) {\r\n col += step;\r\n }\r\n else if (orient == \"l\" && !freezonFuc[1]) {\r\n col -= step;\r\n }\r\n else if (orient == \"d\" && !freezonFuc[0]) {\r\n row += step;\r\n }\r\n\r\n if (row[0] < 0 || col[0] < 0) {\r\n return _this.error.r;\r\n }\r\n\r\n if (!isNaN(row) && !isNaN(col)) {\r\n return prefix + $col + chatatABC(col) + $row + (row);\r\n }\r\n else if (!isNaN(row)) {\r\n return prefix + $row + (row);\r\n }\r\n else if (!isNaN(col)) {\r\n return prefix + $col + chatatABC(col);\r\n }\r\n else {\r\n return txt;\r\n }\r\n }\r\n else {\r\n rangetxt = rangetxt.split(\":\");\r\n let row = [],\r\n col = [];\r\n\r\n row[0] = parseInt(rangetxt[0].replace(/[^0-9]/g, \"\"));\r\n row[1] = parseInt(rangetxt[1].replace(/[^0-9]/g, \"\"));\r\n if (row[0] > row[1]) {\r\n return txt;\r\n }\r\n\r\n col[0] = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, \"\"));\r\n col[1] = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, \"\"));\r\n if (col[0] > col[1]) {\r\n return txt;\r\n }\r\n\r\n let freezonFuc0 = _this.isfreezonFuc(rangetxt[0]);\r\n let freezonFuc1 = _this.isfreezonFuc(rangetxt[1]);\r\n let $row0 = freezonFuc0[0] ? \"$\" : \"\",\r\n $col0 = freezonFuc0[1] ? \"$\" : \"\";\r\n let $row1 = freezonFuc1[0] ? \"$\" : \"\",\r\n $col1 = freezonFuc1[1] ? \"$\" : \"\";\r\n\r\n if (orient == \"u\") {\r\n if (!freezonFuc0[0]) {\r\n row[0] -= step;\r\n }\r\n\r\n if (!freezonFuc1[0]) {\r\n row[1] -= step;\r\n }\r\n }\r\n else if (orient == \"r\") {\r\n if (!freezonFuc0[1]) {\r\n col[0] += step;\r\n }\r\n\r\n if (!freezonFuc1[1]) {\r\n col[1] += step;\r\n }\r\n }\r\n else if (orient == \"l\") {\r\n if (!freezonFuc0[1]) {\r\n col[0] -= step;\r\n }\r\n\r\n if (!freezonFuc1[1]) {\r\n col[1] -= step;\r\n }\r\n }\r\n else if (orient == \"d\") {\r\n if (!freezonFuc0[0]) {\r\n row[0] += step;\r\n }\r\n\r\n if (!freezonFuc1[0]) {\r\n row[1] += step;\r\n }\r\n }\r\n\r\n if (row[0] < 0 || col[0] < 0) {\r\n return _this.error.r;\r\n }\r\n\r\n if (isNaN(col[0]) && isNaN(col[1])) {\r\n return prefix + $row0 + (row[0]) + \":\" + $row1 + (row[1]);\r\n }\r\n else if (isNaN(row[0]) && isNaN(row[1])) {\r\n return prefix + $col0 + chatatABC(col[0]) + \":\" + $col1 + chatatABC(col[1]);\r\n }\r\n else {\r\n return prefix + $col0 + chatatABC(col[0]) + $row0 + (row[0]) + \":\" + $col1 + chatatABC(col[1]) + $row1 + (row[1]);\r\n }\r\n }\r\n },\r\n downparam: function (txt, step) {\r\n return this.updateparam(\"d\", txt, step);\r\n },\r\n upparam: function (txt, step) {\r\n return this.updateparam(\"u\", txt, step);\r\n },\r\n leftparam: function (txt, step) {\r\n return this.updateparam(\"l\", txt, step);\r\n },\r\n rightparam: function (txt, step) {\r\n return this.updateparam(\"r\", txt, step);\r\n },\r\n functionStrChange: function (txt, type, rc, orient, stindex, step) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (txt.substr(0, 1) == \"=\") {\r\n txt = txt.substr(1);\r\n }\r\n\r\n let funcstack = txt.split(\"\");\r\n let i = 0,\r\n str = \"\",\r\n function_str = \"\",\r\n ispassby = true;\r\n\r\n let matchConfig = {\r\n \"bracket\": 0, //括号\r\n \"comma\": 0, //逗号\r\n \"squote\": 0, //单引号\r\n \"dquote\": 0 //双引号\r\n };\r\n\r\n while (i < funcstack.length) {\r\n let s = funcstack[i];\r\n\r\n if (s == \"(\" && matchConfig.dquote == 0) {\r\n matchConfig.bracket += 1;\r\n\r\n if (str.length > 0) {\r\n function_str += str + \"(\";\r\n }\r\n else {\r\n function_str += \"(\";\r\n }\r\n\r\n str = \"\";\r\n }\r\n else if (s == \")\" && matchConfig.dquote == 0) {\r\n matchConfig.bracket -= 1;\r\n function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + \")\";\r\n str = \"\";\r\n }\r\n else if (s == '\"' && matchConfig.squote == 0) {\r\n if (matchConfig.dquote > 0) {\r\n function_str += str + '\"';\r\n matchConfig.dquote -= 1;\r\n str = \"\";\r\n }\r\n else {\r\n matchConfig.dquote += 1;\r\n str += '\"';\r\n }\r\n }\r\n else if (s == ',' && matchConfig.dquote == 0) {\r\n function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + ',';\r\n str = \"\";\r\n }\r\n else if (s == '&' && matchConfig.dquote == 0) {\r\n if (str.length > 0) {\r\n function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + \"&\";\r\n str = \"\";\r\n }\r\n else {\r\n function_str += \"&\";\r\n }\r\n }\r\n else if (s in _this.operatorjson && matchConfig.dquote == 0) {\r\n let s_next = \"\";\r\n\r\n if ((i + 1) < funcstack.length) {\r\n s_next = funcstack[i + 1];\r\n }\r\n\r\n let p = i - 1,\r\n s_pre = null;\r\n\r\n if (p >= 0) {\r\n do {\r\n s_pre = funcstack[p--];\r\n }\r\n while (p >= 0 && s_pre == \" \")\r\n }\r\n\r\n if ((s + s_next) in _this.operatorjson) {\r\n if (str.length > 0) {\r\n function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + s + s_next;\r\n str = \"\";\r\n }\r\n else {\r\n function_str += s + s_next;\r\n }\r\n\r\n i++;\r\n }\r\n else if (!(/[^0-9]/.test(s_next)) && s == \"-\" && (s_pre == \"(\" || s_pre == null || s_pre == \",\" || s_pre == \" \" || s_pre in _this.operatorjson)) {\r\n str += s;\r\n }\r\n else {\r\n if (str.length > 0) {\r\n function_str += _this.functionStrChange(str, type, rc, orient, stindex, step) + s;\r\n str = \"\";\r\n }\r\n else {\r\n function_str += s;\r\n }\r\n }\r\n }\r\n else {\r\n str += s;\r\n }\r\n\r\n if (i == funcstack.length - 1) {\r\n if (_this.iscelldata($.trim(str))) {\r\n function_str += _this.functionStrChange_range($.trim(str), type, rc, orient, stindex, step);\r\n }\r\n else {\r\n function_str += $.trim(str);\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return function_str;\r\n },\r\n functionStrChange_range: function (txt, type, rc, orient, stindex, step) {\r\n let _this = this;\r\n\r\n let val = txt.split(\"!\"),\r\n rangetxt, prefix = \"\";\r\n\r\n if (val.length > 1) {\r\n rangetxt = val[1];\r\n prefix = val[0] + \"!\";\r\n }\r\n else {\r\n rangetxt = val[0];\r\n }\r\n\r\n let r1, r2, c1, c2;\r\n let $row0, $row1, $col0, $col1;\r\n\r\n if (rangetxt.indexOf(\":\") == -1) {\r\n r1 = r2 = parseInt(rangetxt.replace(/[^0-9]/g, \"\")) - 1;\r\n c1 = c2 = ABCatNum(rangetxt.replace(/[^A-Za-z]/g, \"\"));\r\n\r\n let freezonFuc = _this.isfreezonFuc(rangetxt);\r\n\r\n $row0 = $row1 = freezonFuc[0] ? \"$\" : \"\",\r\n $col0 = $col1 = freezonFuc[1] ? \"$\" : \"\";\r\n }\r\n else {\r\n rangetxt = rangetxt.split(\":\");\r\n\r\n r1 = parseInt(rangetxt[0].replace(/[^0-9]/g, \"\")) - 1;\r\n r2 = parseInt(rangetxt[1].replace(/[^0-9]/g, \"\")) - 1;\r\n if (r1 > r2) {\r\n return txt;\r\n }\r\n\r\n c1 = ABCatNum(rangetxt[0].replace(/[^A-Za-z]/g, \"\"));\r\n c2 = ABCatNum(rangetxt[1].replace(/[^A-Za-z]/g, \"\"));\r\n if (c1 > c2) {\r\n return txt;\r\n }\r\n\r\n let freezonFuc0 = _this.isfreezonFuc(rangetxt[0]);\r\n $row0 = freezonFuc0[0] ? \"$\" : \"\";\r\n $col0 = freezonFuc0[1] ? \"$\" : \"\";\r\n\r\n let freezonFuc1 = _this.isfreezonFuc(rangetxt[1]);\r\n $row1 = freezonFuc1[0] ? \"$\" : \"\";\r\n $col1 = freezonFuc1[1] ? \"$\" : \"\";\r\n }\r\n\r\n if (type == \"del\") {\r\n if (rc == \"row\") {\r\n if (r1 >= stindex && r2 <= stindex + step - 1) {\r\n return _this.error.r;\r\n }\r\n\r\n if (r1 > stindex + step - 1) {\r\n r1 -= step;\r\n }\r\n else if (r1 >= stindex) {\r\n r1 = stindex;\r\n }\r\n\r\n if (r2 > stindex + step - 1) {\r\n r2 -= step;\r\n }\r\n else if (r2 >= stindex) {\r\n r2 = stindex - 1;\r\n }\r\n\r\n if (r1 < 0) {\r\n r1 = 0;\r\n }\r\n\r\n if (r2 < r1) {\r\n r2 = r1;\r\n }\r\n }\r\n else if (rc == \"col\") {\r\n if (c1 >= stindex && c2 <= stindex + step - 1) {\r\n return _this.error.r;\r\n }\r\n\r\n if (c1 > stindex + step - 1) {\r\n c1 -= step;\r\n }\r\n else if (c1 >= stindex) {\r\n c1 = stindex;\r\n }\r\n\r\n if (c2 > stindex + step - 1) {\r\n c2 -= step;\r\n }\r\n else if (c2 >= stindex) {\r\n c2 = stindex - 1;\r\n }\r\n\r\n if (c1 < 0) {\r\n c1 = 0;\r\n }\r\n\r\n if (c2 < c1) {\r\n c2 = c1;\r\n }\r\n }\r\n\r\n if (r1 == r2 && c1 == c2) {\r\n if (!isNaN(r1) && !isNaN(c1)) {\r\n return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1);\r\n }\r\n else if (!isNaN(r1)) {\r\n return prefix + $row0 + (r1 + 1);\r\n }\r\n else if (!isNaN(c1)) {\r\n return prefix + $col0 + chatatABC(c1);\r\n }\r\n else {\r\n return txt;\r\n }\r\n }\r\n else {\r\n if (isNaN(c1) && isNaN(c2)) {\r\n return prefix + $row0 + (r1 + 1) + \":\" + $row1 + (r2 + 1);\r\n }\r\n else if (isNaN(r1) && isNaN(r2)) {\r\n return prefix + $col0 + chatatABC(c1) + \":\" + $col1 + chatatABC(c2);\r\n }\r\n else {\r\n return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1) + \":\" + $col1 + chatatABC(c2) + $row1 + (r2 + 1);\r\n }\r\n }\r\n }\r\n else if (type == \"add\") {\r\n if (rc == \"row\") {\r\n if (orient == \"lefttop\") {\r\n if (r1 >= stindex) {\r\n r1 += step;\r\n }\r\n\r\n if (r2 >= stindex) {\r\n r2 += step;\r\n }\r\n }\r\n else if (orient == \"rightbottom\") {\r\n if (r1 > stindex) {\r\n r1 += step;\r\n }\r\n\r\n if (r2 > stindex) {\r\n r2 += step;\r\n }\r\n }\r\n }\r\n else if (rc == \"col\") {\r\n if (orient == \"lefttop\") {\r\n if (c1 >= stindex) {\r\n c1 += step;\r\n }\r\n\r\n if (c2 >= stindex) {\r\n c2 += step;\r\n }\r\n }\r\n else if (orient == \"rightbottom\") {\r\n if (c1 > stindex) {\r\n c1 += step;\r\n }\r\n\r\n if (c2 > stindex) {\r\n c2 += step;\r\n }\r\n }\r\n }\r\n\r\n if (r1 == r2 && c1 == c2) {\r\n if (!isNaN(r1) && !isNaN(c1)) {\r\n return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1);\r\n }\r\n else if (!isNaN(r1)) {\r\n return prefix + $row0 + (r1 + 1);\r\n }\r\n else if (!isNaN(c1)) {\r\n return prefix + $col0 + chatatABC(c1);\r\n }\r\n else {\r\n return txt;\r\n }\r\n }\r\n else {\r\n if (isNaN(c1) && isNaN(c2)) {\r\n return prefix + $row0 + (r1 + 1) + \":\" + $row1 + (r2 + 1);\r\n }\r\n else if (isNaN(r1) && isNaN(r2)) {\r\n return prefix + $col0 + chatatABC(c1) + \":\" + $col1 + chatatABC(c2);\r\n }\r\n else {\r\n return prefix + $col0 + chatatABC(c1) + $row0 + (r1 + 1) + \":\" + $col1 + chatatABC(c2) + $row1 + (r2 + 1);\r\n }\r\n }\r\n }\r\n },\r\n israngeseleciton: function (istooltip) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (istooltip == null) {\r\n istooltip = false;\r\n }\r\n\r\n let currSelection = window.getSelection();\r\n let anchor = $(currSelection.anchorNode);\r\n let anchorOffset = currSelection.anchorOffset;\r\n\r\n if (anchor.parent().is(\"span\") && anchorOffset != 0) {\r\n let txt = $.trim(anchor.text()),\r\n lasttxt = \"\";\r\n\r\n if (txt.length == 0 && anchor.parent().prev().length > 0) {\r\n let ahr = anchor.parent().prev();\r\n txt = $.trim(ahr.text());\r\n lasttxt = txt.substr(txt.length - 1, 1);\r\n _this.rangeSetValueTo = ahr;\r\n }\r\n else {\r\n lasttxt = txt.substr(anchorOffset - 1, 1);\r\n _this.rangeSetValueTo = anchor.parent();\r\n }\r\n\r\n if ((istooltip && (lasttxt == \"(\" || lasttxt == \",\")) || (!istooltip && (lasttxt == \"(\" || lasttxt == \",\" || lasttxt == \"=\" || lasttxt in _this.operatorjson || lasttxt == \"&\"))) {\r\n return true;\r\n }\r\n }\r\n else if (anchor.is(\"#luckysheet-rich-text-editor\") || anchor.is(\"#luckysheet-functionbox-cell\")) {\r\n let txt = $.trim(anchor.find(\"span\").last().text()),\r\n lasttxt;\r\n\r\n _this.rangeSetValueTo = anchor.find(\"span\").last();\r\n\r\n if (txt.length == 0 && anchor.find(\"span\").length > 1) {\r\n let ahr = anchor.find(\"span\");\r\n txt = $.trim(ahr.eq(ahr.length - 2).text());\r\n _this.rangeSetValueTo = ahr;\r\n }\r\n\r\n lasttxt = txt.substr(txt.length - 1, 1);\r\n\r\n if ((istooltip && (lasttxt == \"(\" || lasttxt == \",\")) || (!istooltip && (lasttxt == \"(\" || lasttxt == \",\" || lasttxt == \"=\" || lasttxt in _this.operatorjson || lasttxt == \"&\"))) {\r\n return true;\r\n }\r\n }\r\n else if (anchor.parent().is(\"#luckysheet-rich-text-editor\") || anchor.parent().is(\"#luckysheet-functionbox-cell\") || anchorOffset == 0) {\r\n if (anchorOffset == 0) {\r\n anchor = anchor.parent();\r\n }\r\n\r\n if (anchor.prev().length > 0) {\r\n let txt = $.trim(anchor.prev().text());\r\n let lasttxt = txt.substr(txt.length - 1, 1);\r\n\r\n _this.rangeSetValueTo = anchor.prev();\r\n\r\n if ((istooltip && (lasttxt == \"(\" || lasttxt == \",\")) || (!istooltip && (lasttxt == \"(\" || lasttxt == \",\" || lasttxt == \"=\" || lasttxt in _this.operatorjson || lasttxt == \"&\"))) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n },\r\n rangechangeindex: null,\r\n rangestart: false,\r\n rangetosheet: null,\r\n rangeSetValueTo: null,\r\n func_selectedrange: {}, //函数选区范围\r\n rangeSetValue: function (selected, obj) {\r\n let _this = this;\r\n\r\n let range = \"\", rf = selected[\"row\"][0], cf = selected[\"column\"][0];\r\n if (Store.config[\"merge\"] != null && (rf + \"_\" + cf) in Store.config[\"merge\"]) {\r\n range = getRangetxt(Store.currentSheetIndex, {\r\n column: [cf, cf],\r\n row: [rf, rf],\r\n }, _this.rangetosheet);\r\n }\r\n else {\r\n range = getRangetxt(Store.currentSheetIndex, selected, _this.rangetosheet);\r\n }\r\n\r\n let $editor;\r\n\r\n if (_this.rangestart || _this.rangedrag_column_start || _this.rangedrag_row_start) {\r\n if ($(\"#luckysheet-search-formula-parm\").is(\":visible\") || $(\"#luckysheet-search-formula-parm-select\").is(\":visible\")) {\r\n //公式参数框选取范围\r\n $editor = $(\"#luckysheet-rich-text-editor\");\r\n $(\"#luckysheet-search-formula-parm-select-input\").val(range);\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(_this.data_parm_index).find(\".txt input\").val(range);\r\n\r\n //参数对应值显示\r\n let txtdata = luckysheet_getcelldata(range).data;\r\n if (txtdata instanceof Array) {\r\n //参数为多个单元格选区\r\n let txtArr = [];\r\n\r\n for (let i = 0; i < txtdata.length; i++) {\r\n for (let j = 0; j < txtdata[i].length; j++) {\r\n if (txtdata[i][j] == null) {\r\n txtArr.push(null);\r\n }\r\n else {\r\n txtArr.push(txtdata[i][j].v);\r\n }\r\n }\r\n }\r\n\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(_this.data_parm_index).find(\".val\").text(\" = {\" + txtArr.join(\",\") + \"}\");\r\n }\r\n else {\r\n //参数为单个单元格选区\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(_this.data_parm_index).find(\".val\").text(\" = {\" + txtdata.v + \"}\");\r\n }\r\n\r\n //计算结果显示\r\n let isVal = true; //参数不为空\r\n let parmValArr = []; //参数值集合\r\n let lvi = -1; //最后一个有值的参数索引\r\n $(\"#luckysheet-search-formula-parm .parmBox\").each(function (i, e) {\r\n let parmtxt = $(e).find(\".txt input\").val();\r\n if (parmtxt == \"\" && $(e).find(\".txt input\").attr(\"data_parm_require\") == \"m\") {\r\n isVal = false;\r\n }\r\n if (parmtxt != \"\") {\r\n lvi = i;\r\n }\r\n })\r\n\r\n //单元格显示\r\n let functionHtmlTxt;\r\n if (lvi == -1) {\r\n functionHtmlTxt = \"=\" + $(\"#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text\").text() + \"()\";\r\n }\r\n else if (lvi == 0) {\r\n functionHtmlTxt = \"=\" + $(\"#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text\").text() + \"(\" + $(\"#luckysheet-search-formula-parm .parmBox\").eq(0).find(\".txt input\").val() + \")\";\r\n }\r\n else {\r\n for (let j = 0; j <= lvi; j++) {\r\n parmValArr.push($(\"#luckysheet-search-formula-parm .parmBox\").eq(j).find(\".txt input\").val());\r\n }\r\n functionHtmlTxt = \"=\" + $(\"#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text\").text() + \"(\" + parmValArr.join(\",\") + \")\";\r\n }\r\n\r\n let function_str = _this.functionHTMLGenerate(functionHtmlTxt);\r\n $(\"#luckysheet-rich-text-editor\").html(function_str);\r\n $(\"#luckysheet-functionbox-cell\").html($(\"#luckysheet-rich-text-editor\").html());\r\n\r\n if (isVal) {\r\n //公式计算\r\n let fp = $.trim(_this.functionParserExe($(\"#luckysheet-rich-text-editor\").text()));\r\n let result = new Function(\"return \" + fp)();\r\n $(\"#luckysheet-search-formula-parm .result span\").text(result);\r\n }\r\n }\r\n else {\r\n let currSelection = window.getSelection();\r\n let anchorOffset = currSelection.anchorNode;\r\n $editor = $(anchorOffset).closest(\"div\");\r\n\r\n let $span = $editor.find(\"span[rangeindex='\" + _this.rangechangeindex + \"']\").html(range);\r\n\r\n _this.setCaretPosition($span.get(0), 0, range.length);\r\n }\r\n }\r\n else {\r\n let function_str = '' + range + '';\r\n let $t = $(function_str).insertAfter(_this.rangeSetValueTo);\r\n _this.rangechangeindex = _this.functionHTMLIndex;\r\n $editor = $(_this.rangeSetValueTo).closest(\"div\");\r\n\r\n _this.setCaretPosition($editor.find(\"span[rangeindex='\" + _this.rangechangeindex + \"']\").get(0), 0, range.length);\r\n _this.functionHTMLIndex++;\r\n }\r\n\r\n if ($editor.attr(\"id\") == \"luckysheet-rich-text-editor\") {\r\n $(\"#luckysheet-functionbox-cell\").html($(\"#luckysheet-rich-text-editor\").html());\r\n }\r\n else {\r\n $(\"#luckysheet-rich-text-editor\").html($(\"#luckysheet-functionbox-cell\").html());\r\n }\r\n },\r\n rangedrag: function (event) {\r\n let _this = this;\r\n\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let x = mouse[0] + $(\"#luckysheet-cell-main\").scrollLeft();\r\n let y = mouse[1] + $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n let row_location = rowLocation(y),\r\n row = row_location[1],\r\n row_pre = row_location[0],\r\n row_index = row_location[2];\r\n\r\n let col_location = colLocation(x),\r\n col = col_location[1],\r\n col_pre = col_location[0],\r\n col_index = col_location[2];\r\n\r\n let top = 0,\r\n height = 0,\r\n rowseleted = [];\r\n\r\n if (_this.func_selectedrange.top > row_pre) {\r\n top = row_pre;\r\n height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;\r\n rowseleted = [row_index, _this.func_selectedrange.row[1]];\r\n }\r\n else if (_this.func_selectedrange.top == row_pre) {\r\n top = row_pre;\r\n height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;\r\n rowseleted = [row_index, _this.func_selectedrange.row[0]];\r\n }\r\n else {\r\n top = _this.func_selectedrange.top;\r\n height = row - _this.func_selectedrange.top - 1;\r\n rowseleted = [_this.func_selectedrange.row[0], row_index];\r\n }\r\n\r\n let left = 0,\r\n width = 0,\r\n columnseleted = [];\r\n\r\n if (_this.func_selectedrange.left > col_pre) {\r\n left = col_pre;\r\n width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;\r\n columnseleted = [col_index, _this.func_selectedrange.column[1]];\r\n }\r\n else if (_this.func_selectedrange.left == col_pre) {\r\n left = col_pre;\r\n width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;\r\n columnseleted = [col_index, _this.func_selectedrange.column[0]];\r\n }\r\n else {\r\n left = _this.func_selectedrange.left;\r\n width = col - _this.func_selectedrange.left - 1;\r\n columnseleted = [_this.func_selectedrange.column[0], col_index];\r\n }\r\n\r\n rowseleted[0] = luckysheetFreezen.changeFreezenIndex(rowseleted[0], \"h\");\r\n rowseleted[1] = luckysheetFreezen.changeFreezenIndex(rowseleted[1], \"h\");\r\n columnseleted[0] = luckysheetFreezen.changeFreezenIndex(columnseleted[0], \"v\");\r\n columnseleted[1] = luckysheetFreezen.changeFreezenIndex(columnseleted[1], \"v\");\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, rowseleted, _this.func_selectedrange, top, height, left, width);\r\n if (changeparam != null) {\r\n columnseleted = changeparam[0];\r\n rowseleted = changeparam[1];\r\n top = changeparam[2];\r\n height = changeparam[3];\r\n left = changeparam[4];\r\n width = changeparam[5];\r\n }\r\n\r\n _this.func_selectedrange[\"row\"] = rowseleted;\r\n _this.func_selectedrange[\"column\"] = columnseleted;\r\n\r\n _this.func_selectedrange[\"left_move\"] = left;\r\n _this.func_selectedrange[\"width_move\"] = width;\r\n _this.func_selectedrange[\"top_move\"] = top;\r\n _this.func_selectedrange[\"height_move\"] = height;\r\n\r\n luckysheet_count_show(left, top, width, height, rowseleted, columnseleted);\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": top,\r\n \"height\": height\r\n }).show();\r\n\r\n if ($(\"#luckysheet-ifFormulaGenerator-multiRange-dialog\").is(\":visible\")) {\r\n //if公式生成器 选择范围\r\n let range = getRangetxt(Store.currentSheetIndex, { \"row\": rowseleted, \"column\": columnseleted }, Store.currentSheetIndex);\r\n $(\"#luckysheet-ifFormulaGenerator-multiRange-dialog input\").val(range);\r\n }\r\n else {\r\n _this.rangeSetValue({\r\n \"row\": rowseleted,\r\n \"column\": columnseleted\r\n });\r\n }\r\n\r\n luckysheetFreezen.scrollFreezen(rowseleted, columnseleted);\r\n },\r\n rangedrag_column_start: false,\r\n rangedrag_row_start: false,\r\n rangedrag_column: function (event) {\r\n let _this = this;\r\n\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let x = mouse[0] + $(\"#luckysheet-cell-main\").scrollLeft();\r\n let y = mouse[1] + $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n let visibledatarow = Store.visibledatarow;\r\n let row_index = visibledatarow.length - 1,\r\n row = visibledatarow[row_index],\r\n row_pre = 0;\r\n\r\n let col_location = colLocation(x),\r\n col = col_location[1],\r\n col_pre = col_location[0],\r\n col_index = col_location[2];\r\n\r\n let left = 0,\r\n width = 0,\r\n columnseleted = [];\r\n\r\n if (_this.func_selectedrange.left > col_pre) {\r\n left = col_pre;\r\n width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;\r\n columnseleted = [col_index, _this.func_selectedrange.column[1]];\r\n }\r\n else if (_this.func_selectedrange.left == col_pre) {\r\n left = col_pre;\r\n width = _this.func_selectedrange.left + _this.func_selectedrange.width - col_pre;\r\n columnseleted = [col_index, _this.func_selectedrange.column[0]];\r\n }\r\n else {\r\n left = _this.func_selectedrange.left;\r\n width = col - _this.func_selectedrange.left - 1;\r\n columnseleted = [_this.func_selectedrange.column[0], col_index];\r\n }\r\n\r\n //rowseleted[0] = luckysheetFreezen.changeFreezenIndex(rowseleted[0], \"h\");\r\n //rowseleted[1] = luckysheetFreezen.changeFreezenIndex(rowseleted[1], \"h\");\r\n columnseleted[0] = luckysheetFreezen.changeFreezenIndex(columnseleted[0], \"v\");\r\n columnseleted[1] = luckysheetFreezen.changeFreezenIndex(columnseleted[1], \"v\");\r\n\r\n let changeparam = menuButton.mergeMoveMain(columnseleted, [0, row_index], _this.func_selectedrange, row_pre, row - row_pre - 1, left, width);\r\n if (changeparam != null) {\r\n columnseleted = changeparam[0];\r\n // rowseleted= changeparam[1];\r\n // top = changeparam[2];\r\n // height = changeparam[3];\r\n left = changeparam[4];\r\n width = changeparam[5];\r\n }\r\n\r\n _this.func_selectedrange[\"column\"] = columnseleted;\r\n _this.func_selectedrange[\"left_move\"] = left;\r\n _this.func_selectedrange[\"width_move\"] = width;\r\n\r\n luckysheet_count_show(left, row_pre, width, row - row_pre - 1, [0, row_index], columnseleted);\r\n\r\n _this.rangeSetValue({\r\n \"row\": [null, null],\r\n \"column\": columnseleted\r\n });\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({\r\n \"left\": left,\r\n \"width\": width,\r\n \"top\": row_pre,\r\n \"height\": row - row_pre - 1\r\n }).show();\r\n\r\n luckysheetFreezen.scrollFreezen([0, row_index], columnseleted);\r\n },\r\n rangedrag_row: function (event) {\r\n let _this = this;\r\n\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let x = mouse[0] + $(\"#luckysheet-cell-main\").scrollLeft();\r\n let y = mouse[1] + $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n let row_location = rowLocation(y),\r\n row = row_location[1],\r\n row_pre = row_location[0],\r\n row_index = row_location[2];\r\n\r\n let visibledatacolumn = Store.visibledatacolumn;\r\n let col_index = visibledatacolumn.length - 1,\r\n col = visibledatacolumn[col_index],\r\n col_pre = 0;\r\n\r\n let top = 0,\r\n height = 0,\r\n rowseleted = [];\r\n\r\n if (_this.func_selectedrange.top > row_pre) {\r\n top = row_pre;\r\n height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;\r\n rowseleted = [row_index, _this.func_selectedrange.row[1]];\r\n }\r\n else if (_this.func_selectedrange.top == row_pre) {\r\n top = row_pre;\r\n height = _this.func_selectedrange.top + _this.func_selectedrange.height - row_pre;\r\n rowseleted = [row_index, _this.func_selectedrange.row[0]];\r\n }\r\n else {\r\n top = _this.func_selectedrange.top;\r\n height = row - _this.func_selectedrange.top - 1;\r\n rowseleted = [_this.func_selectedrange.row[0], row_index];\r\n }\r\n\r\n rowseleted[0] = luckysheetFreezen.changeFreezenIndex(rowseleted[0], \"h\");\r\n rowseleted[1] = luckysheetFreezen.changeFreezenIndex(rowseleted[1], \"h\");\r\n // columnseleted[0] = luckysheetFreezen.changeFreezenIndex(columnseleted[0], \"v\");\r\n // columnseleted[1] = luckysheetFreezen.changeFreezenIndex(columnseleted[1], \"v\");\r\n\r\n let changeparam = menuButton.mergeMoveMain([0, col_index], rowseleted, _this.func_selectedrange, top, height, col_pre, col - col_pre - 1);\r\n if (changeparam != null) {\r\n // columnseleted = changeparam[0];\r\n rowseleted = changeparam[1];\r\n top = changeparam[2];\r\n height = changeparam[3];\r\n // left = changeparam[4];\r\n // width = changeparam[5];\r\n }\r\n\r\n _this.func_selectedrange[\"row\"] = rowseleted;\r\n _this.func_selectedrange[\"top_move\"] = top;\r\n _this.func_selectedrange[\"height_move\"] = height;\r\n\r\n luckysheet_count_show(col_pre, top, col - col_pre - 1, height, rowseleted, [0, col_index]);\r\n\r\n _this.rangeSetValue({\r\n \"row\": rowseleted,\r\n \"column\": [null, null]\r\n });\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({\r\n \"left\": col_pre,\r\n \"width\": col - col_pre - 1,\r\n \"top\": top,\r\n \"height\": height\r\n }).show();\r\n\r\n luckysheetFreezen.scrollFreezen(rowseleted, [0, col_index]);\r\n },\r\n rangedragged: function () { },\r\n rangeResizeObj: null,\r\n rangeResize: null,\r\n rangeResizeIndex: null,\r\n rangeResizexy: null,\r\n rangeResizeWinH: null,\r\n rangeResizeWinW: null,\r\n rangeResizeTo: null,\r\n rangeResizeDraging: function (event, luckysheetCurrentChartResizeObj, luckysheetCurrentChartResizeXy, luckysheetCurrentChartResize, luckysheetCurrentChartResizeWinW, luckysheetCurrentChartResizeWinH, ch_width, rh_height) {\r\n let _this = this;\r\n\r\n let scrollTop = $(\"#luckysheet-scrollbar-y\").scrollTop(),\r\n scrollLeft = $(\"#luckysheet-scrollbar-x\").scrollLeft();\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let x = mouse[0] + scrollLeft;\r\n let y = mouse[1] + scrollTop;\r\n\r\n let row_location = rowLocation(y),\r\n row = row_location[1],\r\n row_pre = row_location[0],\r\n row_index = row_location[2];\r\n let col_location = colLocation(x),\r\n col = col_location[1],\r\n col_pre = col_location[0],\r\n col_index = col_location[2];\r\n\r\n if (x < 0 || y < 0) {\r\n return false;\r\n }\r\n\r\n let topchange = row_pre - luckysheetCurrentChartResizeXy[1],\r\n leftchange = col_pre - luckysheetCurrentChartResizeXy[0];\r\n let top = luckysheetCurrentChartResizeXy[5],\r\n height = luckysheetCurrentChartResizeXy[3],\r\n left = luckysheetCurrentChartResizeXy[4],\r\n width = luckysheetCurrentChartResizeXy[2];\r\n\r\n if (luckysheetCurrentChartResize == \"lt\" || luckysheetCurrentChartResize == \"lb\") {\r\n if (luckysheetCurrentChartResizeXy[0] + luckysheetCurrentChartResizeXy[2] < col_pre) {\r\n return;\r\n }\r\n\r\n left = col_pre;\r\n width = luckysheetCurrentChartResizeXy[2] - leftchange;\r\n\r\n if (left > luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[4] - col + col_pre) {\r\n left = luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[4] - col + col_pre;\r\n width = luckysheetCurrentChartResizeXy[2] - (luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[4] - col + col_pre - luckysheetCurrentChartResizeXy[0]);\r\n }\r\n else if (left <= 0) {\r\n left = 0;\r\n width = luckysheetCurrentChartResizeXy[2] + luckysheetCurrentChartResizeXy[0];\r\n }\r\n }\r\n\r\n if (luckysheetCurrentChartResize == \"rt\" || luckysheetCurrentChartResize == \"rb\") {\r\n if (luckysheetCurrentChartResizeXy[6] - luckysheetCurrentChartResizeXy[2] > col) {\r\n return;\r\n }\r\n\r\n width = luckysheetCurrentChartResizeXy[2] + col - luckysheetCurrentChartResizeXy[6];\r\n\r\n if (width < col - col_pre - 1) {\r\n width = col - col_pre - 1;\r\n }\r\n else if (width >= ch_width - left) {\r\n width = ch_width - left;\r\n }\r\n }\r\n\r\n if (luckysheetCurrentChartResize == \"lt\" || luckysheetCurrentChartResize == \"rt\") {\r\n if (luckysheetCurrentChartResizeXy[1] + luckysheetCurrentChartResizeXy[3] < row_pre) {\r\n return;\r\n }\r\n\r\n top = row_pre;\r\n height = luckysheetCurrentChartResizeXy[3] - topchange;\r\n\r\n if (top > luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[5] - row + row_pre) {\r\n top = luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[5] - row + row_pre;\r\n height = luckysheetCurrentChartResizeXy[3] - (luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[5] - row + row_pre - luckysheetCurrentChartResizeXy[1]);\r\n }\r\n else if (top <= 0) {\r\n top = 0;\r\n height = luckysheetCurrentChartResizeXy[3] + luckysheetCurrentChartResizeXy[1];\r\n }\r\n }\r\n\r\n if (luckysheetCurrentChartResize == \"lb\" || luckysheetCurrentChartResize == \"rb\") {\r\n if (luckysheetCurrentChartResizeXy[7] - luckysheetCurrentChartResizeXy[3] > row) {\r\n return;\r\n }\r\n\r\n height = luckysheetCurrentChartResizeXy[3] + row - luckysheetCurrentChartResizeXy[7];\r\n\r\n if (height < row - row_pre - 1) {\r\n height = row - row_pre - 1;\r\n }\r\n else if (height >= rh_height - top) {\r\n height = rh_height - top;\r\n }\r\n }\r\n\r\n let rangeindex = _this.rangeResizeIndex;\r\n let selected = {\r\n \"top\": top,\r\n \"left\": left,\r\n \"height\": height,\r\n \"width\": width\r\n };\r\n let range = _this.getSelectedFromRange(selected);\r\n let rangetxt = getRangetxt(Store.currentSheetIndex, range, _this.rangetosheet);\r\n let $span = _this.rangeResizeTo.find(\"span[rangeindex='\" + rangeindex + \"']\").html(rangetxt);\r\n luckysheetRangeLast(_this.rangeResizeTo[0]);\r\n luckysheetCurrentChartResizeObj.css(selected).data(\"range\", range);\r\n },\r\n getSelectedFromRange: function (obj) {\r\n let row_st = obj.top + 2,\r\n row_ed = obj.top + obj.height - 2;\r\n let col_st = obj.left + 2,\r\n col_ed = obj.left + obj.width - 2;\r\n\r\n let ret = {\r\n \"row\": [\r\n rowLocation(row_st)[2],\r\n rowLocation(row_ed)[2]\r\n ],\r\n \"column\": [\r\n colLocation(col_st)[2],\r\n colLocation(col_ed)[2]\r\n ]\r\n };\r\n\r\n return ret;\r\n },\r\n rangeResizeDragged: function (event, luckysheetCurrentChartResizeObj, luckysheetCurrentChartResizeXy, luckysheetCurrentChartResize, luckysheetCurrentChartResizeWinW, luckysheetCurrentChartResizeWinH) {\r\n let _this = this;\r\n\r\n _this.rangeResize = null;\r\n $(\"#luckysheet-formula-functionrange-highlight-\" + _this.rangeResizeIndex).find(\".luckysheet-selection-copy-hc\").css(\"opacity\", 0.03);\r\n },\r\n rangeMovexy: null,\r\n rangeMove: false,\r\n rangeMoveObj: null,\r\n rangeMoveIndex: null,\r\n rangeMoveRangedata: null,\r\n rangeMoveDraging: function (event, luckysheet_cell_selected_move_index, luckysheet_select_save, obj, sheetBarHeight, statisticBarHeight) {\r\n let _this = this;\r\n\r\n let mouse = mouseposition(event.pageX, event.pageY);\r\n let scrollLeft = $(\"#luckysheet-scrollbar-x\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-scrollbar-y\").scrollTop();\r\n let x = mouse[0] + scrollLeft;\r\n let y = mouse[1] + scrollTop;\r\n\r\n let winH = $(window).height() + scrollTop - sheetBarHeight - statisticBarHeight,\r\n winW = $(window).width() + scrollLeft;\r\n\r\n let row_index_original = luckysheet_cell_selected_move_index[0],\r\n col_index_original = luckysheet_cell_selected_move_index[1];\r\n let row_s = luckysheet_select_save[\"row\"][0] - row_index_original + rowLocation(y)[2],\r\n row_e = luckysheet_select_save[\"row\"][1] - row_index_original + rowLocation(y)[2];\r\n let col_s = luckysheet_select_save[\"column\"][0] - col_index_original + colLocation(x)[2],\r\n col_e = luckysheet_select_save[\"column\"][1] - col_index_original + colLocation(x)[2];\r\n\r\n if (row_s < 0 || y < 0) {\r\n row_s = 0;\r\n row_e = luckysheet_select_save[\"row\"][1] - luckysheet_select_save[\"row\"][0];\r\n }\r\n if (col_s < 0 || x < 0) {\r\n col_s = 0;\r\n col_e = luckysheet_select_save[\"column\"][1] - luckysheet_select_save[\"column\"][0];\r\n }\r\n\r\n let visibledatarow = Store.visibledatarow;\r\n if (row_e >= visibledatarow[visibledatarow.length - 1] || y > winH) {\r\n row_s = visibledatarow.length - 1 - luckysheet_select_save[\"row\"][1] + luckysheet_select_save[\"row\"][0];\r\n row_e = visibledatarow.length - 1;\r\n }\r\n let visibledatacolumn = Store.visibledatacolumn;\r\n if (col_e >= visibledatacolumn[visibledatacolumn.length - 1] || x > winW) {\r\n col_s = visibledatacolumn.length - 1 - luckysheet_select_save[\"column\"][1] + luckysheet_select_save[\"column\"][0];\r\n col_e = visibledatacolumn.length - 1;\r\n }\r\n\r\n let col_pre = col_s - 1 == -1 ? 0 : visibledatacolumn[col_s - 1],\r\n col = visibledatacolumn[col_e];\r\n let row_pre = row_s - 1 == -1 ? 0 : visibledatarow[row_s - 1],\r\n row = visibledatarow[row_e];\r\n let rangeindex = _this.rangeMoveIndex;\r\n let selected = {\r\n \"left\": col_pre,\r\n \"width\": col - col_pre - 2,\r\n \"top\": row_pre,\r\n \"height\": row - row_pre - 2,\r\n \"display\": \"block\"\r\n };\r\n let range = _this.getSelectedFromRange(selected);\r\n let rangetxt = getRangetxt(Store.currentSheetIndex, range, _this.rangetosheet);\r\n let $span = _this.rangeResizeTo.find(\"span[rangeindex='\" + rangeindex + \"']\").html(rangetxt);\r\n luckysheetRangeLast(_this.rangeResizeTo[0]);\r\n _this.rangeMoveRangedata = range;\r\n obj.css(selected);\r\n },\r\n rangeMoveDragged: function (obj) {\r\n let _this = this;\r\n\r\n _this.rangeMove = false;\r\n $(\"#luckysheet-formula-functionrange-highlight-\" + _this.rangeMoveIndex).data(\"range\", _this.rangeMoveRangedata).find(\".luckysheet-selection-copy-hc\").css(\"opacity\", 0.03);\r\n },\r\n functionHTMLIndex: 0,\r\n functionRangeIndex: null,\r\n findrangeindex: function (v, vp) {\r\n let _this = this;\r\n\r\n let re = //g;\r\n let v_a = v.replace(re, \"\"),\r\n vp_a = vp.replace(re, \"\");\r\n v_a = v_a.split('');\r\n vp_a = vp_a.split('');\r\n v_a.pop();\r\n vp_a.pop();\r\n\r\n let pfri = _this.functionRangeIndex;\r\n let i = 0;\r\n let spanlen = vp_a.length > v_a.length ? v_a.length : vp_a.length;\r\n\r\n let vplen = vp_a.length, vlen = v_a.length;\r\n //不增加元素输入\r\n if (vplen == vlen) {\r\n let i = pfri[0];\r\n let p = vp_a[i], n = v_a[i];\r\n\r\n if (p == null) {\r\n if (vp_a.length <= i) {\r\n pfri = [vp_a.length - 1, vp_a.length - 1];\r\n }\r\n else if (v_a.length <= i) {\r\n pfri = [v_a.length - 1, v_a.length - 1];\r\n }\r\n\r\n return pfri;\r\n }\r\n else if (p.length == n.length) {\r\n if (vp_a[i + 1] != null && v_a[i + 1] != null && vp_a[i + 1].length < v_a[i + 1].length) {\r\n pfri[0] = pfri[0] + 1;\r\n pfri[1] = 1;\r\n }\r\n\r\n return pfri;\r\n }\r\n else if (p.length > n.length) {\r\n if (p != null && v_a[i + 1] != null && v_a[i + 1].substr(0, 1) == '\"' && (p.indexOf(\"{\") > -1 || p.indexOf(\"}\") > -1)) {\r\n pfri[0] = pfri[0] + 1;\r\n pfri[1] = 1;\r\n }\r\n\r\n return pfri;\r\n }\r\n else if (p.length < n.length) {\r\n if (pfri[1] > n.length) {\r\n pfri[1] = n.length;\r\n }\r\n\r\n return pfri;\r\n }\r\n }\r\n //减少元素输入\r\n else if (vplen > vlen) {\r\n let i = pfri[0];\r\n let p = vp_a[i], n = v_a[i];\r\n\r\n if (n == null) {\r\n if (v_a[i - 1].indexOf(\"{\") > -1) {\r\n pfri[0] = pfri[0] - 1;\r\n let start = v_a[i - 1].search(\"{\");\r\n pfri[1] = pfri[1] + start;\r\n }\r\n else {\r\n pfri[0] = 0;\r\n pfri[1] = 0;\r\n }\r\n }\r\n else if (p.length == n.length) {\r\n if (v_a[i + 1] != null && (v_a[i + 1].substr(0, 1) == '\"' || v_a[i + 1].substr(0, 1) == '{' || v_a[i + 1].substr(0, 1) == '}')) {\r\n pfri[0] = pfri[0] + 1;\r\n pfri[1] = 1;\r\n }\r\n else if (p != null && p.length > 2 && p.substr(0, 1) == '\"' && p.substr(p.length - 1, 1) == '\"') {\r\n //pfri[1] = n.length-1;\r\n }\r\n else if (v_a[i] != null && v_a[i] == '\")') {\r\n pfri[1] = 1;\r\n }\r\n else if (v_a[i] != null && v_a[i] == '\"}') {\r\n pfri[1] = 1;\r\n }\r\n else if (v_a[i] != null && v_a[i] == '{)') {\r\n pfri[1] = 1;\r\n }\r\n else {\r\n pfri[1] = n.length;\r\n }\r\n\r\n return pfri;\r\n }\r\n else if (p.length > n.length) {\r\n if (v_a[i + 1] != null && (v_a[i + 1].substr(0, 1) == '\"' || v_a[i + 1].substr(0, 1) == '{' || v_a[i + 1].substr(0, 1) == '}')) {\r\n pfri[0] = pfri[0] + 1;\r\n pfri[1] = 1;\r\n }\r\n\r\n return pfri;\r\n }\r\n else if (p.length < n.length) {\r\n return pfri;\r\n }\r\n\r\n return pfri;\r\n }\r\n //增加元素输入\r\n else if (vplen < vlen) {\r\n let i = pfri[0];\r\n let p = vp_a[i], n = v_a[i];\r\n\r\n if (p == null) {\r\n pfri[0] = v_a.length - 1;\r\n\r\n if (n != null) {\r\n pfri[1] = n.length;\r\n }\r\n else {\r\n pfri[1] = 1;\r\n }\r\n }\r\n else if (p.length == n.length) {\r\n if (vp_a[i + 1] != null && (vp_a[i + 1].substr(0, 1) == '\"' || vp_a[i + 1].substr(0, 1) == '{' || vp_a[i + 1].substr(0, 1) == '}')) {\r\n pfri[1] = n.length;\r\n }\r\n else if (v_a[i + 1] != null && v_a[i + 1].substr(0, 1) == '\"' && (v_a[i + 1].substr(0, 1) == '{' || v_a[i + 1].substr(0, 1) == '}')) {\r\n pfri[0] = pfri[0] + 1;\r\n pfri[1] = 1;\r\n }\r\n else if (n != null && n.substr(0, 1) == '\"' && n.substr(n.length - 1, 1) == '\"' && p.substr(0, 1) == '\"' && p.substr(p.length - 1, 1) == ')') {\r\n pfri[1] = n.length;\r\n }\r\n else if (n != null && n.substr(0, 1) == '{' && n.substr(n.length - 1, 1) == '}' && p.substr(0, 1) == '{' && p.substr(p.length - 1, 1) == ')') {\r\n pfri[1] = n.length;\r\n }\r\n else {\r\n pfri[0] = pfri[0] + vlen - vplen;\r\n if (v_a.length > vp_a.length) {\r\n pfri[1] = v_a[i + 1].length;\r\n }\r\n else {\r\n pfri[1] = 1;\r\n }\r\n }\r\n\r\n return pfri;\r\n }\r\n else if (p.length > n.length) {\r\n if (p != null && p.substr(0, 1) == '\"') {\r\n pfri[1] = n.length;\r\n }\r\n else if (v_a[i + 1] != null && /{.*?}/.test(v_a[i + 1])) {\r\n pfri[0] = pfri[0] + 1;\r\n pfri[1] = v_a[i + 1].length;\r\n }\r\n else if (p != null && v_a[i + 1].substr(0, 1) == '\"' && (p.indexOf(\"{\") > -1 || p.indexOf(\"}\") > -1)) {\r\n pfri[0] = pfri[0] + 1;\r\n pfri[1] = 1;\r\n }\r\n else if (p != null && (p.indexOf(\"{\") > -1 || p.indexOf(\"}\") > -1)) {\r\n\r\n }\r\n else {\r\n pfri[0] = pfri[0] + vlen - vplen - 1;\r\n pfri[1] = v_a[i - 1].length;\r\n }\r\n\r\n return pfri;\r\n }\r\n else if (p.length < n.length) {\r\n return pfri;\r\n }\r\n\r\n return pfri;\r\n }\r\n\r\n return null;\r\n },\r\n setCaretPosition: function (textDom, children, pos) {\r\n try {\r\n let el = textDom;\r\n let range = document.createRange();\r\n let sel = window.getSelection();\r\n range.setStart(el.childNodes[children], pos);\r\n range.collapse(true);\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n el.focus();\r\n }\r\n catch (err) {\r\n luckysheetRangeLast(this.rangeResizeTo[0]);\r\n }\r\n },\r\n functionRange: function (obj, v, vp) {\r\n let _this = this;\r\n\r\n if (window.getSelection) { //ie11 10 9 ff safari\r\n let currSelection = window.getSelection();\r\n let fri = _this.findrangeindex(v, vp);\r\n\r\n if (fri == null) {\r\n currSelection.selectAllChildren(obj.get(0));\r\n currSelection.collapseToEnd();\r\n }\r\n else {\r\n _this.setCaretPosition(obj.find(\"span\").get(fri[0]), 0, fri[1]);\r\n }\r\n }\r\n else if (document.selection) { //ie10 9 8 7 6 5\r\n _this.functionRangeIndex.moveToElementText(obj); //range定位到obj\r\n _this.functionRangeIndex.collapse(false); //光标移至最后\r\n _this.functionRangeIndex.select();\r\n }\r\n },\r\n functionInputHanddler: function ($to, $input, kcode) {\r\n if (isEditMode()) {//此模式下禁用公式栏\r\n return;\r\n }\r\n\r\n let _this = this;\r\n\r\n let $copy = $to,\r\n $editer = $input;\r\n let value1 = $editer.html(),\r\n value1txt = $editer.text();\r\n\r\n setTimeout(function () {\r\n let value = $editer.text(),\r\n valuetxt = value;\r\n\r\n if (value.length > 0 && value.substr(0, 1) == \"=\" && (kcode != 229 || value.length == 1)) {\r\n value = _this.functionHTMLGenerate(value);\r\n value1 = _this.functionHTMLGenerate(value1txt);\r\n\r\n if (window.getSelection) { // all browsers, except IE before version 9\r\n let currSelection = window.getSelection();\r\n if ($(currSelection.anchorNode).is(\"div\")) {\r\n let editorlen = $(\"#luckysheet-rich-text-editor span\").length;\r\n _this.functionRangeIndex = [editorlen - 1, $(\"#luckysheet-rich-text-editor\").find(\"span\").eq(editorlen - 1).text().length];\r\n }\r\n else {\r\n _this.functionRangeIndex = [$(currSelection.anchorNode).parent().index(), currSelection.anchorOffset];\r\n }\r\n }\r\n else { // Internet Explorer before version 9\r\n let textRange = document.selection.createRange();\r\n _this.functionRangeIndex = textRange;\r\n }\r\n\r\n $editer.html(value);\r\n _this.functionRange($editer, value, value1);\r\n _this.canceFunctionrangeSelected();\r\n\r\n if (kcode != 46) {//delete不执行此函数\r\n _this.createRangeHightlight();\r\n }\r\n\r\n $copy.html(value);\r\n _this.rangestart = false;\r\n _this.rangedrag_column_start = false;\r\n _this.rangedrag_row_start = false;\r\n\r\n _this.rangeHightlightselected($editer, kcode);\r\n\r\n }\r\n else if (value1txt.substr(0, 1) != \"=\") {\r\n //&& value1.indexOf(\"span\")>-1\r\n // $editer.html(value1);\r\n\r\n // let w = window.getSelection();\r\n // if(w!=null && w.type!=\"None\"){\r\n // let range = w.getRangeAt(0);\r\n // let c = range.startContainer;\r\n\r\n // if(c.id==\"luckysheet-rich-text-editor\" || $(c).closest(\"#luckysheet-rich-text-editor\")){\r\n // $functionbox.html(value);\r\n // }\r\n // else if(c.id==\"luckysheet-functionbox-cell\" || $(c).closest(\"#luckysheet-functionbox-cell\")){\r\n // if(value1.indexOf(\"span\")>-1){\r\n\r\n // }\r\n // else{\r\n // $editer.html(value);\r\n // }\r\n // }\r\n\r\n // }\r\n // console.trace();\r\n // console.log(value, $copy.attr(\"id\"));\r\n\r\n if ($copy.attr(\"id\") == \"luckysheet-rich-text-editor\") {\r\n if ($copy.html().substr(0, 5) == \"=' + _this.functionHTML(txt);\r\n },\r\n functionHTML: function (txt) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (txt.substr(0, 1) == \"=\") {\r\n txt = txt.substr(1);\r\n }\r\n\r\n let funcstack = txt.split(\"\");\r\n let i = 0,\r\n str = \"\",\r\n function_str = \"\",\r\n ispassby = true;\r\n let matchConfig = {\r\n \"bracket\": 0,\r\n \"comma\": 0,\r\n \"squote\": 0,\r\n \"dquote\": 0,\r\n \"braces\": 0\r\n }\r\n\r\n while (i < funcstack.length) {\r\n let s = funcstack[i];\r\n\r\n if (s == \"(\" && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n matchConfig.bracket += 1;\r\n\r\n if (str.length > 0) {\r\n function_str += '' + str + '(';\r\n }\r\n else {\r\n function_str += '(';\r\n }\r\n\r\n str = \"\";\r\n }\r\n else if (s == \")\" && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n matchConfig.bracket -= 1;\r\n function_str += _this.functionHTML(str) + ')';\r\n str = \"\";\r\n }\r\n else if (s == \"{\" && matchConfig.squote == 0 && matchConfig.dquote == 0) {\r\n str += '{';\r\n matchConfig.braces += 1;\r\n }\r\n else if (s == \"}\" && matchConfig.squote == 0 && matchConfig.dquote == 0) {\r\n str += '}';\r\n matchConfig.braces -= 1;\r\n }\r\n else if (s == '\"' && matchConfig.squote == 0) {\r\n if (matchConfig.dquote > 0) {\r\n if (str.length > 0) {\r\n function_str += str + '\"';\r\n }\r\n else {\r\n function_str += '\"';\r\n }\r\n\r\n matchConfig.dquote -= 1;\r\n str = \"\";\r\n }\r\n else {\r\n matchConfig.dquote += 1;\r\n\r\n if (str.length > 0) {\r\n function_str += _this.functionHTML(str) + '\"';\r\n }\r\n else {\r\n function_str += '\"';\r\n }\r\n\r\n str = \"\";\r\n }\r\n }\r\n //修正例如输入公式='1-2'!A1时,只有2'!A1是luckysheet-formula-functionrange-cell色,'1-是黑色的问题。\r\n else if (s == \"'\" && matchConfig.dquote == 0) {\r\n str += \"'\";\r\n matchConfig.squote = matchConfig.squote == 0 ? 1 : 0;\r\n }\r\n else if (s == ',' && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n //matchConfig.comma += 1;\r\n function_str += _this.functionHTML(str) + ',';\r\n str = \"\";\r\n }\r\n else if (s == '&' && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n if (str.length > 0) {\r\n function_str += _this.functionHTML(str) + '' + '&' + '';\r\n str = \"\";\r\n }\r\n else {\r\n function_str += '' + '&' + '';\r\n }\r\n }\r\n else if (s in _this.operatorjson && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n let s_next = \"\";\r\n if ((i + 1) < funcstack.length) {\r\n s_next = funcstack[i + 1];\r\n }\r\n\r\n let p = i - 1, s_pre = null;\r\n if (p >= 0) {\r\n do {\r\n s_pre = funcstack[p--];\r\n }\r\n while (p >= 0 && s_pre == \" \")\r\n }\r\n\r\n if ((s + s_next) in _this.operatorjson) {\r\n if (str.length > 0) {\r\n function_str += _this.functionHTML(str) + '' + s + s_next + '';\r\n str = \"\";\r\n }\r\n else {\r\n function_str += '' + s + s_next + '';\r\n }\r\n\r\n i++;\r\n }\r\n else if (!(/[^0-9]/.test(s_next)) && s == \"-\" && (s_pre == \"(\" || s_pre == null || s_pre == \",\" || s_pre == \" \" || s_pre in _this.operatorjson)) {\r\n str += s;\r\n }\r\n else {\r\n if (str.length > 0) {\r\n function_str += _this.functionHTML(str) + '' + s + '';\r\n str = \"\";\r\n }\r\n else {\r\n function_str += '' + s + '';\r\n }\r\n }\r\n }\r\n else {\r\n str += s;\r\n }\r\n\r\n if (i == funcstack.length - 1) {\r\n //function_str += str;\r\n if (_this.iscelldata($.trim(str))) {\r\n function_str += '' + str + '';\r\n _this.functionHTMLIndex++;\r\n }\r\n else if (matchConfig.dquote > 0) {\r\n function_str += str + '';\r\n }\r\n else if (str.indexOf(\"\") == -1 && str.length > 0) {\r\n let regx = /{.*?}/;\r\n\r\n if (regx.test($.trim(str))) {\r\n let arraytxt = regx.exec(str)[0];\r\n let arraystart = str.search(regx);\r\n let alltxt = \"\";\r\n\r\n if (arraystart > 0) {\r\n alltxt += '' + str.substr(0, arraystart) + '';\r\n }\r\n\r\n alltxt += '' + arraytxt + '';\r\n\r\n if (arraystart + arraytxt.length < str.length) {\r\n alltxt += '' + str.substr(arraystart + arraytxt.length, str.length) + '';\r\n }\r\n\r\n function_str += alltxt;\r\n }\r\n else {\r\n function_str += '' + str + '';\r\n }\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return function_str;\r\n },\r\n getfunctionParam: function (txt) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (txt.substr(0, 1) == \"=\") {\r\n txt = txt.substr(1);\r\n }\r\n\r\n let funcstack = txt.split(\"\");\r\n let i = 0,\r\n str = \"\",\r\n function_str = \"\";\r\n let matchConfig = {\r\n \"bracket\": 0,\r\n \"comma\": 0,\r\n \"squote\": 0,\r\n \"dquote\": 0,\r\n \"compare\": 0\r\n }\r\n\r\n //bracket 0为运算符括号、1为函数括号\r\n let fn = null, param = [], bracket = [];\r\n\r\n while (i < funcstack.length) {\r\n let s = funcstack[i];\r\n\r\n if (s == \"(\" && matchConfig.dquote == 0) {\r\n if (str.length > 0 && bracket.length == 0) {\r\n fn = str.toUpperCase();\r\n bracket.push(1);\r\n str = \"\";\r\n }\r\n else if (bracket.length == 0) {\r\n //function_str += \"(\";\r\n bracket.push(0);\r\n str = \"\";\r\n }\r\n else {\r\n bracket.push(0);\r\n str += s;\r\n }\r\n }\r\n else if (s == \")\" && matchConfig.dquote == 0) {\r\n let bt = bracket.pop();\r\n\r\n if (bracket.length == 0) {\r\n param.push(str);\r\n str = \"\";\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n else if (s == '\"') {\r\n str += '\"';\r\n\r\n if (matchConfig.dquote > 0) {\r\n matchConfig.dquote -= 1;\r\n str = \"\";\r\n }\r\n else {\r\n matchConfig.dquote += 1;\r\n }\r\n }\r\n else if (s == ',' && matchConfig.dquote == 0) {\r\n if (bracket.length <= 1) {\r\n param.push(str);\r\n str = \"\";\r\n }\r\n else {\r\n str += \",\";\r\n }\r\n }\r\n else if (s in _this.operatorjson && matchConfig.dquote == 0) {\r\n let s_next = \"\";\r\n if ((i + 1) < funcstack.length) {\r\n s_next = funcstack[i + 1];\r\n }\r\n\r\n let p = i - 1, s_pre = null;\r\n if (p >= 0) {\r\n do {\r\n s_pre = funcstack[p--];\r\n }\r\n while (p >= 0 && s_pre == \" \")\r\n }\r\n\r\n if (!(/[^0-9]/.test(s_next)) && s == \"-\" && (s_pre == \"(\" || s_pre == null || s_pre == \",\" || s_pre == \" \" || s_pre in _this.operatorjson)) {\r\n if (matchConfig.dquote == 0) {\r\n str += $.trim(s);\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n else {\r\n function_str = \"\";\r\n str = \"\";\r\n }\r\n }\r\n else {\r\n if (matchConfig.dquote == 0) {\r\n str += $.trim(s);\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n\r\n return { \"fn\": fn, \"param\": param };\r\n },\r\n calPostfixExpression: function (cal) {\r\n if (cal.length == 0) {\r\n return \"\";\r\n }\r\n\r\n let stack = [];\r\n for (let i = cal.length - 1; i >= 0; i--) {\r\n let c = cal[i];\r\n if (c in this.operatorjson) {\r\n let s2 = stack.pop();\r\n let s1 = stack.pop();\r\n\r\n let str = \"luckysheet_compareWith(\" + s1 + \",'\" + c + \"', \" + s2 + \")\";\r\n\r\n stack.push(str);\r\n }\r\n else {\r\n stack.push(c);\r\n }\r\n }\r\n\r\n if (stack.length > 0) {\r\n return stack[0];\r\n }\r\n else {\r\n return \"\";\r\n }\r\n },\r\n checkBracketNum: function (fp) {\r\n let bra_l = fp.match(/\\(/g),\r\n bra_r = fp.match(/\\)/g),\r\n bra_tl_txt = fp.match(/(['\"])(?:(?!\\1).)*?\\1/g),\r\n bra_tr_txt = fp.match(/(['\"])(?:(?!\\1).)*?\\1/g);\r\n\r\n let bra_l_len = 0, bra_r_len = 0;\r\n if (bra_l != null) {\r\n bra_l_len += bra_l.length;\r\n }\r\n if (bra_r != null) {\r\n bra_r_len += bra_r.length;\r\n }\r\n\r\n let bra_tl_len = 0, bra_tr_len = 0;\r\n if (bra_tl_txt != null) {\r\n for (let i = 0; i < bra_tl_txt.length; i++) {\r\n let bra_tl = bra_tl_txt[i].match(/\\(/g);\r\n if (bra_tl != null) {\r\n bra_tl_len += bra_tl.length;\r\n }\r\n }\r\n }\r\n\r\n if (bra_tr_txt != null) {\r\n for (let i = 0; i < bra_tr_txt.length; i++) {\r\n let bra_tr = bra_tr_txt[i].match(/\\)/g);\r\n if (bra_tr != null) {\r\n bra_tr_len += bra_tr.length;\r\n }\r\n }\r\n }\r\n\r\n bra_l_len -= bra_tl_len;\r\n bra_r_len -= bra_tr_len;\r\n\r\n if (bra_l_len != bra_r_len) {\r\n return false;\r\n }\r\n else {\r\n return true;\r\n }\r\n },\r\n operatorPriority: {\r\n \"^\": 0,\r\n \"%\": 1,\r\n \"*\": 1,\r\n \"/\": 1,\r\n \"+\": 2,\r\n \"-\": 2\r\n },\r\n functionParserExe: function (txt) {\r\n let _this = this;\r\n // let txt1 = txt.toUpperCase();\r\n // return this.functionParser(txt, function(c){\r\n // _this.addToCellList(txt, c);\r\n // });\r\n return this.functionParser(txt);\r\n },\r\n functionParser: function (txt, cellRangeFunction) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (txt == null) {\r\n return \"\";\r\n }\r\n\r\n if (txt.substr(0, 2) == \"=+\") {\r\n txt = txt.substr(2);\r\n }\r\n else if (txt.substr(0, 1) == \"=\") {\r\n txt = txt.substr(1);\r\n }\r\n\r\n let funcstack = txt.split(\"\");\r\n let i = 0,\r\n str = \"\",\r\n function_str = \"\";\r\n\r\n let matchConfig = {\r\n \"bracket\": 0,\r\n \"comma\": 0,\r\n \"squote\": 0,\r\n \"dquote\": 0,\r\n \"compare\": 0,\r\n \"braces\": 0\r\n }\r\n\r\n //=(sum(b1:c10)+10)*5-100\r\n\r\n //=MAX(B1:C10,10)*5-100\r\n\r\n // =(sum(max(B1:C10,10)*5-100,((1+1)*2+5)/2,10)+count(B1:C10,10*5-100))*5-100\r\n\r\n //=SUM(MAX(B1:C10,10)*5-100,((1+1)*2+5)/2,10)+COUNT(B1:C10,10*5-100)\r\n\r\n //=SUM(MAX(B1:C10,10)*5-100,((1+1)*2+5)/2,10)\r\n\r\n //=SUM(10,((1+1)*2+5)/2,10)\r\n\r\n //=SUM(MAX(B1:C10,10)*5-100)\r\n\r\n //=IFERROR(IF(ROW()-ROW($G$3)=1,$F4+$D4,SUM($D1:INDEX($D$4:$D$9,1,1),$F1:INDEX($F$4:$F$9,1,1))), \"\")\r\n\r\n //=IFERROR(IF(ROW()-ROW($G$3)=1,$F4+$D4,SUM(INDEX($D$4:$D$9,1,1):$D4,INDEX($F$4:$F$9,1,1):$F4)), \"\")\r\n\r\n //=SUM(I$4:OFFSET(I10,0,0))\r\n\r\n //bracket 0为运算符括号、1为函数括号\r\n let cal1 = [], cal2 = [], bracket = [];\r\n let firstSQ = -1;\r\n while (i < funcstack.length) {\r\n let s = funcstack[i];\r\n\r\n if (s == \"(\" && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n if (str.length > 0 && bracket.length == 0) {\r\n str = str.toUpperCase();\r\n if (str.indexOf(\":\") > -1) {\r\n let funcArray = str.split(\":\");\r\n function_str += \"luckysheet_getSpecialReference(true,'\" + $.trim(funcArray[0]).replace(/'/g, \"\\\\'\") + \"', luckysheet_function.\" + funcArray[1] + \".f(#lucky#\";\r\n }\r\n else {\r\n function_str += \"luckysheet_function.\" + str + \".f(\";\r\n }\r\n bracket.push(1);\r\n str = \"\";\r\n }\r\n else if (bracket.length == 0) {\r\n function_str += \"(\";\r\n bracket.push(0);\r\n str = \"\";\r\n }\r\n else {\r\n bracket.push(0);\r\n str += s;\r\n }\r\n }\r\n else if (s == \")\" && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n let bt = bracket.pop();\r\n\r\n if (bracket.length == 0) {\r\n let functionS = _this.functionParser(str, cellRangeFunction);\r\n if (functionS.indexOf(\"#lucky#\") > -1) {\r\n functionS = functionS.replace(/#lucky#/g, \"\") + \")\";\r\n }\r\n function_str += functionS + \")\";\r\n str = \"\";\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n else if (s == \"{\" && matchConfig.squote == 0 && matchConfig.dquote == 0) {\r\n str += '{';\r\n matchConfig.braces += 1;\r\n }\r\n else if (s == \"}\" && matchConfig.squote == 0 && matchConfig.dquote == 0) {\r\n str += '}';\r\n matchConfig.braces -= 1;\r\n }\r\n else if (s == '\"' && matchConfig.squote == 0) {\r\n\r\n if (matchConfig.dquote > 0) {\r\n //如果是\"\"代表着输出\"\r\n if (i < funcstack.length - 1 && funcstack[i + 1] == '\"') {\r\n i++;\r\n str += \"\\x7F\";//用非打印控制字符DEL替换一下\"\"\r\n }\r\n else {\r\n matchConfig.dquote -= 1;\r\n str += '\"';\r\n }\r\n }\r\n else {\r\n matchConfig.dquote += 1;\r\n str += '\"';\r\n }\r\n }\r\n else if (s == \"'\" && matchConfig.dquote == 0) {\r\n str += \"'\";\r\n\r\n if (matchConfig.squote > 0) {\r\n if (firstSQ == i - 1)//配对的单引号后第一个字符不能是单引号\r\n {\r\n return \"\";\r\n }\r\n //如果是''代表着输出'\r\n if (i < funcstack.length - 1 && funcstack[i + 1] == \"'\") {\r\n i++;\r\n str += \"'\";\r\n }\r\n else {//如果下一个字符不是'代表单引号结束\r\n if (funcstack[i - 1] == \"'\") {//配对的单引号后最后一个字符不能是单引号\r\n return \"\";\r\n } else {\r\n matchConfig.squote -= 1;\r\n }\r\n }\r\n }\r\n else {\r\n matchConfig.squote += 1;\r\n firstSQ = i;\r\n }\r\n }\r\n else if (s == ',' && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n if (bracket.length <= 1) {\r\n let functionS = _this.functionParser(str, cellRangeFunction);\r\n if (functionS.indexOf(\"#lucky#\") > -1) {\r\n functionS = functionS.replace(/#lucky#/g, \"\") + \")\";\r\n }\r\n function_str += functionS + \",\";\r\n str = \"\";\r\n }\r\n else {\r\n str += \",\";\r\n }\r\n }\r\n else if (s in _this.operatorjson && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n let s_next = \"\";\r\n let op = _this.operatorPriority;\r\n\r\n if ((i + 1) < funcstack.length) {\r\n s_next = funcstack[i + 1];\r\n }\r\n\r\n if ((s + s_next) in _this.operatorjson) {\r\n if (bracket.length == 0) {\r\n if ($.trim(str).length > 0) {\r\n cal2.unshift(_this.functionParser($.trim(str), cellRangeFunction));\r\n }\r\n else if ($.trim(function_str).length > 0) {\r\n cal2.unshift($.trim(function_str));\r\n }\r\n\r\n if (cal1[0] in _this.operatorjson) {\r\n let stackCeilPri = op[cal1[0]];\r\n\r\n while (cal1.length > 0 && stackCeilPri != null) {\r\n cal2.unshift(cal1.shift());\r\n stackCeilPri = op[cal1[0]];\r\n }\r\n }\r\n\r\n cal1.unshift(s + s_next);\r\n\r\n function_str = \"\";\r\n str = \"\";\r\n }\r\n else {\r\n str += s + s_next;\r\n }\r\n\r\n i++;\r\n }\r\n else {\r\n if (bracket.length == 0) {\r\n if ($.trim(str).length > 0) {\r\n cal2.unshift(_this.functionParser($.trim(str), cellRangeFunction));\r\n }\r\n else if ($.trim(function_str).length > 0) {\r\n cal2.unshift($.trim(function_str));\r\n }\r\n\r\n if (cal1[0] in _this.operatorjson) {\r\n let stackCeilPri = op[cal1[0]];\r\n stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;\r\n\r\n let sPri = op[s];\r\n sPri = sPri == null ? 1000 : sPri;\r\n\r\n while (cal1.length > 0 && sPri >= stackCeilPri) {\r\n cal2.unshift(cal1.shift());\r\n\r\n stackCeilPri = op[cal1[0]];\r\n stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;\r\n }\r\n }\r\n\r\n cal1.unshift(s);\r\n\r\n function_str = \"\";\r\n str = \"\";\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n }\r\n else {\r\n if (matchConfig.dquote == 0 && matchConfig.squote == 0) {\r\n // str += $.trim(s);\r\n str += s; //Do not use $.trim(s). When obtaining the worksheet name that contains spaces, you should keep the spaces\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n\r\n if (i == funcstack.length - 1) {\r\n let endstr = \"\";\r\n let str_nb = $.trim(str).replace(/'/g, \"\\\\'\");\r\n if (_this.iscelldata(str_nb) && str_nb.substr(0, 1) != \":\") {\r\n\r\n endstr = \"luckysheet_getcelldata('\" + str_nb + \"')\";\r\n if (typeof (cellRangeFunction) == \"function\") {\r\n cellRangeFunction(str_nb);\r\n }\r\n\r\n }\r\n else if (str_nb.substr(0, 1) == \":\") {\r\n str_nb = str_nb.substr(1);\r\n if (_this.iscelldata(str_nb)) {\r\n endstr = \"luckysheet_getSpecialReference(false,\" + function_str + \",'\" + str_nb + \"')\";\r\n }\r\n }\r\n else {\r\n str = $.trim(str);\r\n\r\n let regx = /{.*?}/;\r\n if (regx.test(str) && str.substr(0, 1) != '\"' && str.substr(str.length - 1, 1) != '\"') {\r\n let arraytxt = regx.exec(str)[0];\r\n let arraystart = str.search(regx);\r\n let alltxt = \"\";\r\n\r\n if (arraystart > 0) {\r\n endstr += str.substr(0, arraystart);\r\n }\r\n\r\n endstr += \"luckysheet_getarraydata('\" + arraytxt + \"')\";\r\n\r\n if (arraystart + arraytxt.length < str.length) {\r\n endstr += str.substr(arraystart + arraytxt.length, str.length);\r\n }\r\n }\r\n else {\r\n endstr = str;\r\n }\r\n }\r\n\r\n if (endstr.length > 0) {\r\n cal2.unshift(endstr);\r\n }\r\n\r\n if (cal1.length > 0) {\r\n if (function_str.length > 0) {\r\n cal2.unshift(function_str);\r\n function_str = \"\";\r\n }\r\n\r\n while (cal1.length > 0) {\r\n cal2.unshift(cal1.shift());\r\n }\r\n }\r\n\r\n if (cal2.length > 0) {\r\n function_str = _this.calPostfixExpression(cal2);\r\n }\r\n else {\r\n function_str += endstr;\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n // console.log(function_str);\r\n return function_str;\r\n },\r\n insertUpdateDynamicArray: function (dynamicArrayItem) {\r\n let r = dynamicArrayItem.r, c = dynamicArrayItem.c, index = dynamicArrayItem.index;\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n let file = luckysheetfile[getSheetIndex(index)];\r\n\r\n let dynamicArray = file.dynamicArray;\r\n if (dynamicArray == null) {\r\n dynamicArray = [];\r\n }\r\n\r\n for (let i = 0; i < dynamicArray.length; i++) {\r\n let calc = dynamicArray[i];\r\n if (calc.r == r && calc.c == c && calc.index == index) {\r\n calc.data = dynamicArrayItem.data;\r\n calc.f = dynamicArrayItem.f;\r\n return dynamicArray;\r\n }\r\n }\r\n\r\n dynamicArray.push(dynamicArrayItem);\r\n return dynamicArray\r\n },\r\n addFunctionGroup: function (r, c, func, index) {\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n let file = luckysheetfile[getSheetIndex(index)];\r\n if (file.calcChain == null) {\r\n file.calcChain = [];\r\n }\r\n\r\n let cc = {\r\n \"r\": r,\r\n \"c\": c,\r\n \"index\": index,\r\n \"func\": func\r\n };\r\n file.calcChain.push(cc);\r\n\r\n server.saveParam(\"fc\", index, JSON.stringify(cc), {\r\n \"op\": \"add\",\r\n \"pos\": file.calcChain.length - 1\r\n });\r\n setluckysheetfile(luckysheetfile);\r\n },\r\n getAllFunctionGroup: function () {\r\n let luckysheetfile = getluckysheetfile();\r\n let ret = [];\r\n for (let i = 0; i < luckysheetfile.length; i++) {\r\n let file = luckysheetfile[i];\r\n let calcChain = file.calcChain;\r\n \r\n /* 备注:再次加载表格获取的数据可能是JSON字符串格式(需要进行发序列化处理) */\r\n if(calcChain){\r\n let tempCalcChain = [];\r\n calcChain.forEach((item,idx)=>{\r\n if(typeof item === \"string\"){\r\n tempCalcChain.push(JSON.parse(item));\r\n }else{\r\n tempCalcChain.push(item);\r\n }\r\n })\r\n calcChain = file.calcChain = tempCalcChain;\r\n }\r\n\r\n let dynamicArray_compute = file.dynamicArray_compute;\r\n if (calcChain == null) {\r\n calcChain = [];\r\n }\r\n\r\n if (dynamicArray_compute == null) {\r\n dynamicArray_compute = [];\r\n }\r\n\r\n ret = ret.concat(calcChain);\r\n\r\n for (let i = 0; i < dynamicArray_compute.length; i++) {\r\n let d = dynamicArray_compute[0];\r\n ret.push({\r\n r: d.r,\r\n c: d.c,\r\n index: d.index\r\n });\r\n }\r\n }\r\n\r\n return ret;\r\n },\r\n getFunctionGroup: function (index) {\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n let file = luckysheetfile[getSheetIndex(index)];\r\n\r\n if (file.calcChain == null) {\r\n return [];\r\n }\r\n\r\n return file.calcChain;\r\n },\r\n updateFunctionGroup: function (r, c, index) {\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n let file = luckysheetfile[getSheetIndex(index)];\r\n\r\n let calcChain = file.calcChain;\r\n if (calcChain != null) {\r\n for (let i = 0; i < calcChain.length; i++) {\r\n let calc = calcChain[i];\r\n if (calc.r == r && calc.c == c && calc.index == index) {\r\n server.saveParam(\"fc\", index, JSON.stringify(calc), {\r\n \"op\": \"update\",\r\n \"pos\": i\r\n });\r\n break;\r\n }\r\n }\r\n }\r\n\r\n setluckysheetfile(luckysheetfile);\r\n },\r\n insertUpdateFunctionGroup: function (r, c, index) {\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n // let func = getcellFormula(r, c, index);\r\n // if (func == null || func.length==0) {\r\n // this.delFunctionGroup(r, c, index);\r\n // return;\r\n // }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n let file = luckysheetfile[getSheetIndex(index)];\r\n\r\n let calcChain = file.calcChain;\r\n if (calcChain == null) {\r\n calcChain = [];\r\n }\r\n\r\n for (let i = 0; i < calcChain.length; i++) {\r\n let calc = calcChain[i];\r\n if (calc.r == r && calc.c == c && calc.index == index) {\r\n server.saveParam(\"fc\", index, JSON.stringify(calc), {\r\n \"op\": \"update\",\r\n \"pos\": i\r\n });\r\n return;\r\n }\r\n }\r\n\r\n let cc = {\r\n \"r\": r,\r\n \"c\": c,\r\n \"index\": index\r\n };\r\n calcChain.push(cc);\r\n file.calcChain = calcChain;\r\n\r\n server.saveParam(\"fc\", index, JSON.stringify(cc), {\r\n \"op\": \"add\",\r\n \"pos\": file.calcChain.length - 1\r\n });\r\n setluckysheetfile(luckysheetfile);\r\n },\r\n isFunctionRangeSave: false,\r\n isFunctionRangeSimple: function (txt, r, c, index, dynamicArray_compute) {\r\n if (txt == null || txt.length == 0) {\r\n return;\r\n }\r\n\r\n let txtArray = txt.split(/==|!=|<>|<=|>=|[,()=+-\\/*%&^><]/g);\r\n if (txtArray.length > 0) {\r\n for (let i = 0; i < txtArray.length; i++) {\r\n let t = txtArray[i];\r\n if (t.length <= 1) {\r\n continue;\r\n }\r\n\r\n if (t.substr(0, 1) == '\"' && t.substr(t.length - 1, 1) == '\"') {\r\n continue;\r\n }\r\n\r\n this.isFunctionRangeSaveChange(t, r, c, index, dynamicArray_compute);\r\n }\r\n }\r\n },\r\n isFunctionRangeSimple1: function (txt, r, c, index, dynamicArray_compute) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (txt.substr(0, 1) == \"=\") {\r\n txt = txt.substr(1);\r\n }\r\n\r\n let funcstack = txt.split(\"\");\r\n let i = 0,\r\n str = \"\",\r\n function_str = \"\",\r\n ispassby = true;\r\n\r\n let matchConfig = {\r\n \"bracket\": 0,\r\n \"comma\": 0,\r\n \"squote\": 0,\r\n \"dquote\": 0\r\n }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n\r\n\r\n while (i < funcstack.length) {\r\n let s = funcstack[i];\r\n\r\n if (s == \"(\" && matchConfig.dquote == 0) {\r\n matchConfig.bracket += 1;\r\n\r\n if (str.length > 0) {\r\n function_str += \"luckysheet_function.\" + str.toUpperCase() + \".f(\";\r\n }\r\n else {\r\n function_str += \"(\";\r\n }\r\n\r\n str = \"\";\r\n }\r\n else if (s == \")\" && matchConfig.dquote == 0) {\r\n matchConfig.bracket -= 1;\r\n function_str += _this.isFunctionRangeSimple(str, r, c, index, dynamicArray_compute) + \")\";\r\n str = \"\";\r\n }\r\n else if (s == ',' && matchConfig.dquote == 0) {\r\n //matchConfig.comma += 1;\r\n function_str += _this.isFunctionRangeSimple(str, r, c, index, dynamicArray_compute) + ',';\r\n str = \"\";\r\n }\r\n else if (s in _this.operatorjson && matchConfig.dquote == 0) {\r\n let s_next = \"\";\r\n\r\n if ((i + 1) < funcstack.length) {\r\n s_next = funcstack[i + 1];\r\n }\r\n\r\n if ((s + s_next) in _this.operatorjson) {\r\n if (str.length > 0) {\r\n function_str += _this.isFunctionRangeSimple(str, r, c, index, dynamicArray_compute) + s + s_next;\r\n str = \"\";\r\n }\r\n else {\r\n function_str += s + s_next;\r\n }\r\n\r\n i++;\r\n }\r\n else {\r\n if (str.length > 0) {\r\n function_str += _this.isFunctionRangeSimple(str, r, c, index, dynamicArray_compute) + s;\r\n str = \"\";\r\n }\r\n else {\r\n function_str += s;\r\n }\r\n }\r\n }\r\n else {\r\n str += s;\r\n }\r\n\r\n if (i == funcstack.length - 1) {\r\n if (_this.iscelldata($.trim(str))) {\r\n _this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);\r\n // if (r != null && c != null) {\r\n\r\n // let range = _this.getcellrange($.trim(str));\r\n // let row = range.row,\r\n // col = range.column;\r\n\r\n // if ((r + \"_\" + c) in dynamicArray_compute) {\r\n // let isd_range = false;\r\n\r\n // for (let d_r = row[0]; d_r <= row[1]; d_r++) {\r\n // for (let d_c = col[0]; d_c <= col[1]; d_c++) {\r\n // if ((d_r + \"_\" + d_c) in dynamicArray_compute && dynamicArray_compute[d_r + \"_\" + d_c].r == r && dynamicArray_compute[d_r + \"_\" + d_c].c == c) {\r\n // isd_range = true;\r\n // }\r\n // }\r\n // }\r\n\r\n // if (isd_range) {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;\r\n // }\r\n // else {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;\r\n // }\r\n // }\r\n // else {\r\n // if (r >= row[0] && r <= row[1] && c >= col[0] && c <= col[1]) {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;\r\n // }\r\n // else {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;\r\n // }\r\n // }\r\n // }\r\n // else {\r\n // let sheetlen = $.trim(str).split(\"!\");\r\n\r\n // if (sheetlen.length > 1) {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;\r\n // }\r\n // else {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;\r\n // }\r\n // }\r\n }\r\n else {\r\n //console.log(str);\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n //console.log(function_str);\r\n return function_str;\r\n },\r\n isFunctionRangeSelect: function (txt, r, c, index, dynamicArray_compute) {\r\n if (txt == null || txt == \"\") {\r\n return;\r\n }\r\n\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n if (dynamicArray_compute == null) {\r\n dynamicArray_compute = {};\r\n }\r\n let _this = this;\r\n let txt1 = txt.toUpperCase();\r\n let isOffsetFunc = txt1.indexOf(\"INDIRECT(\") > -1 || txt1.indexOf(\"OFFSET(\") > -1 || txt1.indexOf(\"INDEX(\") > -1;\r\n if (txt in this.formulaContainCellList) {\r\n let cellList = this.formulaContainCellList[txt];\r\n if (isOffsetFunc) {\r\n let isoff = cellList[\"__LuckyisOff__\"];\r\n if (isoff == true) {\r\n for (let cellStr in cellList) {\r\n if (cellStr == \"__LuckyisOff__\") {\r\n continue;\r\n }\r\n this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute);\r\n }\r\n }\r\n else {\r\n this.isFunctionRange(txt, r, c, index, dynamicArray_compute, function (str) {\r\n _this.addToCellList(txt, str);\r\n });\r\n cellList[\"__LuckyisOff__\"] = true;\r\n }\r\n }\r\n else {\r\n\r\n for (let cellStr in cellList) {\r\n if (cellStr == \"__LuckyisOff__\") {\r\n continue;\r\n }\r\n this.isFunctionRangeSaveChange(cellStr, r, c, index, dynamicArray_compute);\r\n }\r\n }\r\n\r\n return;\r\n }\r\n\r\n\r\n if (isOffsetFunc) {\r\n this.isFunctionRange(txt, r, c, index, dynamicArray_compute);\r\n }\r\n else {\r\n this.isFunctionRangeSimple(txt, r, c, index, dynamicArray_compute);\r\n }\r\n },\r\n isFunctionRange: function (txt, r, c, index, dynamicArray_compute, cellRangeFunction) {\r\n let _this = this;\r\n\r\n if (_this.operatorjson == null) {\r\n let arr = _this.operator.split(\"|\"),\r\n op = {};\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n op[arr[i].toString()] = 1;\r\n }\r\n\r\n _this.operatorjson = op;\r\n }\r\n\r\n if (txt.substr(0, 1) == \"=\") {\r\n txt = txt.substr(1);\r\n }\r\n\r\n let funcstack = txt.split(\"\");\r\n let i = 0,\r\n str = \"\",\r\n function_str = \"\",\r\n ispassby = true;\r\n\r\n let matchConfig = {\r\n \"bracket\": 0,\r\n \"comma\": 0,\r\n \"squote\": 0,\r\n \"dquote\": 0,\r\n \"compare\": 0,\r\n \"braces\": 0\r\n }\r\n\r\n // let luckysheetfile = getluckysheetfile();\r\n // let dynamicArray_compute = luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray_compute\"] == null ? {} : luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray_compute\"];\r\n\r\n //bracket 0为运算符括号、1为函数括号\r\n let cal1 = [], cal2 = [], bracket = [];\r\n let firstSQ = -1;\r\n while (i < funcstack.length) {\r\n let s = funcstack[i];\r\n\r\n if (s == \"(\" && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n if (str.length > 0 && bracket.length == 0) {\r\n str = str.toUpperCase();\r\n if (str.indexOf(\":\") > -1) {\r\n let funcArray = str.split(\":\");\r\n function_str += \"luckysheet_getSpecialReference(true,'\" + $.trim(funcArray[0]).replace(/'/g, \"\\\\'\") + \"', luckysheet_function.\" + funcArray[1] + \".f(#lucky#\";\r\n }\r\n else {\r\n function_str += \"luckysheet_function.\" + str + \".f(\";\r\n }\r\n bracket.push(1);\r\n str = \"\";\r\n }\r\n else if (bracket.length == 0) {\r\n function_str += \"(\";\r\n bracket.push(0);\r\n str = \"\";\r\n }\r\n else {\r\n bracket.push(0);\r\n str += s;\r\n }\r\n }\r\n else if (s == \")\" && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n let bt = bracket.pop();\r\n\r\n if (bracket.length == 0) {\r\n // function_str += _this.isFunctionRange(str,r,c, index,dynamicArray_compute,cellRangeFunction) + \")\";\r\n // str = \"\";\r\n\r\n let functionS = _this.isFunctionRange(str, r, c, index, dynamicArray_compute, cellRangeFunction);\r\n if (functionS.indexOf(\"#lucky#\") > -1) {\r\n functionS = functionS.replace(/#lucky#/g, \"\") + \")\";\r\n }\r\n function_str += functionS + \")\";\r\n str = \"\";\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n else if (s == \"{\" && matchConfig.squote == 0 && matchConfig.dquote == 0) {\r\n str += '{';\r\n matchConfig.braces += 1;\r\n }\r\n else if (s == \"}\" && matchConfig.squote == 0 && matchConfig.dquote == 0) {\r\n str += '}';\r\n matchConfig.braces -= 1;\r\n }\r\n else if (s == '\"' && matchConfig.squote == 0) {\r\n\r\n if (matchConfig.dquote > 0) {\r\n //如果是\"\"代表着输出\"\r\n if (i < funcstack.length - 1 && funcstack[i + 1] == '\"') {\r\n i++;\r\n str += \"\\x7F\";//用DEL替换一下\"\"\r\n }\r\n else {\r\n matchConfig.dquote -= 1;\r\n str += '\"';\r\n }\r\n }\r\n else {\r\n matchConfig.dquote += 1;\r\n str += '\"';\r\n }\r\n }\r\n else if (s == \"'\" && matchConfig.dquote == 0) {\r\n str += \"'\";\r\n\r\n if (matchConfig.squote > 0) {\r\n //if (firstSQ == i - 1)//配对的单引号后第一个字符不能是单引号\r\n //{\r\n // 代码到了此处应该是公式错误\r\n //}\r\n //如果是''代表着输出'\r\n if (i < funcstack.length - 1 && funcstack[i + 1] == \"'\") {\r\n i++;\r\n str += \"'\";\r\n }\r\n else {//如果下一个字符不是'代表单引号结束\r\n //if (funcstack[i - 1] == \"'\") {//配对的单引号后最后一个字符不能是单引号\r\n // 代码到了此处应该是公式错误\r\n //} else {\r\n matchConfig.squote -= 1;\r\n //}\r\n }\r\n }\r\n else {\r\n matchConfig.squote += 1;\r\n firstSQ = i;\r\n }\r\n }\r\n else if (s == ',' && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n if (bracket.length <= 1) {\r\n // function_str += _this.isFunctionRange(str, r, c, index,dynamicArray_compute,cellRangeFunction) + \",\";\r\n // str = \"\";\r\n\r\n let functionS = _this.isFunctionRange(str, r, c, index, dynamicArray_compute, cellRangeFunction);\r\n if (functionS.indexOf(\"#lucky#\") > -1) {\r\n functionS = functionS.replace(/#lucky#/g, \"\") + \")\";\r\n }\r\n function_str += functionS + \",\";\r\n str = \"\";\r\n }\r\n else {\r\n str += \",\";\r\n }\r\n }\r\n else if (s in _this.operatorjson && matchConfig.squote == 0 && matchConfig.dquote == 0 && matchConfig.braces == 0) {\r\n let s_next = \"\";\r\n let op = _this.operatorPriority;\r\n\r\n if ((i + 1) < funcstack.length) {\r\n s_next = funcstack[i + 1];\r\n }\r\n\r\n if ((s + s_next) in _this.operatorjson) {\r\n if (bracket.length == 0) {\r\n if ($.trim(str).length > 0) {\r\n cal2.unshift(_this.isFunctionRange($.trim(str), r, c, index, dynamicArray_compute, cellRangeFunction));\r\n }\r\n else if ($.trim(function_str).length > 0) {\r\n cal2.unshift($.trim(function_str));\r\n }\r\n\r\n if (cal1[0] in _this.operatorjson) {\r\n let stackCeilPri = op[cal1[0]];\r\n\r\n while (cal1.length > 0 && stackCeilPri != null) {\r\n cal2.unshift(cal1.shift());\r\n stackCeilPri = op[cal1[0]];\r\n }\r\n }\r\n\r\n cal1.unshift(s + s_next);\r\n\r\n function_str = \"\";\r\n str = \"\";\r\n }\r\n else {\r\n str += s + s_next;\r\n }\r\n\r\n i++;\r\n }\r\n else {\r\n if (bracket.length == 0) {\r\n if ($.trim(str).length > 0) {\r\n cal2.unshift(_this.isFunctionRange($.trim(str), r, c, index, dynamicArray_compute, cellRangeFunction));\r\n }\r\n else if ($.trim(function_str).length > 0) {\r\n cal2.unshift($.trim(function_str));\r\n }\r\n\r\n if (cal1[0] in _this.operatorjson) {\r\n let stackCeilPri = op[cal1[0]];\r\n stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;\r\n\r\n let sPri = op[s];\r\n sPri = sPri == null ? 1000 : sPri;\r\n\r\n while (cal1.length > 0 && sPri >= stackCeilPri) {\r\n cal2.unshift(cal1.shift());\r\n\r\n stackCeilPri = op[cal1[0]];\r\n stackCeilPri = stackCeilPri == null ? 1000 : stackCeilPri;\r\n }\r\n }\r\n\r\n cal1.unshift(s);\r\n\r\n function_str = \"\";\r\n str = \"\";\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n }\r\n else {\r\n if (matchConfig.dquote == 0 && matchConfig.squote == 0) {\r\n\r\n str += $.trim(s);\r\n }\r\n else {\r\n str += s;\r\n }\r\n }\r\n\r\n if (i == funcstack.length - 1) {\r\n let endstr = \"\";\r\n let str_nb = $.trim(str).replace(/'/g, \"\\\\'\");\r\n if (_this.iscelldata(str_nb) && str_nb.substr(0, 1) != \":\") {\r\n // endstr = \"luckysheet_getcelldata('\" + $.trim(str) + \"')\";\r\n endstr = \"luckysheet_getcelldata('\" + str_nb + \"')\";\r\n _this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);\r\n }\r\n else if (str_nb.substr(0, 1) == \":\") {\r\n str_nb = str_nb.substr(1);\r\n if (_this.iscelldata(str_nb)) {\r\n endstr = \"luckysheet_getSpecialReference(false,\" + function_str + \",'\" + str_nb + \"')\";\r\n }\r\n }\r\n else {\r\n str = $.trim(str);\r\n\r\n let regx = /{.*?}/;\r\n if (regx.test(str) && str.substr(0, 1) != '\"' && str.substr(str.length - 1, 1) != '\"') {\r\n let arraytxt = regx.exec(str)[0];\r\n let arraystart = str.search(regx);\r\n let alltxt = \"\";\r\n\r\n if (arraystart > 0) {\r\n endstr += str.substr(0, arraystart);\r\n }\r\n\r\n endstr += \"luckysheet_getarraydata('\" + arraytxt + \"')\";\r\n\r\n if (arraystart + arraytxt.length < str.length) {\r\n endstr += str.substr(arraystart + arraytxt.length, str.length);\r\n }\r\n }\r\n else {\r\n endstr = str;\r\n }\r\n }\r\n\r\n if (endstr.length > 0) {\r\n cal2.unshift(endstr);\r\n }\r\n\r\n if (cal1.length > 0) {\r\n if (function_str.length > 0) {\r\n cal2.unshift(function_str);\r\n function_str = \"\";\r\n }\r\n\r\n while (cal1.length > 0) {\r\n cal2.unshift(cal1.shift());\r\n }\r\n }\r\n\r\n if (cal2.length > 0) {\r\n function_str = _this.calPostfixExpression(cal2);\r\n }\r\n else {\r\n function_str += endstr;\r\n }\r\n }\r\n\r\n i++;\r\n }\r\n // console.log(function_str);\r\n _this.checkSpecialFunctionRange(function_str, r, c, index, dynamicArray_compute, cellRangeFunction);\r\n return function_str;\r\n },\r\n isFunctionRangeSaveChange: function (str, r, c, index, dynamicArray_compute) {\r\n let _this = this;\r\n if (r != null && c != null) {\r\n let range = _this.getcellrange($.trim(str), index);\r\n if (range == null) {\r\n return;\r\n }\r\n let row = range.row,\r\n col = range.column,\r\n sheetIndex = range.sheetIndex;\r\n\r\n if ((r + \"_\" + c) in dynamicArray_compute && (index == sheetIndex || index == null)) {\r\n let isd_range = false;\r\n\r\n for (let d_r = row[0]; d_r <= row[1]; d_r++) {\r\n for (let d_c = col[0]; d_c <= col[1]; d_c++) {\r\n if ((d_r + \"_\" + d_c) in dynamicArray_compute && dynamicArray_compute[d_r + \"_\" + d_c].r == r && dynamicArray_compute[d_r + \"_\" + d_c].c == c) {\r\n isd_range = true;\r\n }\r\n }\r\n }\r\n\r\n if (isd_range) {\r\n _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;\r\n }\r\n else {\r\n _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;\r\n }\r\n }\r\n else {\r\n if (r >= row[0] && r <= row[1] && c >= col[0] && c <= col[1] && (index == sheetIndex || index == null)) {\r\n _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;\r\n }\r\n else {\r\n _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;\r\n }\r\n }\r\n\r\n }\r\n else {\r\n _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;\r\n // let sheetlen = $.trim(str).split(\"!\");\r\n\r\n // if (sheetlen.length > 1) {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || true;//if change sheet, it must be true, but this is very slow\r\n // }\r\n // else {\r\n // _this.isFunctionRangeSave = _this.isFunctionRangeSave || false;\r\n // }\r\n }\r\n },\r\n checkSpecialFunctionRange: function (function_str, r, c, index, dynamicArray_compute, cellRangeFunction) {\r\n\r\n if (function_str.substr(0, 30) == \"luckysheet_getSpecialReference\" || function_str.substr(0, 20) == \"luckysheet_function.\") {\r\n if (function_str.substr(0, 20) == \"luckysheet_function.\") {\r\n let funcName = function_str.split(\".\")[1];\r\n if (funcName != null) {\r\n funcName = funcName.toUpperCase();\r\n if (funcName != \"INDIRECT\" && funcName != \"OFFSET\" && funcName != \"INDEX\") {\r\n return;\r\n }\r\n }\r\n }\r\n try {\r\n Store.calculateSheetIndex = index;\r\n let str = new Function(\"return \" + function_str)();\r\n\r\n if (str instanceof Object && str.startCell != null) {\r\n str = str.startCell;\r\n }\r\n let str_nb = $.trim(str);\r\n // console.log(function_str, tempFunc,str, this.iscelldata(str_nb),this.isFunctionRangeSave,r,c);\r\n if (this.iscelldata(str_nb)) {\r\n if (typeof (cellRangeFunction) == \"function\") {\r\n cellRangeFunction(str_nb);\r\n }\r\n // this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);\r\n // console.log(function_str, str, this.isFunctionRangeSave,r,c);\r\n }\r\n }\r\n catch {\r\n\r\n }\r\n }\r\n\r\n // if (function_str.substr(0, 20) == \"luckysheet_function.\") {\r\n // let funcName = function_str.split(\".\")[1];\r\n // if (funcName != null) {\r\n // funcName = funcName.toUpperCase();\r\n // if (funcName == \"INDIRECT\") {\r\n // let tempFunc = \"luckysheet_indirect_check\" + function_str.substr(30, function_str.length);\r\n\r\n // //tempFunc = tempFunc.replace(/luckysheet_getcelldata/g, \"luckysheet_indirect_check_return\");\r\n\r\n // try {\r\n // Store.calculateSheetIndex = index;\r\n // let str = eval(tempFunc);\r\n\r\n // if(str instanceof Object && str.data!=null){\r\n // str = str.data.v;\r\n // }\r\n // let str_nb = $.trim(str);\r\n // // console.log(function_str, tempFunc,str, this.iscelldata(str_nb),this.isFunctionRangeSave,r,c);\r\n // if (this.iscelldata(str_nb)) {\r\n // if(typeof(cellRangeFunction)==\"function\"){\r\n // cellRangeFunction(str_nb);\r\n // }\r\n // this.isFunctionRangeSaveChange(str, r, c, index, dynamicArray_compute);\r\n // // console.log(function_str, str, this.isFunctionRangeSave,r,c);\r\n // }\r\n // }\r\n // catch{\r\n\r\n // }\r\n\r\n\r\n // }\r\n // else if (funcName == \"OFFSET\") {\r\n // let tempFunc = \"luckysheet_offset_check\" + function_str.substr(28, function_str.length);\r\n\r\n // try {\r\n // Store.calculateSheetIndex = index;\r\n // let str = eval(tempFunc);\r\n // if(str instanceof Object && str.data!=null){\r\n // str = str.data.v;\r\n // }\r\n // let str_nb = $.trim(str);\r\n // if (this.iscelldata(str_nb)) {\r\n // if(typeof(cellRangeFunction)==\"function\"){\r\n // cellRangeFunction(str_nb);\r\n // }\r\n // this.isFunctionRangeSaveChange(str, r, c, index,dynamicArray_compute);\r\n // //console.log(function_str, str, this.isFunctionRangeSave,r,c);\r\n // }\r\n // }\r\n // catch{\r\n\r\n // }\r\n // //let result = eval(function_str);\r\n\r\n // //console.log(function_str, result);\r\n // }\r\n // }\r\n\r\n // }\r\n },\r\n execvertex: {},\r\n execFunctionGroupData: null,\r\n execFunctionExist: null,\r\n formulaContainSheetList: {},\r\n formulaContainCellList: {},\r\n cellTextToIndexList: {},\r\n addToCellList: function (formulaTxt, cellstring) {\r\n if (formulaTxt == null || formulaTxt.length == 0 || cellstring == null || cellstring.length == 0) {\r\n return;\r\n }\r\n if (this.formulaContainCellList == null) {\r\n this.formulaContainCellList = {};\r\n }\r\n\r\n // formulaTxt = formulaTxt.toUpperCase();\r\n if (this.formulaContainCellList[formulaTxt] == null) {\r\n this.formulaContainCellList[formulaTxt] = {};\r\n }\r\n\r\n this.formulaContainCellList[formulaTxt][cellstring] = 1;\r\n },\r\n addToCellIndexList: function (txt, infoObj) {\r\n if (txt == null || txt.length == 0 || infoObj == null) {\r\n return;\r\n }\r\n if (this.cellTextToIndexList == null) {\r\n this.cellTextToIndexList = {};\r\n }\r\n\r\n if (txt.indexOf(\"!\") > -1) {\r\n txt = txt.replace(/\\\\'/g, \"'\").replace(/''/g, \"'\");\r\n this.cellTextToIndexList[txt] = infoObj;\r\n }\r\n else {\r\n this.cellTextToIndexList[txt + \"_\" + infoObj.sheetIndex] = infoObj;\r\n }\r\n\r\n // console.log(this.cellTextToIndexList);\r\n },\r\n addToSheetIndexList: function (formulaTxt, sheetIndex, obIndex) {\r\n if (formulaTxt == null || formulaTxt.length == 0) {\r\n return;\r\n }\r\n\r\n if (sheetIndex == null || sheetIndex.length == 0) {\r\n sheetIndex = Store.currentSheetIndex;\r\n }\r\n\r\n if (obIndex == null || obIndex.length == 0) {\r\n obIndex = \"\";\r\n }\r\n\r\n if (this.formulaContainSheetList == null) {\r\n this.formulaContainSheetList = {};\r\n }\r\n\r\n if (this.formulaContainSheetList[formulaTxt] == null) {\r\n this.formulaContainSheetList[formulaTxt] = {};\r\n }\r\n\r\n this.formulaContainSheetList[formulaTxt][sheetIndex] = obIndex;\r\n },\r\n execFunctionGlobalData: {},\r\n execFunctionGroupForce: function (isForce) {\r\n if (isForce) {\r\n this.execFunctionGroup(undefined, undefined, undefined, undefined, undefined, true);\r\n }\r\n else {\r\n this.execFunctionGroup();\r\n }\r\n },\r\n execFunctionGroup: function (origin_r, origin_c, value, index, data, isForce = false) {\r\n let _this = this;\r\n\r\n if (data == null) {\r\n data = Store.flowdata;\r\n }\r\n\r\n if (!window.luckysheet_compareWith) {\r\n window.luckysheet_compareWith = luckysheet_compareWith;\r\n window.luckysheet_getarraydata = luckysheet_getarraydata;\r\n window.luckysheet_getcelldata = luckysheet_getcelldata;\r\n window.luckysheet_parseData = luckysheet_parseData;\r\n window.luckysheet_getValue = luckysheet_getValue;\r\n window.luckysheet_indirect_check = luckysheet_indirect_check;\r\n window.luckysheet_indirect_check_return = luckysheet_indirect_check_return;\r\n window.luckysheet_offset_check = luckysheet_offset_check;\r\n window.luckysheet_calcADPMM = luckysheet_calcADPMM;\r\n window.luckysheet_getSpecialReference = luckysheet_getSpecialReference;\r\n }\r\n\r\n if (_this.execFunctionGlobalData == null) {\r\n _this.execFunctionGlobalData = {};\r\n }\r\n // let luckysheetfile = getluckysheetfile();\r\n // let dynamicArray_compute = luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray_compute\"] == null ? {} : luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray_compute\"];\r\n\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n if (value != null) {\r\n //此处setcellvalue 中this.execFunctionGroupData会保存想要更新的值,本函数结尾不要设为null,以备后续函数使用\r\n // setcellvalue(origin_r, origin_c, _this.execFunctionGroupData, value);\r\n let cellCache = [[{ v: null }]];\r\n setcellvalue(0, 0, cellCache, value);\r\n _this.execFunctionGlobalData[origin_r + \"_\" + origin_c + \"_\" + index] = cellCache[0][0];\r\n\r\n }\r\n\r\n //{ \"r\": r, \"c\": c, \"index\": index, \"func\": func}\r\n let calcChains = _this.getAllFunctionGroup(),\r\n formulaObjects = {};\r\n\r\n let sheets = getluckysheetfile();\r\n let sheetData = {};\r\n for (let i = 0; i < sheets.length; i++) {\r\n let sheet = sheets[i];\r\n sheetData[sheet.index] = sheet.data;\r\n }\r\n\r\n //把修改涉及的单元格存储为对象\r\n let updateValueOjects = {}, updateValueArray = [];\r\n if (_this.execFunctionExist == null) {\r\n let key = \"r\" + origin_r + \"c\" + origin_c + \"i\" + index;\r\n updateValueOjects[key] = 1;\r\n }\r\n else {\r\n for (let x = 0; x < _this.execFunctionExist.length; x++) {\r\n let cell = _this.execFunctionExist[x];\r\n let key = \"r\" + cell.r + \"c\" + cell.c + \"i\" + cell.i;\r\n updateValueOjects[key] = 1;\r\n }\r\n }\r\n\r\n let arrayMatchCache = {};\r\n let arrayMatch = function (formulaArray, formulaObjects, updateValueOjects, func) {\r\n for (let a = 0; a < formulaArray.length; a++) {\r\n let range = formulaArray[a];\r\n let cacheKey = \"r\" + range.row[0] + \"\" + range.row[1] + \"c\" + range.column[0] + \"\" + range.column[1] + \"index\" + range.sheetIndex;\r\n if (cacheKey in arrayMatchCache) {\r\n let amc = arrayMatchCache[cacheKey];\r\n // console.log(amc);\r\n amc.forEach((item) => {\r\n func(item.key, item.r, item.c, item.sheetIndex);\r\n });\r\n }\r\n else {\r\n let functionArr = [];\r\n for (let r = range.row[0]; r <= range.row[1]; r++) {\r\n for (let c = range.column[0]; c <= range.column[1]; c++) {\r\n let key = \"r\" + r + \"c\" + c + \"i\" + range.sheetIndex;\r\n func(key, r, c, range.sheetIndex);\r\n if ((formulaObjects && key in formulaObjects) || (updateValueOjects && key in updateValueOjects)) {\r\n functionArr.push({\r\n key: key,\r\n r: r,\r\n c: c,\r\n sheetIndex: range.sheetIndex\r\n });\r\n }\r\n }\r\n }\r\n\r\n if (formulaObjects || updateValueOjects) {\r\n arrayMatchCache[cacheKey] = functionArr;\r\n }\r\n }\r\n }\r\n }\r\n\r\n let existsChildFormulaMatch = {}, ii = 0;\r\n\r\n //创建公式缓存及其范围的缓存\r\n // console.time(\"1\");\r\n for (let i = 0; i < calcChains.length; i++) {\r\n let formulaCell = calcChains[i];\r\n let key = \"r\" + formulaCell.r + \"c\" + formulaCell.c + \"i\" + formulaCell.index;\r\n let calc_funcStr = getcellFormula(formulaCell.r, formulaCell.c, formulaCell.index);\r\n if (calc_funcStr == null) {\r\n continue;\r\n }\r\n let txt1 = calc_funcStr.toUpperCase();\r\n let isOffsetFunc = txt1.indexOf(\"INDIRECT(\") > -1 || txt1.indexOf(\"OFFSET(\") > -1 || txt1.indexOf(\"INDEX(\") > -1;\r\n let formulaArray = [];\r\n\r\n if (isOffsetFunc) {\r\n this.isFunctionRange(calc_funcStr, null, null, formulaCell.index, null, function (str_nb) {\r\n let range = _this.getcellrange($.trim(str_nb), formulaCell.index);\r\n if (range != null) {\r\n formulaArray.push(range);\r\n }\r\n });\r\n }\r\n else if (!(calc_funcStr.substr(0, 2) == '=\"' && calc_funcStr.substr(calc_funcStr.length - 1, 1) == '\"')) {\r\n //let formulaTextArray = calc_funcStr.split(/==|!=|<>|<=|>=|[,()=+-\\/*%&^><]/g);//无法正确分割单引号或双引号之间有==、!=、-等运算符的情况。导致如='1-2'!A1公式中表名1-2的A1单元格内容更新后,公式的值不更新的bug\r\n //解决='1-2'!A1+5会被calc_funcStr.split(/==|!=|<>|<=|>=|[,()=+-\\/*%&^><]/g)分割成[\"\",\"'1\",\"2'!A1\",5]的错误情况\r\n let point = 0;//指针\r\n let squote = -1;//双引号\r\n let dquote = -1;//单引号\r\n let formulaTextArray = [];\r\n let sq_end_array = [];//保存了配对的单引号在formulaTextArray的index索引。\r\n let calc_funcStr_length = calc_funcStr.length;\r\n for (let i = 0; i < calc_funcStr_length; i++) {\r\n let char = calc_funcStr.charAt(i);\r\n if (char == \"'\" && dquote == -1) {\r\n //如果是单引号开始\r\n if (squote == -1) {\r\n if (point != i) {\r\n formulaTextArray.push(...calc_funcStr.substring(point, i).split(/==|!=|<>|<=|>=|[,()=+-\\/*%&\\^><]/));\r\n }\r\n squote = i;\r\n point = i;\r\n }\r\n else//单引号结束\r\n {\r\n //if (squote == i - 1)//配对的单引号后第一个字符不能是单引号\r\n //{\r\n // ;//到此处说明公式错误\r\n //}\r\n //如果是''代表着输出'\r\n if (i < calc_funcStr_length - 1 && calc_funcStr.charAt(i + 1) == \"'\") {\r\n i++;\r\n }\r\n else {//如果下一个字符不是'代表单引号结束\r\n //if (calc_funcStr.charAt(i - 1) == \"'\") {//配对的单引号后最后一个字符不能是单引号\r\n // ;//到此处说明公式错误\r\n point = i + 1;\r\n formulaTextArray.push(calc_funcStr.substring(squote, point));\r\n sq_end_array.push(formulaTextArray.length - 1);\r\n squote = -1;\r\n //} else {\r\n // point = i + 1;\r\n // formulaTextArray.push(calc_funcStr.substring(squote, point));\r\n // sq_end_array.push(formulaTextArray.length - 1);\r\n // squote = -1;\r\n //}\r\n }\r\n\r\n }\r\n }\r\n if (char == '\"' && squote == -1) {\r\n //如果是双引号开始\r\n if (dquote == -1) {\r\n if (point != i) {\r\n formulaTextArray.push(...calc_funcStr.substring(point, i).split(/==|!=|<>|<=|>=|[,()=+-\\/*%&\\^><]/));\r\n }\r\n dquote = i;\r\n point = i;\r\n }\r\n else {\r\n //如果是\"\"代表着输出\"\r\n if (i < calc_funcStr_length - 1 && calc_funcStr.charAt(i + 1) == '\"') {\r\n i++;\r\n }\r\n else {//双引号结束\r\n point = i + 1;\r\n formulaTextArray.push(calc_funcStr.substring(dquote, point));\r\n dquote = -1;\r\n }\r\n }\r\n }\r\n }\r\n if (point != calc_funcStr_length) {\r\n formulaTextArray.push(...calc_funcStr.substring(point, calc_funcStr_length).split(/==|!=|<>|<=|>=|[,()=+-\\/*%&\\^><]/))\r\n }\r\n //拼接所有配对单引号及之后一个单元格内容,例如[\"'1-2'\",\"!A1\"]拼接为[\"'1-2'!A1\"]\r\n for (let i = sq_end_array.length - 1; i >= 0; i--) {\r\n if (sq_end_array[i] != formulaTextArray.length - 1) {\r\n formulaTextArray[sq_end_array[i]] = formulaTextArray[sq_end_array[i]] + formulaTextArray[sq_end_array[i] + 1];\r\n formulaTextArray.splice(sq_end_array[i] + 1, 1);\r\n }\r\n }\r\n //至此=SUM('1-2'!A1:A2&\"'1-2'!A2\")由原来的[\"\",\"SUM\",\"'1\",\"2'!A1:A2\",\"\",\"\"'1\",\"2'!A2\"\"]更正为[\"\",\"SUM\",\"\",\"'1-2'!A1:A2\",\"\",\"\",\"\"'1-2'!A2\"\"]\r\n\r\n for (let i = 0; i < formulaTextArray.length; i++) {\r\n let t = formulaTextArray[i];\r\n if (t.length <= 1) {\r\n continue;\r\n }\r\n\r\n if (t.substr(0, 1) == '\"' && t.substr(t.length - 1, 1) == '\"' && !_this.iscelldata(t)) {\r\n continue;\r\n }\r\n\r\n let range = _this.getcellrange($.trim(t), formulaCell.index);\r\n\r\n if (range == null) {\r\n continue;\r\n }\r\n\r\n formulaArray.push(range);\r\n }\r\n }\r\n\r\n let item = {\r\n formulaArray: formulaArray,\r\n calc_funcStr: calc_funcStr,\r\n key: key,\r\n r: formulaCell.r,\r\n c: formulaCell.c,\r\n index: formulaCell.index,\r\n parents: {},\r\n chidren: {},\r\n color: \"w\"\r\n }\r\n\r\n formulaObjects[key] = item;\r\n\r\n\r\n\r\n // if(isForce){\r\n // updateValueArray.push(item);\r\n // }\r\n // else{\r\n // arrayMatch(formulaArray, null, function(key){\r\n // if(key in updateValueOjects){\r\n // updateValueArray.push(item);\r\n // }\r\n // });\r\n // }\r\n\r\n }\r\n\r\n // console.timeEnd(\"1\");\r\n\r\n // console.time(\"2\");\r\n //形成一个公式之间引用的图结构\r\n Object.keys(formulaObjects).forEach((key) => {\r\n let formulaObject = formulaObjects[key];\r\n arrayMatch(formulaObject.formulaArray, formulaObjects, updateValueOjects, function (childKey) {\r\n if (childKey in formulaObjects) {\r\n let childFormulaObject = formulaObjects[childKey];\r\n formulaObject.chidren[childKey] = 1;\r\n childFormulaObject.parents[key] = 1;\r\n }\r\n // console.log(childKey,formulaObject.formulaArray);\r\n if (!isForce && childKey in updateValueOjects) {\r\n updateValueArray.push(formulaObject);\r\n }\r\n });\r\n\r\n if (isForce) {\r\n updateValueArray.push(formulaObject);\r\n }\r\n });\r\n\r\n // console.log(formulaObjects)\r\n // console.timeEnd(\"2\");\r\n\r\n\r\n // console.time(\"3\");\r\n let formulaRunList = [];\r\n //计算,采用深度优先遍历公式形成的图结构\r\n\r\n // updateValueArray.forEach((key)=>{\r\n // let formulaObject = formulaObjects[key];\r\n\r\n\r\n // });\r\n\r\n let stack = updateValueArray, existsFormulaRunList = {};\r\n while (stack.length > 0) {\r\n let formulaObject = stack.pop();\r\n\r\n if (formulaObject == null || formulaObject.key in existsFormulaRunList) {\r\n continue;\r\n }\r\n\r\n if (formulaObject.color == \"b\") {\r\n formulaRunList.push(formulaObject);\r\n existsFormulaRunList[formulaObject.key] = 1;\r\n continue;\r\n }\r\n\r\n let cacheStack = [];\r\n Object.keys(formulaObject.parents).forEach((parentKey) => {\r\n let parentFormulaObject = formulaObjects[parentKey];\r\n if (parentFormulaObject != null) {\r\n cacheStack.push(parentFormulaObject);\r\n }\r\n });\r\n\r\n\r\n ii++;\r\n\r\n if (cacheStack.length == 0) {\r\n formulaRunList.push(formulaObject);\r\n existsFormulaRunList[formulaObject.key] = 1;\r\n }\r\n else {\r\n formulaObject.color = \"b\";\r\n stack.push(formulaObject);\r\n stack = stack.concat(cacheStack);\r\n }\r\n }\r\n\r\n formulaRunList.reverse();\r\n\r\n // console.log(formulaObjects, ii)\r\n // console.timeEnd(\"3\");\r\n\r\n // console.time(\"4\");\r\n for (let i = 0; i < formulaRunList.length; i++) {\r\n let formulaCell = formulaRunList[i];\r\n if (formulaCell.level == Math.max) {\r\n continue;\r\n }\r\n\r\n window.luckysheet_getcelldata_cache = null;\r\n let calc_funcStr = formulaCell.calc_funcStr;\r\n\r\n let v = _this.execfunction(calc_funcStr, formulaCell.r, formulaCell.c, formulaCell.index);\r\n\r\n _this.groupValuesRefreshData.push({\r\n \"r\": formulaCell.r,\r\n \"c\": formulaCell.c,\r\n \"v\": v[1],\r\n \"f\": v[2],\r\n \"spe\": v[3],\r\n \"index\": formulaCell.index\r\n });\r\n\r\n // _this.execFunctionGroupData[u.r][u.c] = value;\r\n _this.execFunctionGlobalData[formulaCell.r + \"_\" + formulaCell.c + \"_\" + formulaCell.index] = {\r\n v: v[1],\r\n f: v[2]\r\n };\r\n }\r\n // console.log(formulaRunList);\r\n // console.timeEnd(\"4\");\r\n\r\n _this.execFunctionExist = null;\r\n },\r\n // When set origin_r and origin_c, that mean just refresh cell value link to [origin_r,origin_c] cell\r\n execFunctionGroup1: function (origin_r, origin_c, value, index, data, isForce = false) {\r\n let _this = this;\r\n\r\n if (data == null) {\r\n data = Store.flowdata;\r\n }\r\n\r\n if (!window.luckysheet_compareWith) {\r\n window.luckysheet_compareWith = luckysheet_compareWith;\r\n window.luckysheet_getarraydata = luckysheet_getarraydata;\r\n window.luckysheet_getcelldata = luckysheet_getcelldata;\r\n window.luckysheet_parseData = luckysheet_parseData;\r\n window.luckysheet_getValue = luckysheet_getValue;\r\n window.luckysheet_indirect_check = luckysheet_indirect_check;\r\n window.luckysheet_indirect_check_return = luckysheet_indirect_check_return;\r\n window.luckysheet_offset_check = luckysheet_offset_check;\r\n window.luckysheet_calcADPMM = luckysheet_calcADPMM;\r\n window.luckysheet_getSpecialReference = luckysheet_getSpecialReference;\r\n }\r\n\r\n if (_this.execFunctionGlobalData == null) {\r\n _this.execFunctionGlobalData = {};\r\n }\r\n let luckysheetfile = getluckysheetfile();\r\n let dynamicArray_compute = luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray_compute\"] == null ? {} : luckysheetfile[getSheetIndex(Store.currentSheetIndex)][\"dynamicArray_compute\"];\r\n\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n if (value != null) {\r\n //此处setcellvalue 中this.execFunctionGroupData会保存想要更新的值,本函数结尾不要设为null,以备后续函数使用\r\n // setcellvalue(origin_r, origin_c, _this.execFunctionGroupData, value);\r\n let cellCache = [[{ v: null }]];\r\n setcellvalue(0, 0, cellCache, value);\r\n _this.execFunctionGlobalData[origin_r + \"_\" + origin_c + \"_\" + index] = cellCache[0][0];\r\n\r\n }\r\n\r\n\r\n\r\n //{ \"r\": r, \"c\": c, \"index\": index, \"func\": func}\r\n let group = _this.getAllFunctionGroup(),\r\n vertex1 = {},\r\n stack = [],\r\n count = 0;\r\n\r\n _this.execvertex = {};\r\n if (_this.execFunctionExist == null) {\r\n for (let i = 0; i < group.length; i++) {\r\n let item = group[i];\r\n let file = luckysheetfile[getSheetIndex(item[\"index\"])];\r\n if (file == null) {\r\n continue;\r\n }\r\n let cell = file.data[item.r][item.c];\r\n let calc_funcStr = getcellFormula(item.r, item.c, item.index);\r\n if (cell != null && cell.f != null && cell.f == calc_funcStr) {\r\n if (!(item instanceof Object)) {\r\n item = new Function(\"return \" + item)();\r\n }\r\n\r\n item.color = \"w\";\r\n item.parent = null;\r\n item.chidren = {};\r\n item.times = 0;\r\n\r\n vertex1[\"r\" + item.r + \"c\" + item.c + \"i\" + item.index] = item;\r\n _this.isFunctionRangeSave = false;\r\n\r\n if (isForce) {\r\n _this.isFunctionRangeSave = true;\r\n }\r\n else if (origin_r != null && origin_c != null) {\r\n _this.isFunctionRangeSelect(calc_funcStr, origin_r, origin_c, index, dynamicArray_compute);\r\n }\r\n // else {\r\n // _this.isFunctionRangeSelect(calc_funcStr, undefined, undefined ,dynamicArray_compute);\r\n // }\r\n\r\n if (_this.isFunctionRangeSave) {\r\n stack.push(item);\r\n _this.execvertex[\"r\" + item.r + \"c\" + item.c + \"i\" + item.index] = item;\r\n count++;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n for (let x = 0; x < _this.execFunctionExist.length; x++) {\r\n let cell = _this.execFunctionExist[x];\r\n\r\n if (\"r\" + cell.r + \"c\" + cell.c + \"i\" + cell.i in vertex1) {\r\n continue;\r\n }\r\n\r\n for (let i = 0; i < group.length; i++) {\r\n let item = group[i];\r\n let calc_funcStr = getcellFormula(item.r, item.c, item.index);\r\n item.color = \"w\";\r\n item.parent = null;\r\n item.chidren = {};\r\n item.times = 0;\r\n\r\n vertex1[\"r\" + item.r + \"c\" + item.c + \"i\" + item.index] = item;\r\n _this.isFunctionRangeSave = false;\r\n if (isForce) {\r\n _this.isFunctionRangeSave = true;\r\n }\r\n else {\r\n _this.isFunctionRangeSelect(calc_funcStr, cell.r, cell.c, cell.i, dynamicArray_compute);\r\n }\r\n\r\n if (_this.isFunctionRangeSave) {\r\n stack.push(item);\r\n _this.execvertex[\"r\" + item.r + \"c\" + item.c + \"i\" + item.index] = item;\r\n count++;\r\n }\r\n }\r\n }\r\n }\r\n\r\n\r\n // console.time(\"1\");\r\n // console.log(group.length);\r\n // let iii = 0, ii=0;\r\n //先进先出法,构建逆向执行结构树\r\n while (stack.length > 0) {\r\n let u = stack.shift();\r\n let excludeList = {};\r\n _this.getChildrenVertex(u, vertex1, excludeList);\r\n // ii++;\r\n // console.log(JSON.stringify(excludeList));\r\n for (let name in vertex1) {\r\n let item = vertex1[name];\r\n if (item == null) {\r\n continue;\r\n }\r\n\r\n let ukey = \"r\" + u.r + \"c\" + u.c + \"i\" + u.index;\r\n\r\n // if ((u.r == item.r && u.c == item.c && u.index == item.index) ) {\r\n // continue;\r\n // }\r\n\r\n if (name in excludeList) {\r\n continue;\r\n }\r\n\r\n _this.isFunctionRangeSave = false;\r\n\r\n\r\n\r\n let calc_funcStr = getcellFormula(item.r, item.c, item.index);\r\n _this.isFunctionRangeSelect(calc_funcStr, u.r, u.c, u.index, dynamicArray_compute);\r\n\r\n // iii++;\r\n\r\n if (_this.isFunctionRangeSave) {\r\n if (!(name in _this.execvertex)) {\r\n // console.log(JSON.stringify(item), JSON.stringify(u), _this.isFunctionRangeSave);\r\n\r\n stack.push(item);\r\n _this.execvertex[name] = item;\r\n }\r\n\r\n count++;\r\n _this.execvertex[name].chidren[ukey] = 1;\r\n }\r\n }\r\n }\r\n // console.log(iii, ii);\r\n // console.timeEnd(\"1\");\r\n\r\n // console.time(\"2\");\r\n _this.groupValuesRefreshData = [];\r\n let i = 0;\r\n\r\n while (i < count) {\r\n for (let name in _this.execvertex) {\r\n let u = _this.execvertex[name];\r\n\r\n if (u.color == \"w\") {\r\n _this.functionDFS(u);\r\n }\r\n else if (u.color == \"b\") {\r\n i++;\r\n }\r\n }\r\n }\r\n // console.timeEnd(\"2\");\r\n\r\n _this.execFunctionExist = null;\r\n },\r\n //递归得到引用节点\r\n getChildrenVertex: function (u, vertex1, obj) {\r\n let ukey = \"r\" + u.r + \"c\" + u.c + \"i\" + u.index;\r\n obj[ukey] = 1;\r\n if (u.chidren != null) {\r\n for (let key in u.chidren) {\r\n if (vertex1[key] && !(key in obj)) {\r\n this.getChildrenVertex(vertex1[key], vertex1, obj);\r\n }\r\n }\r\n }\r\n },\r\n //深度优先算法,处理多级调用函数\r\n functionDFS: function (u) {\r\n let _this = this;\r\n u.color = \"g\";\r\n u.times += 1;\r\n for (let chd in u.chidren) {\r\n let v = _this.execvertex[chd];\r\n if (v.color == \"w\") {\r\n v.parent = \"r\" + u.r.toString() + \"c\" + u.c.toString() + \"i\" + u.index;\r\n _this.functionDFS(v);\r\n }\r\n }\r\n\r\n u.color = \"b\";\r\n window.luckysheet_getcelldata_cache = null;\r\n let calc_funcStr = getcellFormula(u.r, u.c, u.index);\r\n\r\n let v = _this.execfunction(calc_funcStr, u.r, u.c, u.index);\r\n\r\n // let value = _this.execFunctionGroupData[u.r][u.c];\r\n // if(value == null){\r\n // value = {};\r\n // }\r\n\r\n // value.v = v[1];\r\n // value.f = v[2];\r\n\r\n // let cell = getOrigincell(u.r,u.c,u.index);\r\n\r\n // let spl;\r\n // if(v[3]!=null){\r\n // if(v[3].type==\"sparklines\"){\r\n // window.luckysheetCurrentRow = u.r;\r\n // window.luckysheetCurrentColumn = u.c;\r\n // window.luckysheetCurrentIndex = u.index;\r\n // window.luckysheetCurrentFunction = calc_funcStr;\r\n\r\n // let fp = $.trim(_this.functionParserExe(calc_funcStr));\r\n // let sparklines = eval(fp);\r\n // spl = sparklines;\r\n // }\r\n // }\r\n\r\n _this.groupValuesRefreshData.push({\r\n \"r\": u.r,\r\n \"c\": u.c,\r\n \"v\": v[1],\r\n \"f\": v[2],\r\n \"spe\": v[3],\r\n \"index\": u.index\r\n });\r\n\r\n // _this.execFunctionGroupData[u.r][u.c] = value;\r\n _this.execFunctionGlobalData[u.r + \"_\" + u.c + \"_\" + u.index] = {\r\n v: v[1],\r\n f: v[2]\r\n };\r\n },\r\n groupValuesRefreshData: [],\r\n groupValuesRefresh: function () {\r\n let _this = this;\r\n let luckysheetfile = getluckysheetfile();\r\n if (_this.groupValuesRefreshData.length > 0) {\r\n for (let i = 0; i < _this.groupValuesRefreshData.length; i++) {\r\n let item = _this.groupValuesRefreshData[i];\r\n\r\n // if(item.i != Store.currentSheetIndex){\r\n // continue;\r\n // }\r\n\r\n let file = luckysheetfile[getSheetIndex(item.index)];\r\n let data = file.data;\r\n if (data == null) {\r\n continue;\r\n }\r\n\r\n let updateValue = {};\r\n if (item.spe != null) {\r\n if (item.spe.type == \"sparklines\") {\r\n updateValue.spl = item.spe.data;\r\n }\r\n else if (item.spe.type == \"dynamicArrayItem\") {\r\n file.dynamicArray = _this.insertUpdateDynamicArray(item.spe.data);\r\n }\r\n }\r\n updateValue.v = item.v;\r\n updateValue.f = item.f;\r\n setcellvalue(item.r, item.c, data, updateValue);\r\n server.saveParam(\"v\", item.index, item.v, {\r\n \"r\": item.r,\r\n \"c\": item.c\r\n });\r\n }\r\n\r\n editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据\r\n _this.groupValuesRefreshData = [];\r\n }\r\n },\r\n delFunctionGroup: function (r, c, index) {\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n let luckysheetfile = getluckysheetfile();\r\n let file = luckysheetfile[getSheetIndex(index)];\r\n\r\n let calcChain = file.calcChain;\r\n if (calcChain != null) {\r\n for (let i = 0; i < calcChain.length; i++) {\r\n let calc = calcChain[i];\r\n if (calc.r == r && calc.c == c && calc.index == index) {\r\n calcChain.splice(i, 1);\r\n server.saveParam(\"fc\", index, null, {\r\n \"op\": \"del\",\r\n \"pos\": i\r\n });\r\n break;\r\n }\r\n }\r\n }\r\n\r\n let dynamicArray = file.dynamicArray;\r\n if (dynamicArray != null) {\r\n for (let i = 0; i < dynamicArray.length; i++) {\r\n let calc = dynamicArray[i];\r\n if (calc.r == r && calc.c == c && (calc.index == null || calc.index == index)) {\r\n dynamicArray.splice(i, 1);\r\n server.saveParam(\"ac\", index, null, {\r\n \"op\": \"del\",\r\n \"pos\": i\r\n });\r\n break;\r\n }\r\n }\r\n }\r\n\r\n setluckysheetfile(luckysheetfile);\r\n },\r\n execfunction: function (txt, r, c, index, isrefresh, notInsertFunc) {\r\n let _this = this;\r\n\r\n let _locale = locale();\r\n let locale_formulaMore = _locale.formulaMore;\r\n // console.log(txt,r,c)\r\n if (txt.indexOf(_this.error.r) > -1) {\r\n return [false, _this.error.r, txt];\r\n }\r\n\r\n if (!_this.checkBracketNum(txt)) {\r\n txt += \")\";\r\n }\r\n\r\n if (index == null) {\r\n index = Store.currentSheetIndex;\r\n }\r\n\r\n Store.calculateSheetIndex = index;\r\n\r\n let fp = $.trim(_this.functionParserExe(txt));\r\n //console.log(fp)\r\n if ((fp.substr(0, 20) == \"luckysheet_function.\" || fp.substr(0, 22) == \"luckysheet_compareWith\")) {\r\n _this.functionHTMLIndex = 0;\r\n }\r\n\r\n if (!_this.testFunction(txt, fp) || fp == \"\") {\r\n tooltip.info(\"\", locale_formulaMore.execfunctionError);\r\n return [false, _this.error.n, txt];\r\n }\r\n\r\n\r\n\r\n let result = null;\r\n window.luckysheetCurrentRow = r;\r\n window.luckysheetCurrentColumn = c;\r\n window.luckysheetCurrentIndex = index;\r\n window.luckysheetCurrentFunction = txt;\r\n\r\n let sparklines = null;\r\n\r\n try {\r\n if (fp.indexOf(\"luckysheet_getcelldata\") > -1) {\r\n let funcg = fp.split(\"luckysheet_getcelldata('\");\r\n\r\n for (let i = 1; i < funcg.length; i++) {\r\n let funcgStr = funcg[i].split(\"')\")[0];\r\n let funcgRange = _this.getcellrange(funcgStr);\r\n\r\n if (funcgRange.row[0] < 0 || funcgRange.column[0] < 0) {\r\n return [true, _this.error.r, txt];\r\n }\r\n\r\n if (funcgRange.sheetIndex == Store.calculateSheetIndex && r >= funcgRange.row[0] && r <= funcgRange.row[1] && c >= funcgRange.column[0] && c <= funcgRange.column[1]) {\r\n if (isEditMode()) {\r\n alert(locale_formulaMore.execfunctionSelfError);\r\n }\r\n else {\r\n tooltip.info(\"\", locale_formulaMore.execfunctionSelfErrorResult);\r\n\r\n }\r\n\r\n return [false, 0, txt];\r\n }\r\n }\r\n }\r\n\r\n result = new Function(\"return \" + fp)();\r\n if (typeof (result) == \"string\") {//把之前的非打印控制字符DEL替换回一个双引号。\r\n result = result.replace(/\\x7F/g, '\"');\r\n }\r\n\r\n //加入sparklines的参数项目\r\n if (fp.indexOf(\"SPLINES\") > -1) {\r\n sparklines = result;\r\n result = \"\";\r\n }\r\n }\r\n catch (e) {\r\n let err = e;\r\n //err错误提示处理\r\n console.log(e, fp);\r\n err = _this.errorInfo(err);\r\n result = [_this.error.n, err];\r\n }\r\n\r\n //公式结果是对象,则表示只是选区。如果是单个单元格,则返回其值;如果是多个单元格,则返回 #VALUE!。\r\n if (getObjType(result) == \"object\" && result.startCell != null) {\r\n if (getObjType(result.data) == \"array\") {\r\n result = _this.error.v;\r\n }\r\n else {\r\n if (getObjType(result.data) == \"object\" && !isRealNull(result.data.v)) {\r\n result = result.data.v;\r\n }\r\n else if (!isRealNull(result.data)) {\r\n //只有data长或宽大于1才可能是选区\r\n if (result.cell > 1 || result.rowl > 1) {\r\n result = result.data;\r\n }\r\n else//否则就是单个不为null的没有值v的单元格\r\n {\r\n result = 0;\r\n }\r\n }\r\n else {\r\n result = 0;\r\n }\r\n }\r\n }\r\n\r\n //公式结果是数组,分错误值 和 动态数组 两种情况\r\n let dynamicArrayItem = null;\r\n\r\n if (getObjType(result) == \"array\") {\r\n let isErr = false;\r\n\r\n if (getObjType(result[0]) != \"array\" && result.length == 2) {\r\n isErr = valueIsError(result[0]);\r\n }\r\n\r\n if (!isErr) {\r\n if (getObjType(result[0]) == \"array\" && result.length == 1 && result[0].length == 1) {\r\n result = result[0][0];\r\n }\r\n else {\r\n dynamicArrayItem = { \"r\": r, \"c\": c, \"f\": txt, \"index\": index, \"data\": result };\r\n result = \"\";\r\n }\r\n }\r\n else {\r\n result = result[0];\r\n }\r\n }\r\n\r\n window.luckysheetCurrentRow = null;\r\n window.luckysheetCurrentColumn = null;\r\n window.luckysheetCurrentIndex = null;\r\n window.luckysheetCurrentFunction = null;\r\n\r\n if (r != null && c != null) {\r\n if (isrefresh) {\r\n _this.execFunctionGroup(r, c, result, index);\r\n }\r\n\r\n if (!notInsertFunc) {\r\n _this.insertUpdateFunctionGroup(r, c, index);\r\n }\r\n }\r\n\r\n if (!!sparklines) {\r\n return [true, result, txt, { type: \"sparklines\", data: sparklines }];\r\n }\r\n\r\n if (!!dynamicArrayItem) {\r\n return [true, result, txt, { type: \"dynamicArrayItem\", data: dynamicArrayItem }];\r\n }\r\n\r\n // console.log(result, txt);\r\n\r\n return [true, result, txt];\r\n },\r\n testFunction: function (txt, fp) {\r\n if (txt.substr(0, 1) == \"=\") {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n },\r\n //供function/functionImplementation.js的EVALUATE函数调用。\r\n execstringformula: function (txt, r, c, index) {\r\n let _this = this;\r\n return this.execfunction(txt, r, c, index);\r\n },\r\n functionResizeData: {},\r\n functionResizeStatus: false,\r\n functionResizeTimeout: null,\r\n data_parm_index: 0 //选择公式后参数索引标记\r\n}\r\n\r\nexport default luckysheetformula;","import menuButton from './menuButton';\r\nimport formula from '../global/formula';\r\nimport { dynamicArrayHightShow } from '../global/dynamicArray';\r\nimport { rowLocationByIndex, colLocationByIndex } from '../global/location';\r\nimport browser from '../global/browser';\r\nimport dataVerificationCtrl from './dataVerificationCtrl';\r\nimport { getSheetIndex, getRangetxt } from '../methods/get';\r\nimport Store from '../store';\r\nimport method from '../global/method';\r\nimport locale from '../locale/locale';\r\n\r\n//公式函数 选区实体框\r\nfunction seletedHighlistByindex(id, r1, r2, c1, c2) {\r\n let row = Store.visibledatarow[r2],\r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2],\r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n $('#' + id).css({\r\n \"left\": col_pre,\r\n \"width\": col - col_pre - 1,\r\n \"top\": row_pre,\r\n \"height\": row - row_pre - 1\r\n });\r\n}\r\n\r\n//Set selection highlight\r\nfunction selectHightlightShow(isRestore = false) {\r\n $(\"#luckysheet-cell-selected-boxs\").show();\r\n $(\"#luckysheet-cell-selected-boxs #luckysheet-cell-selected\").siblings(\".luckysheet-cell-selected\").remove();\r\n\r\n if (Store.luckysheet_select_save.length > 0) {\r\n for (let i = 0; i < Store.luckysheet_select_save.length; i++) {\r\n let r1 = Store.luckysheet_select_save[i].row[0],\r\n r2 = Store.luckysheet_select_save[i].row[1];\r\n let c1 = Store.luckysheet_select_save[i].column[0],\r\n c2 = Store.luckysheet_select_save[i].column[1];\r\n\r\n let rf, cf;\r\n if (Store.luckysheet_select_save[i].row_focus == null) {\r\n rf = r1;\r\n }\r\n else {\r\n rf = Store.luckysheet_select_save[i].row_focus;\r\n }\r\n\r\n if (Store.luckysheet_select_save[i].column_focus == null) {\r\n cf = c1;\r\n }\r\n else {\r\n cf = Store.luckysheet_select_save[i].column_focus;\r\n }\r\n\r\n let row = Store.visibledatarow[r2],\r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2],\r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n let row_f = Store.visibledatarow[rf],\r\n row_pre_f = rf - 1 == -1 ? 0 : Store.visibledatarow[rf - 1];\r\n let col_f = Store.visibledatacolumn[cf],\r\n col_pre_f = cf - 1 == -1 ? 0 : Store.visibledatacolumn[cf - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, rf, cf);\r\n if (!!margeset) {\r\n row_f = margeset.row[1];\r\n row_pre_f = margeset.row[0];\r\n\r\n col_f = margeset.column[1];\r\n col_pre_f = margeset.column[0];\r\n }\r\n\r\n Store.luckysheet_select_save[i][\"row\"] = [r1, r2];\r\n Store.luckysheet_select_save[i][\"column\"] = [c1, c2];\r\n\r\n Store.luckysheet_select_save[i][\"row_focus\"] = rf;\r\n Store.luckysheet_select_save[i][\"column_focus\"] = cf;\r\n\r\n Store.luckysheet_select_save[i][\"left\"] = col_pre_f;\r\n Store.luckysheet_select_save[i][\"width\"] = col_f - col_pre_f - 1;\r\n Store.luckysheet_select_save[i][\"top\"] = row_pre_f;\r\n Store.luckysheet_select_save[i][\"height\"] = row_f - row_pre_f - 1;\r\n\r\n Store.luckysheet_select_save[i][\"left_move\"] = col_pre;\r\n Store.luckysheet_select_save[i][\"width_move\"] = col - col_pre - 1;\r\n Store.luckysheet_select_save[i][\"top_move\"] = row_pre;\r\n Store.luckysheet_select_save[i][\"height_move\"] = row - row_pre - 1;\r\n\r\n if (i == 0) {\r\n if (Store.luckysheet_select_save.length == 1) {\r\n if (browser.mobilecheck()) {//移动端\r\n $(\"#luckysheet-cell-selected-boxs #luckysheet-cell-selected\").css({\r\n \"left\": Store.luckysheet_select_save[i][\"left_move\"],\r\n \"width\": Store.luckysheet_select_save[i][\"width_move\"],\r\n \"top\": Store.luckysheet_select_save[i][\"top_move\"],\r\n \"height\": Store.luckysheet_select_save[i][\"height_move\"],\r\n \"display\": \"block\",\r\n \"border\": \"1px solid #0188fb\"\r\n })\r\n .find(\".luckysheet-cs-draghandle\")\r\n .css(\"display\", \"block\")\r\n .end()\r\n .find(\".luckysheet-cs-fillhandle\")\r\n .css(\"display\", \"none\")\r\n .end()\r\n .find(\".luckysheet-cs-touchhandle\")\r\n .css(\"display\", \"block\");\r\n }\r\n else {\r\n $(\"#luckysheet-cell-selected-boxs #luckysheet-cell-selected\").css({\r\n \"left\": Store.luckysheet_select_save[i][\"left_move\"],\r\n \"width\": Store.luckysheet_select_save[i][\"width_move\"],\r\n \"top\": Store.luckysheet_select_save[i][\"top_move\"],\r\n \"height\": Store.luckysheet_select_save[i][\"height_move\"],\r\n \"display\": \"block\",\r\n \"border\": \"1px solid #0188fb\"\r\n })\r\n .find(\".luckysheet-cs-draghandle\")\r\n .css(\"display\", \"block\")\r\n .end()\r\n .find(\".luckysheet-cs-fillhandle\")\r\n .css(\"display\", \"block\")\r\n .end()\r\n .find(\".luckysheet-cs-touchhandle\")\r\n .css(\"display\", \"none\");\r\n }\r\n }\r\n else {\r\n $(\"#luckysheet-cell-selected-boxs #luckysheet-cell-selected\").css({\r\n \"left\": Store.luckysheet_select_save[i][\"left_move\"],\r\n \"width\": Store.luckysheet_select_save[i][\"width_move\"],\r\n \"top\": Store.luckysheet_select_save[i][\"top_move\"],\r\n \"height\": Store.luckysheet_select_save[i][\"height_move\"],\r\n \"display\": \"block\",\r\n \"border\": \"1px solid rgba(1, 136, 251, 0.15)\"\r\n })\r\n .find(\".luckysheet-cs-draghandle\")\r\n .css(\"display\", \"none\")\r\n .end()\r\n .find(\".luckysheet-cs-fillhandle\")\r\n .css(\"display\", \"none\");\r\n }\r\n }\r\n else {\r\n $(\"#luckysheet-cell-selected-boxs\").append('
');\r\n }\r\n\r\n if (i == Store.luckysheet_select_save.length - 1) {\r\n //focus 取选区数组最后一个\r\n $(\"#luckysheet-cell-selected-focus\").css({\r\n \"left\": Store.luckysheet_select_save[i][\"left\"],\r\n \"width\": Store.luckysheet_select_save[i][\"width\"],\r\n \"top\": Store.luckysheet_select_save[i][\"top\"],\r\n \"height\": Store.luckysheet_select_save[i][\"height\"],\r\n \"display\": \"block\"\r\n });\r\n //行列数\r\n luckysheet_count_show(\r\n Store.luckysheet_select_save[i][\"left_move\"],\r\n Store.luckysheet_select_save[i][\"top_move\"],\r\n Store.luckysheet_select_save[i][\"width_move\"],\r\n Store.luckysheet_select_save[i][\"height_move\"],\r\n [r1, r2],\r\n [c1, c2]\r\n );\r\n //左上角选择区域框\r\n formula.fucntionboxshow(rf, cf);\r\n //focus单元格数据验证\r\n dataVerificationCtrl.cellFocus(rf, cf);\r\n }\r\n }\r\n\r\n //行列标题栏\r\n selectTitlesShow(Store.luckysheet_select_save, isRestore);\r\n\r\n //左上角范围显示\r\n selectHelpboxFill();\r\n\r\n //动态数组显示\r\n if (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1]) {\r\n dynamicArrayHightShow(Store.luckysheet_select_save[0].row[0], Store.luckysheet_select_save[0].column[0]);\r\n }\r\n }\r\n\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].luckysheet_select_save = Store.luckysheet_select_save;\r\n // Hook function, change the range selection box, selectHightlightShowillbe triggered multiple times when mousemove is moused, and thhistoricalvalue is used here to throttle\r\n const luckysheet_select_save_previous = JSON.stringify(Store.luckysheet_select_save);\r\n\r\n if(Store.luckysheet_select_save_previous == null |Store.luckysheet_select_save_previous !== luckysheet_select_save_previous){\r\n method.createHookFunction('rangeSelect', Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)], Store.luckysheet_select_save);\r\n }\r\n \r\n Store.luckysheet_select_save_previous = luckysheet_select_save_previous;\r\n}\r\n\r\n//选区标题栏\r\nfunction selectTitlesShow(rangeArr, isRestore = false) {\r\n let s = $.extend(true, [], rangeArr);\r\n\r\n let rowTitleMap = {}, columnTitleMap = {};\r\n for (let i = 0; i < s.length; i++) {\r\n let r1 = s[i][\"row\"][0], r2 = s[i][\"row\"][1], c1 = s[i][\"column\"][0], c2 = s[i][\"column\"][1];\r\n\r\n // if(isRestore){\r\n // let margeset = menuButton.mergeborer(Store.flowdata, r1, c1);\r\n // if(!!margeset){\r\n // r1 = margeset.row[2];\r\n // r2 = margeset.row[3];\r\n\r\n // c1 = margeset.column[2];\r\n // c2 = margeset.column[3];\r\n // }\r\n // }\r\n\r\n //行、列标题栏\r\n rowTitleMap = selectTitlesMap(rowTitleMap, r1, r2);\r\n columnTitleMap = selectTitlesMap(columnTitleMap, c1, c2);\r\n }\r\n\r\n //行标题\r\n $(\"#luckysheet-rows-h-selected\").empty();\r\n\r\n let rowTitleRange = selectTitlesRange(rowTitleMap);\r\n for (let i = 0; i < rowTitleRange.length; i++) {\r\n let r1 = rowTitleRange[i][0], r2 = rowTitleRange[i][rowTitleRange[i].length - 1];\r\n let row = rowLocationByIndex(r2)[1], row_pre = rowLocationByIndex(r1)[0];\r\n\r\n $(\"#luckysheet-rows-h-selected\").append('
');\r\n }\r\n\r\n //列标题\r\n $(\"#luckysheet-cols-h-selected\").empty();\r\n\r\n let columnTitleRange = selectTitlesRange(columnTitleMap);\r\n for (let j = 0; j < columnTitleRange.length; j++) {\r\n let c1 = columnTitleRange[j][0], c2 = columnTitleRange[j][columnTitleRange[j].length - 1];\r\n let col = colLocationByIndex(c2)[1], col_pre = colLocationByIndex(c1)[0];\r\n\r\n $(\"#luckysheet-cols-h-selected\").append('
');\r\n\r\n }\r\n}\r\nfunction selectTitlesMap(rangeMap, range1, range2) {\r\n let map = $.extend(true, {}, rangeMap);\r\n\r\n for (let i = range1; i <= range2; i++) {\r\n if (i in map) {\r\n continue;\r\n }\r\n\r\n map[i] = 0;\r\n }\r\n\r\n return map;\r\n}\r\nfunction selectTitlesRange(map) {\r\n let mapArr = [];\r\n\r\n for (let i in map) {\r\n mapArr.push(i);\r\n }\r\n\r\n mapArr.sort(function (a, b) { return a - b; });\r\n\r\n let rangeArr = [];\r\n let item = [];\r\n\r\n if (mapArr.length > 1) {\r\n for (let j = 1; j < mapArr.length; j++) {\r\n if (mapArr[j] - mapArr[j - 1] == 1) {\r\n item.push(mapArr[j - 1]);\r\n\r\n if (j == mapArr.length - 1) {\r\n item.push(mapArr[j]);\r\n rangeArr.push(item);\r\n }\r\n }\r\n else {\r\n if (j == 1) {\r\n if (j == mapArr.length - 1) {\r\n item.push(mapArr[j - 1]);\r\n rangeArr.push(item);\r\n rangeArr.push([mapArr[j]]);\r\n }\r\n else {\r\n rangeArr.push(mapArr[0]);\r\n }\r\n }\r\n else if (j == mapArr.length - 1) {\r\n item.push(mapArr[j - 1]);\r\n rangeArr.push(item);\r\n rangeArr.push([mapArr[j]]);\r\n }\r\n else {\r\n item.push(mapArr[j - 1]);\r\n rangeArr.push(item);\r\n item = [];\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n rangeArr.push([mapArr[0]]);\r\n }\r\n\r\n return rangeArr;\r\n}\r\n\r\n//选区是否重叠\r\nfunction selectIsOverlap(range) {\r\n if (range == null) {\r\n range = Store.luckysheet_select_save;\r\n }\r\n\r\n let overlap = false;\r\n let map = {};\r\n\r\n for (let s = 0; s < range.length; s++) {\r\n let str_r = range[s].row[0],\r\n end_r = range[s].row[1];\r\n let str_c = range[s].column[0],\r\n end_c = range[s].column[1];\r\n\r\n for (let r = str_r; r <= end_r; r++) {\r\n for (let c = str_c; c <= end_c; c++) {\r\n if ((r + \"_\" + c) in map) {\r\n overlap = true;\r\n break;\r\n }\r\n else {\r\n map[r + \"_\" + c] = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return overlap;\r\n}\r\n// 协同提示框\r\nfunction collaborativeEditBox() {\r\n let all_width = Store.visibledatacolumn;//当前操作页的所有列距离左边的距离\r\n let all_height = Store.visibledatarow;//当前操作页的所有列距离顶部的距离\r\n\r\n Store.cooperativeEdit.changeCollaborationSize.forEach(value => {\r\n if (value.i == Store.currentSheetIndex) {\r\n let count_col = value.v.column;//系统提示框所在的列范围\r\n let change_width = all_width[count_col[0]] -1 //提示框所在列号为0时要改变的宽\r\n if(value.v.column[0] !== 0) {\r\n //用提示框右边框到图表最左的距离减去左边框到图表左边距离再减去边框值\r\n change_width = all_width[count_col[1]] - all_width[count_col[0] - 1] - (count_col[1] - count_col[0] + 1)\r\n }\r\n let count_row = value.v.row;//系统提示框所在的行范围\r\n let change_height = all_height[count_row[0]] -1\r\n if(value.v.row[0] !== 0){\r\n change_height = all_height[count_row[1]] - all_height[count_row[0] - 1] - (count_row[1] - count_row[0] + 1)\r\n }\r\n let range = Store.cooperativeEdit.merge_range //获取单元格合并后的数据\r\n let change_left = all_width[value.v.column[0] - 1] - 1 //提示框离图表最左边的距离\r\n let change_top = all_height[value.v.row[0] - 1] - 1 //提示框离图表最右边的距离\r\n if (Store.config.columnlen !== null) {\r\n //当改变宽的列不在提示框范围内时,将改变列的初始位置改为在提示框范围内\r\n for (let k in Store.config.columnlen) {\r\n if (value.v.column[0] <= k && k <= value.v.column[1]) {\r\n Store.luckysheet_cols_change_size_start[1] = k - 0\r\n break\r\n }\r\n }\r\n }\r\n if (Store.config.rowlen !== null) {\r\n for (let k in Store.config.rowlen) {\r\n if (value.v.row[0] <= k && k <= value.v.row[1]) {\r\n Store.luckysheet_rows_change_size_start[1] = k - 0\r\n break\r\n }\r\n }\r\n }\r\n // 改变列宽的位置在提示框范围内\r\n let flag_width = value.v.column[0] <= Store.luckysheet_cols_change_size_start[1] && Store.luckysheet_cols_change_size_start[1] <= value.v.column[1]\r\n if (flag_width) {\r\n if (Store.luckysheet_cols_change_size_start[1] == 0) {\r\n change_width = all_width[0] - 1\r\n } else {\r\n // 不在提示框范围内\r\n let counts = value.v.column;\r\n change_width = all_width[counts[1]] - all_width[counts[0] - 1] - (counts[1] - counts[0] + 1)\r\n }\r\n }\r\n let flag_height = value.v.row[0] <= Store.luckysheet_rows_change_size_start[1] && Store.luckysheet_rows_change_size_start[1] <= value.v.row[1]\r\n if (flag_height) {\r\n if (Store.luckysheet_rows_change_size_start[1] == 0) {\r\n change_height = all_height[0] - 1\r\n } else {\r\n let counts = value.v.row;\r\n change_height = all_height[counts[1]] - all_height[counts[0] - 1] - (counts[1] - counts[0] + 1)\r\n }\r\n }\r\n //合并单元格时执行\r\n if (Object.keys(range).length > 0 ) {\r\n let flag_sure_merge = false\r\n if(range.v.length > 1) {\r\n flag_sure_merge = Object.keys(range.v[1][0]).length > 0\r\n }\r\n if(range.v[0].length > 1) {\r\n flag_sure_merge = Object.keys(range.v[0][1]).length > 0\r\n }\r\n if(flag_sure_merge) {\r\n // 合并成一个时执行\r\n let flag_merge_width = range.column[0] <= value.v.column[0] && range.column[1] >= value.v.column[1];\r\n change_left = all_width[range.column[0] - 1] - 1\r\n change_top = all_height[range.row[0] - 1] - 1\r\n change_width = all_width[range.column[1]] - 1\r\n change_height = all_height[range.row[1]] - 1\r\n if (flag_merge_width) {\r\n if (range.column[0] !== 0) {\r\n let counts = range.column;\r\n change_width = all_width[counts[1]] - all_width[counts[0] - 1] - (counts[1] - counts[0] + 1)\r\n } else {\r\n change_left = 0\r\n }\r\n value.v.column = range.column\r\n }\r\n let flag_merge_height = range.row[0] <= value.v.row[0] && range.row[1] >= value.v.row[1];\r\n if (flag_merge_height) {\r\n if (range.row[0] !== 0) {\r\n let counts = range.row;\r\n change_height = all_height[counts[1]] - all_height[counts[0] - 1] - (counts[1] - counts[0] + 1)\r\n } else {\r\n change_top = 0\r\n }\r\n value.v.row = range.row\r\n }\r\n } else {\r\n // 合并取消变成多个单元格时执行\r\n change_width = all_width[count_col[0]] - all_width[count_col[0] - 1] - 1\r\n if(count_col[0] === 0) {\r\n change_width = all_width[count_col[0]] - 1\r\n }\r\n change_height = all_height[count_row[0]] - all_height[count_row[0] - 1] - 1\r\n if(count_row[0] === 0) {\r\n change_height = all_height[count_row[0]] - 1\r\n }\r\n }\r\n }\r\n $(\"#luckysheet-multipleRange-show-\" + value.id).css({ \"height\": change_height, \"width\": change_width, \"top\": change_top + 'px', \"left\": change_left + 'px' })\r\n let change_bottom = $(\"#luckysheet-multipleRange-show-\" + value.id)[0].offsetHeight - 1\r\n $(\"#luckysheet-multipleRange-show-\" + value.id + \">.username\").css({ \"bottom\": change_bottom + 'px' })\r\n }\r\n })\r\n}\r\n//复制选区虚线框\r\nfunction selectionCopyShow(range) {\r\n $(\"#luckysheet-selection-copy\").empty();\r\n\r\n if (range == null) {\r\n range = Store.luckysheet_selection_range;\r\n }\r\n\r\n if (range.length > 0) {\r\n for (let s = 0; s < range.length; s++) {\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n let row = Store.visibledatarow[r2],\r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2],\r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n let copyDomHtml = '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
';\r\n $(\"#luckysheet-selection-copy\").append(copyDomHtml);\r\n }\r\n }\r\n}\r\n\r\n//选区行列数显示\r\nfunction luckysheet_count_show(left, top, width, height, rowseleted, columnseleted) {\r\n let rowl = rowseleted[1] - rowseleted[0] + 1,\r\n coll = columnseleted[1] - columnseleted[0] + 1;\r\n let drawWidth = Store.luckysheetTableContentHW[0],\r\n drawHeight = Store.luckysheetTableContentHW[1];\r\n let scrollWidth = $(\"#luckysheet-cell-main\").scrollLeft(),\r\n scrollHeight = $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n const _locale = locale();\r\n const locale_info = _locale.info;\r\n\r\n if (rowl >= 4) {\r\n let leftv = left - 25;\r\n if (leftv < 0) {\r\n leftv = left + 5;\r\n }\r\n\r\n if (leftv < scrollWidth) {\r\n leftv = scrollWidth + 10;\r\n }\r\n\r\n let topv = top + height / 2;\r\n if (height > drawHeight) {\r\n topv = scrollHeight + drawHeight / 2;\r\n }\r\n\r\n $(\"#luckysheet-row-count-show\").css({ \"left\": leftv, \"top\": topv, \"display\": \"block\", \"width\": \"11px\" }).html(\"
\" + rowl.toString().split(\"\").join(\"
\") + \"
\" + locale_info.row + \"
\");\r\n }\r\n else {\r\n $(\"#luckysheet-row-count-show\").hide();\r\n }\r\n\r\n if (coll >= 4) {\r\n let topv = top - 25;\r\n if (topv < 0) {\r\n topv = top + 5;\r\n }\r\n\r\n if (topv < scrollHeight) {\r\n topv = scrollHeight + 10;\r\n }\r\n\r\n let leftv = left + width / 2;\r\n if (width > drawWidth) {\r\n leftv = scrollWidth + drawWidth / 2;\r\n }\r\n\r\n $(\"#luckysheet-column-count-show\").css({ \"left\": leftv, \"top\": topv, \"display\": \"block\" }).text(coll + locale_info.column);\r\n }\r\n else {\r\n $(\"#luckysheet-column-count-show\").hide();\r\n }\r\n}\r\n\r\nfunction selectHelpboxFill() {\r\n let range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rf = range[\"row_focus\"], cf = range[\"column_focus\"];\r\n if (Store.config[\"merge\"] != null && (rf + \"_\" + cf) in Store.config[\"merge\"]) {\r\n $(\"#luckysheet-helpbox-cell\").text(getRangetxt(Store.currentSheetIndex, {\r\n column: [cf, cf],\r\n row: [rf, rf],\r\n }));\r\n }\r\n else {\r\n $(\"#luckysheet-helpbox-cell\").text(getRangetxt(Store.currentSheetIndex, range));\r\n }\r\n\r\n}\r\n\r\nexport {\r\n seletedHighlistByindex,\r\n selectHightlightShow,\r\n selectIsOverlap,\r\n selectionCopyShow,\r\n collaborativeEditBox,\r\n luckysheet_count_show,\r\n selectHelpboxFill\r\n}\r\n","import { replaceHtml } from '../utils/util';\r\nimport { modelHTML } from './constant';\r\nimport menuButton from './menuButton';\r\nimport editor from '../global/editor';\r\nimport tooltip from '../global/tooltip';\r\nimport { isEditMode } from '../global/validate';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\n//更多格式\r\nconst luckysheetMoreFormat = {\r\n moneyFmtList: [\r\n {\r\n \"name\": \"人民币\",\r\n \"pos\": \"before\",\r\n \"value\": \"¥\"\r\n }, {\r\n \"name\": \"美元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"欧元\",\r\n \"pos\": \"before\",\r\n \"value\": \"€\"\r\n }, {\r\n \"name\": \"英镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"£\"\r\n }, {\r\n \"name\": \"港元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"日元\",\r\n \"pos\": \"before\",\r\n \"value\": \"¥\"\r\n }, {\r\n \"name\": \"阿尔巴尼亚列克\",\r\n \"pos\": \"before\",\r\n \"value\": \"Lek\"\r\n }, {\r\n \"name\": \"阿尔及利亚第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"阿富汗尼\",\r\n \"pos\": \"after\",\r\n \"value\": \"Af\"\r\n }, {\r\n \"name\": \"阿根廷比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"阿拉伯联合酋长国迪拉姆\",\r\n \"pos\": \"before\",\r\n \"value\": \"dh\"\r\n }, {\r\n \"name\": \"阿鲁巴弗罗林\",\r\n \"pos\": \"before\",\r\n \"value\": \"Afl\"\r\n }, {\r\n \"name\": \"阿曼里亚尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rial\"\r\n }, {\r\n \"name\": \"阿塞拜疆马纳特\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"埃及镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"£\"\r\n }, {\r\n \"name\": \"埃塞俄比亚比尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Birr\"\r\n }, {\r\n \"name\": \"安哥拉宽扎\",\r\n \"pos\": \"before\",\r\n \"value\": \"Kz\"\r\n }, {\r\n \"name\": \"澳大利亚元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"澳门元\",\r\n \"pos\": \"before\",\r\n \"value\": \"MOP\"\r\n }, {\r\n \"name\": \"巴巴多斯元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"巴布亚新几内亚基那\",\r\n \"pos\": \"before\",\r\n \"value\": \"PGK\"\r\n }, {\r\n \"name\": \"巴哈马元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"巴基斯坦卢比\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rs\"\r\n }, {\r\n \"name\": \"巴拉圭瓜拉尼\",\r\n \"pos\": \"after\",\r\n \"value\": \"Gs\"\r\n }, {\r\n \"name\": \"巴林第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"巴拿马巴波亚\",\r\n \"pos\": \"before\",\r\n \"value\": \"B/\"\r\n }, {\r\n \"name\": \"巴西里亚伊\",\r\n \"pos\": \"before\",\r\n \"value\": \"R$\"\r\n }, {\r\n \"name\": \"白俄罗斯卢布\",\r\n \"pos\": \"after\",\r\n \"value\": \"р\"\r\n }, {\r\n \"name\": \"百慕大元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"保加利亚列弗\",\r\n \"pos\": \"before\",\r\n \"value\": \"lev\"\r\n }, {\r\n \"name\": \"冰岛克朗\",\r\n \"pos\": \"before\",\r\n \"value\": \"kr\"\r\n }, {\r\n \"name\": \"波黑可兑换马克\",\r\n \"pos\": \"before\",\r\n \"value\": \"KM\"\r\n }, {\r\n \"name\": \"波兰兹罗提\",\r\n \"pos\": \"after\",\r\n \"value\": \"z?\"\r\n }, {\r\n \"name\": \"玻利维亚诺\",\r\n \"pos\": \"before\",\r\n \"value\": \"Bs\"\r\n }, {\r\n \"name\": \"伯利兹元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"博茨瓦纳普拉\",\r\n \"pos\": \"before\",\r\n \"value\": \"P\"\r\n }, {\r\n \"name\": \"不丹努扎姆\",\r\n \"pos\": \"before\",\r\n \"value\": \"Nu\"\r\n }, {\r\n \"name\": \"布隆迪法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"FBu\"\r\n }, {\r\n \"name\": \"朝鲜圆\",\r\n \"pos\": \"before\",\r\n \"value\": \"?KP\"\r\n }, {\r\n \"name\": \"丹麦克朗\",\r\n \"pos\": \"after\",\r\n \"value\": \"kr\"\r\n }, {\r\n \"name\": \"东加勒比元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"多米尼加比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"RD$\"\r\n }, {\r\n \"name\": \"俄国卢布\",\r\n \"pos\": \"after\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"厄立特里亚纳克法\",\r\n \"pos\": \"before\",\r\n \"value\": \"Nfk\"\r\n }, {\r\n \"name\": \"非洲金融共同体法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"CFA\"\r\n }, {\r\n \"name\": \"菲律宾比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"斐济元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"佛得角埃斯库多\",\r\n \"pos\": \"before\",\r\n \"value\": \"CVE\"\r\n }, {\r\n \"name\": \"福克兰群岛镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"£\"\r\n }, {\r\n \"name\": \"冈比亚达拉西\",\r\n \"pos\": \"before\",\r\n \"value\": \"GMD\"\r\n }, {\r\n \"name\": \"刚果法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"FrCD\"\r\n }, {\r\n \"name\": \"哥伦比亚比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"哥斯达黎加科朗\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"古巴比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"古巴可兑换比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"圭亚那元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"哈萨克斯坦坚戈\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"海地古德\",\r\n \"pos\": \"before\",\r\n \"value\": \"HTG\"\r\n }, {\r\n \"name\": \"韩元\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"荷属安的列斯盾\",\r\n \"pos\": \"before\",\r\n \"value\": \"NAf.\"\r\n }, {\r\n \"name\": \"洪都拉斯拉伦皮拉\",\r\n \"pos\": \"before\",\r\n \"value\": \"L\"\r\n }, {\r\n \"name\": \"吉布提法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"Fdj\"\r\n }, {\r\n \"name\": \"吉尔吉斯斯坦索姆\",\r\n \"pos\": \"before\",\r\n \"value\": \"KGS\"\r\n }, {\r\n \"name\": \"几内亚法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"FG\"\r\n }, {\r\n \"name\": \"加拿大元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"加纳塞地\",\r\n \"pos\": \"before\",\r\n \"value\": \"GHS\"\r\n }, {\r\n \"name\": \"柬埔寨瑞尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Riel\"\r\n }, {\r\n \"name\": \"捷克克朗\",\r\n \"pos\": \"after\",\r\n \"value\": \"K?\"\r\n }, {\r\n \"name\": \"津巴布韦元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"卡塔尔里亚尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rial\"\r\n }, {\r\n \"name\": \"开曼群岛元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"科摩罗法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"CF\"\r\n }, {\r\n \"name\": \"科威特第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"克罗地亚库纳\",\r\n \"pos\": \"before\",\r\n \"value\": \"kn\"\r\n }, {\r\n \"name\": \"肯尼亚先令\",\r\n \"pos\": \"before\",\r\n \"value\": \"Ksh\"\r\n }, {\r\n \"name\": \"莱索托洛蒂\",\r\n \"pos\": \"before\",\r\n \"value\": \"LSL\"\r\n }, {\r\n \"name\": \"老挝基普\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"黎巴嫩镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"L£\"\r\n }, {\r\n \"name\": \"立陶宛立特\",\r\n \"pos\": \"before\",\r\n \"value\": \"Lt\"\r\n }, {\r\n \"name\": \"利比亚第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"利比亚元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"卢旺达法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"RF\"\r\n }, {\r\n \"name\": \"罗马尼亚列伊\",\r\n \"pos\": \"before\",\r\n \"value\": \"RON\"\r\n }, {\r\n \"name\": \"马达加斯加阿里亚里\",\r\n \"pos\": \"before\",\r\n \"value\": \"Ar\"\r\n }, {\r\n \"name\": \"马尔代夫拉菲亚\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rf\"\r\n }, {\r\n \"name\": \"马拉维克瓦查\",\r\n \"pos\": \"before\",\r\n \"value\": \"MWK\"\r\n }, {\r\n \"name\": \"马来西亚林吉特\",\r\n \"pos\": \"before\",\r\n \"value\": \"RM\"\r\n }, {\r\n \"name\": \"马其顿戴第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"毛里求斯卢比\",\r\n \"pos\": \"before\",\r\n \"value\": \"MURs\"\r\n }, {\r\n \"name\": \"毛里塔尼亚乌吉亚\",\r\n \"pos\": \"before\",\r\n \"value\": \"MRO\"\r\n }, {\r\n \"name\": \"蒙古图格里克\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"孟加拉塔卡\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"秘鲁新索尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"S/\"\r\n }, {\r\n \"name\": \"缅甸开亚特\",\r\n \"pos\": \"before\",\r\n \"value\": \"K\"\r\n }, {\r\n \"name\": \"摩尔多瓦列伊\",\r\n \"pos\": \"before\",\r\n \"value\": \"MDL\"\r\n }, {\r\n \"name\": \"摩洛哥迪拉姆\",\r\n \"pos\": \"before\",\r\n \"value\": \"dh\"\r\n }, {\r\n \"name\": \"莫桑比克梅蒂卡尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"MTn\"\r\n }, {\r\n \"name\": \"墨西哥比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"纳米比亚元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"南非兰特\",\r\n \"pos\": \"before\",\r\n \"value\": \"R\"\r\n }, {\r\n \"name\": \"南苏丹镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"£\"\r\n }, {\r\n \"name\": \"尼加拉瓜科多巴\",\r\n \"pos\": \"before\",\r\n \"value\": \"C$\"\r\n }, {\r\n \"name\": \"尼泊尔卢比\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rs\"\r\n }, {\r\n \"name\": \"尼日利亚奈拉\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"挪威克朗\",\r\n \"pos\": \"after\",\r\n \"value\": \"kr\"\r\n }, {\r\n \"name\": \"乔治亚拉瑞\",\r\n \"pos\": \"before\",\r\n \"value\": \"GEL\"\r\n }, {\r\n \"name\": \"人民币(离岸)\",\r\n \"pos\": \"before\",\r\n \"value\": \"¥\"\r\n }, {\r\n \"name\": \"瑞典克朗\",\r\n \"pos\": \"after\",\r\n \"value\": \"kr\"\r\n }, {\r\n \"name\": \"瑞士法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"CHF\"\r\n }, {\r\n \"name\": \"塞尔维亚第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"塞拉利昂利昂\",\r\n \"pos\": \"before\",\r\n \"value\": \"SLL\"\r\n }, {\r\n \"name\": \"塞舌尔卢比\",\r\n \"pos\": \"before\",\r\n \"value\": \"SCR\"\r\n }, {\r\n \"name\": \"沙特里亚尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rial\"\r\n }, {\r\n \"name\": \"圣多美多布拉\",\r\n \"pos\": \"before\",\r\n \"value\": \"Db\"\r\n }, {\r\n \"name\": \"圣赫勒拿群岛磅\",\r\n \"pos\": \"before\",\r\n \"value\": \"£\"\r\n }, {\r\n \"name\": \"斯里兰卡卢比\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rs\"\r\n }, {\r\n \"name\": \"斯威士兰里兰吉尼\",\r\n \"pos\": \"before\",\r\n \"value\": \"SZL\"\r\n }, {\r\n \"name\": \"苏丹镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"SDG\"\r\n }, {\r\n \"name\": \"苏里南元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"所罗门群岛元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"索马里先令\",\r\n \"pos\": \"before\",\r\n \"value\": \"SOS\"\r\n }, {\r\n \"name\": \"塔吉克斯坦索莫尼\",\r\n \"pos\": \"before\",\r\n \"value\": \"Som\"\r\n }, {\r\n \"name\": \"太平洋法郎\",\r\n \"pos\": \"after\",\r\n \"value\": \"FCFP\"\r\n }, {\r\n \"name\": \"泰国铢\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"坦桑尼亚先令\",\r\n \"pos\": \"before\",\r\n \"value\": \"TSh\"\r\n }, {\r\n \"name\": \"汤加潘加\",\r\n \"pos\": \"before\",\r\n \"value\": \"T$\"\r\n }, {\r\n \"name\": \"特立尼达和多巴哥元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"突尼斯第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"土耳其里拉\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"瓦努阿图瓦图\",\r\n \"pos\": \"before\",\r\n \"value\": \"VUV\"\r\n }, {\r\n \"name\": \"危地马拉格查尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Q\"\r\n }, {\r\n \"name\": \"委内瑞拉博利瓦\",\r\n \"pos\": \"before\",\r\n \"value\": \"Bs\"\r\n }, {\r\n \"name\": \"文莱元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"乌干达先令\",\r\n \"pos\": \"before\",\r\n \"value\": \"UGX\"\r\n }, {\r\n \"name\": \"乌克兰格里夫尼亚\",\r\n \"pos\": \"before\",\r\n \"value\": \"грн.\"\r\n }, {\r\n \"name\": \"乌拉圭比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"乌兹别克斯坦苏姆\",\r\n \"pos\": \"before\",\r\n \"value\": \"so?m\"\r\n }, {\r\n \"name\": \"西萨摩亚塔拉\",\r\n \"pos\": \"before\",\r\n \"value\": \"WST\"\r\n }, {\r\n \"name\": \"新加坡元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"新台币\",\r\n \"pos\": \"before\",\r\n \"value\": \"NT$\"\r\n }, {\r\n \"name\": \"新西兰元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"匈牙利福林\",\r\n \"pos\": \"before\",\r\n \"value\": \"Ft\"\r\n }, {\r\n \"name\": \"叙利亚镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"£\"\r\n }, {\r\n \"name\": \"牙买加元\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"亚美尼亚德拉姆\",\r\n \"pos\": \"before\",\r\n \"value\": \"Dram\"\r\n }, {\r\n \"name\": \"也门里亚尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rial\"\r\n }, {\r\n \"name\": \"伊拉克第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"伊朗里亚尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rial\"\r\n }, {\r\n \"name\": \"以色列新谢克尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"印度卢比\",\r\n \"pos\": \"before\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"印度尼西亚卢比\",\r\n \"pos\": \"before\",\r\n \"value\": \"Rp\"\r\n }, {\r\n \"name\": \"约旦第纳尔\",\r\n \"pos\": \"before\",\r\n \"value\": \"din\"\r\n }, {\r\n \"name\": \"越南盾\",\r\n \"pos\": \"after\",\r\n \"value\": \"?\"\r\n }, {\r\n \"name\": \"赞比亚克瓦查\",\r\n \"pos\": \"before\",\r\n \"value\": \"ZMW\"\r\n }, {\r\n \"name\": \"直布罗陀镑\",\r\n \"pos\": \"before\",\r\n \"value\": \"£\"\r\n }, {\r\n \"name\": \"智利比索\",\r\n \"pos\": \"before\",\r\n \"value\": \"$\"\r\n }, {\r\n \"name\": \"中非金融合作法郎\",\r\n \"pos\": \"before\",\r\n \"value\": \"FCFA\"\r\n }\r\n ],\r\n dateFmtList: [\r\n {\r\n \"name\": \"1930-08-05\",\r\n \"value\": \"yyyy-MM-dd\"\r\n },\r\n {\r\n \"name\": \"1930/8/5\",\r\n \"value\": \"yyyy/MM/dd\"\r\n },\r\n {\r\n \"name\": \"1930年8月5日\",\r\n \"value\": 'yyyy\"年\"M\"月\"d\"日\"'\r\n },\r\n {\r\n \"name\": \"08-05\",\r\n \"value\": \"MM-dd\"\r\n },\r\n {\r\n \"name\": \"8-5\",\r\n \"value\": \"M-d\"\r\n },\r\n {\r\n \"name\": \"8月5日\",\r\n \"value\": 'M\"月\"d\"日\"'\r\n },\r\n {\r\n \"name\": \"13:30:30\",\r\n \"value\": \"h:mm:ss\"\r\n },\r\n {\r\n \"name\": \"13:30\",\r\n \"value\": \"h:mm\"\r\n },\r\n {\r\n \"name\": \"下午01:30\",\r\n \"value\": '上午/下午 hh:mm'\r\n },\r\n {\r\n \"name\": \"下午1:30\",\r\n \"value\": '上午/下午 h:mm'\r\n },\r\n {\r\n \"name\": \"下午1:30:30\",\r\n \"value\": '上午/下午 h:mm:ss'\r\n },\r\n {\r\n \"name\": \"08-05 下午01:30\",\r\n \"value\": \"MM-dd 上午/下午 hh:mm\"\r\n },\r\n // {\r\n // \"name\": \"1930年8月5日星期二\",\r\n // \"value\": ''\r\n // },\r\n // {\r\n // \"name\": \"1930年8月5日星期二 下午1:30:30\",\r\n // \"value\": ''\r\n // },\r\n ],\r\n numFmtList: [\r\n {\r\n \"name\": \"1235\",\r\n \"value\": \"0\"\r\n },\r\n {\r\n \"name\": \"1234.56\",\r\n \"value\": \"0.00\"\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": \"#,##0\"\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": \"#,##0.00\"\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": \"#,##0_);(#,##0)\"\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": \"#,##0_);[Red](#,##0)\"\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": \"#,##0.00_);(#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": \"#,##0.00_);[Red](#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"$1,235\",\r\n \"value\": \"$#,##0_);($#,##0)\"\r\n },\r\n {\r\n \"name\": \"$1,235\",\r\n \"value\": \"$#,##0_);[Red]($#,##0)\"\r\n },\r\n {\r\n \"name\": \"$1,234.56\",\r\n \"value\": \"$#,##0.00_);($#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"$1,234.56\",\r\n \"value\": \"$#,##0.00_);[Red]($#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"1234.56\",\r\n \"value\": \"@\"\r\n },\r\n {\r\n \"name\": \"123456%\",\r\n \"value\": \"0%\"\r\n },\r\n {\r\n \"name\": \"123456.00%\",\r\n \"value\": \"0.00%\"\r\n },\r\n {\r\n \"name\": \"1.23E+03\",\r\n \"value\": \"0.00E+00\"\r\n },\r\n {\r\n \"name\": \"1.2E+3\",\r\n \"value\": \"##0.0E+0\"\r\n },\r\n {\r\n \"name\": \"1234 5/9\",\r\n \"value\": \"# ?/?\"\r\n },\r\n {\r\n \"name\": \"1234 14/25\",\r\n \"value\": \"# ??/??\"\r\n },\r\n {\r\n \"name\": \"$ 1,235\",\r\n \"value\": '_($* #,##0_);_(...($* \"-\"_);_(@_)'\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": '_(* #,##0_);_(*..._(* \"-\"_);_(@_)'\r\n },\r\n {\r\n \"name\": \"$ 1,234.56\",\r\n // \"value\": '_($* #,##0.00_)...* \"-\"??_);_(@_)'\r\n \"value\": '_($* #,##0.00_);_(...($* \"-\"_);_(@_)'\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": '_(* #,##0.00_);...* \"-\"??_);_(@_)'\r\n },\r\n ],\r\n createDialog: function(type){\r\n let _this = this;\r\n\r\n const currencyDetail = locale().currencyDetail;\r\n const locale_format = locale().format;\r\n const locale_button = locale().button;\r\n\r\n this.moneyFmtList = [\r\n {'name': currencyDetail.RMB,'pos': 'before','value': '¥'},\r\n {'name': currencyDetail.USdollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.EUR,'pos': 'before','value': '€'},\r\n {'name': currencyDetail.GBP,'pos': 'before','value': '£'},\r\n {'name': currencyDetail.HK,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.JPY,'pos': 'before','value': '¥'},\r\n {'name': currencyDetail.AlbanianLek,'pos': 'before','value': 'Lek'},\r\n {'name': currencyDetail.AlgerianDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.Afghani,'pos': 'after','value': 'Af'},\r\n {'name': currencyDetail.ArgentinePeso,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.UnitedArabEmiratesDirham,'pos': 'before','value': 'dh'},\r\n {'name': currencyDetail.ArubanFlorin,'pos': 'before','value': 'Afl'},\r\n {'name': currencyDetail.OmaniRial,'pos': 'before','value': 'Rial'},\r\n {'name': currencyDetail.Azerbaijanimanat,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.EgyptianPound,'pos': 'before','value': '£'},\r\n {'name': currencyDetail.EthiopianBirr,'pos': 'before','value': 'Birr'},\r\n {'name': currencyDetail.AngolaKwanza,'pos': 'before','value': 'Kz'},\r\n {'name': currencyDetail.AustralianDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.Patacas,'pos': 'before','value': 'MOP'},\r\n {'name': currencyDetail.BarbadosDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.PapuaNewGuineaKina,'pos': 'before','value': 'PGK'},\r\n {'name': currencyDetail.BahamianDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.PakistanRupee,'pos': 'before','value': 'Rs'},\r\n {'name': currencyDetail.ParaguayanGuarani,'pos': 'after','value': 'Gs'},\r\n {'name': currencyDetail.BahrainiDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.PanamanianBalboa,'pos': 'before','value': 'B/'},\r\n {'name': currencyDetail.Brazilianreal,'pos': 'before','value': 'R$'},\r\n {'name': currencyDetail.Belarusianruble,'pos': 'after','value': 'р'},\r\n {'name': currencyDetail.BermudianDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.BulgarianLev,'pos': 'before','value': 'lev'},\r\n {'name': currencyDetail.IcelandKrona,'pos': 'before','value': 'kr'},\r\n {'name': currencyDetail.BosniaHerzegovinaConvertibleMark,'pos': 'before','value': 'KM'},\r\n {'name': currencyDetail.PolishZloty,'pos': 'after','value': 'z?'},\r\n {'name': currencyDetail.Boliviano,'pos': 'before','value': 'Bs'},\r\n {'name': currencyDetail.BelizeDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.BotswanaPula,'pos': 'before','value': 'P'},\r\n {'name': currencyDetail.NotDannuzhamu,'pos': 'before','value': 'Nu'},\r\n {'name': currencyDetail.BurundiFranc,'pos': 'before','value': 'FBu'},\r\n {'name': currencyDetail.NorthKoreanWon,'pos': 'before','value': '?KP'},\r\n {'name': currencyDetail.DanishKrone,'pos': 'after','value': 'kr'},\r\n {'name': currencyDetail.EastCaribbeanDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.DominicaPeso,'pos': 'before','value': 'RD$'},\r\n {'name': currencyDetail.RussianRuble,'pos': 'after','value': '?'},\r\n {'name': currencyDetail.EritreanNakfa,'pos': 'before','value': 'Nfk'},\r\n {'name': currencyDetail.CFAfranc,'pos': 'before','value': 'CFA'},\r\n {'name': currencyDetail.PhilippinePeso,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.FijiDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.CapeVerdeEscudo,'pos': 'before','value': 'CVE'},\r\n {'name': currencyDetail.FalklandIslandsPound,'pos': 'before','value': '£'},\r\n {'name': currencyDetail.GambianDalasi,'pos': 'before','value': 'GMD'},\r\n {'name': currencyDetail.Congolesefranc,'pos': 'before','value': 'FrCD'},\r\n {'name': currencyDetail.ColombianPeso,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.CostaRicanColon,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.CubanPeso,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.Cubanconvertiblepeso,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.GuyanaDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.KazakhstanTenge,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.Haitiangourde,'pos': 'before','value': 'HTG'},\r\n {'name': currencyDetail.won,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.NetherlandsAntillesGuilder,'pos': 'before','value': 'NAf.'},\r\n {'name': currencyDetail.Honduraslempiras,'pos': 'before','value': 'L'},\r\n {'name': currencyDetail.DjiboutiFranc,'pos': 'before','value': 'Fdj'},\r\n {'name': currencyDetail.KyrgyzstanSom,'pos': 'before','value': 'KGS'},\r\n {'name': currencyDetail.GuineaFranc,'pos': 'before','value': 'FG'},\r\n {'name': currencyDetail.CanadianDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.GhanaianCedi,'pos': 'before','value': 'GHS'},\r\n {'name': currencyDetail.Cambodianriel,'pos': 'before','value': 'Riel'},\r\n {'name': currencyDetail.CzechKoruna,'pos': 'after','value': 'K?'},\r\n {'name': currencyDetail.ZimbabweDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.QatariRiyal,'pos': 'before','value': 'Rial'},\r\n {'name': currencyDetail.CaymanIslandsDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.Comorianfranc,'pos': 'before','value': 'CF'},\r\n {'name': currencyDetail.KuwaitiDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.CroatianKuna,'pos': 'before','value': 'kn'},\r\n {'name': currencyDetail.KenyanShilling,'pos': 'before','value': 'Ksh'},\r\n {'name': currencyDetail.LesothoLoti,'pos': 'before','value': 'LSL'},\r\n {'name': currencyDetail.LaoKip,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.LebanesePound,'pos': 'before','value': 'L£'},\r\n {'name': currencyDetail.Lithuanianlitas,'pos': 'before','value': 'Lt'},\r\n {'name': currencyDetail.LibyanDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.LiberianDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.RwandaFranc,'pos': 'before','value': 'RF'},\r\n {'name': currencyDetail.RomanianLeu,'pos': 'before','value': 'RON'},\r\n {'name': currencyDetail.MalagasyAriary,'pos': 'before','value': 'Ar'},\r\n {'name': currencyDetail.MaldivianRufiyaa,'pos': 'before','value': 'Rf'},\r\n {'name': currencyDetail.MalawiKwacha,'pos': 'before','value': 'MWK'},\r\n {'name': currencyDetail.MalaysianRinggit,'pos': 'before','value': 'RM'},\r\n {'name': currencyDetail.MacedoniawearingDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.MauritiusRupee,'pos': 'before','value': 'MURs'},\r\n {'name': currencyDetail.MauritanianOuguiya,'pos': 'before','value': 'MRO'},\r\n {'name': currencyDetail.MongolianTugrik,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.BangladeshiTaka,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.PeruvianNuevoSol,'pos': 'before','value': 'S/'},\r\n {'name': currencyDetail.MyanmarKyat,'pos': 'before','value': 'K'},\r\n {'name': currencyDetail.MoldovanLeu,'pos': 'before','value': 'MDL'},\r\n {'name': currencyDetail.MoroccanDirham,'pos': 'before','value': 'dh'},\r\n {'name': currencyDetail.MozambiqueMetical,'pos': 'before','value': 'MTn'},\r\n {'name': currencyDetail.MexicanPeso,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.NamibianDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.SouthAfricanRand,'pos': 'before','value': 'R'},\r\n {'name': currencyDetail.SouthSudanesePound,'pos': 'before','value': '£'},\r\n {'name': currencyDetail.NicaraguaCordoba,'pos': 'before','value': 'C$'},\r\n {'name': currencyDetail.NepaleseRupee,'pos': 'before','value': 'Rs'},\r\n {'name': currencyDetail.NigerianNaira,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.NorwegianKrone,'pos': 'after','value': 'kr'},\r\n {'name': currencyDetail.GeorgianLari,'pos': 'before','value': 'GEL'},\r\n {'name': currencyDetail.RenminbiOffshore,'pos': 'before','value': '¥'},\r\n {'name': currencyDetail.SwedishKrona,'pos': 'after','value': 'kr'},\r\n {'name': currencyDetail.SwissFranc,'pos': 'before','value': 'CHF'},\r\n {'name': currencyDetail.SerbianDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.SierraLeone,'pos': 'before','value': 'SLL'},\r\n {'name': currencyDetail.SeychellesRupee,'pos': 'before','value': 'SCR'},\r\n {'name': currencyDetail.SaudiRiyal,'pos': 'before','value': 'Rial'},\r\n {'name': currencyDetail.SaoTomeDobra,'pos': 'before','value': 'Db'},\r\n {'name': currencyDetail.SaintHelenapound,'pos': 'before','value': '£'},\r\n {'name': currencyDetail.SriLankaRupee,'pos': 'before','value': 'Rs'},\r\n {'name': currencyDetail.SwazilandLilangeni,'pos': 'before','value': 'SZL'},\r\n {'name': currencyDetail.SudanesePound,'pos': 'before','value': 'SDG'},\r\n {'name': currencyDetail.Surinamesedollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.SolomonIslandsDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.SomaliShilling,'pos': 'before','value': 'SOS'},\r\n {'name': currencyDetail.TajikistanSomoni,'pos': 'before','value': 'Som'},\r\n {'name': currencyDetail.PacificFranc,'pos': 'after','value': 'FCFP'},\r\n {'name': currencyDetail.ThaiBaht,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.TanzanianShilling,'pos': 'before','value': 'TSh'},\r\n {'name': currencyDetail.TonganPaanga,'pos': 'before','value': 'T$'},\r\n {'name': currencyDetail.TrinidadandTobagoDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.TunisianDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.TurkishLira,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.VanuatuVatu,'pos': 'before','value': 'VUV'},\r\n {'name': currencyDetail.GuatemalanQuetzal,'pos': 'before','value': 'Q'},\r\n {'name': currencyDetail.CommissionBolivar,'pos': 'before','value': 'Bs'},\r\n {'name': currencyDetail.BruneiDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.UgandanShilling,'pos': 'before','value': 'UGX'},\r\n {'name': currencyDetail.UkrainianHryvnia,'pos': 'before','value': 'грн.'},\r\n {'name': currencyDetail.UruguayanPeso,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.Uzbekistansom,'pos': 'before','value': 'so?m'},\r\n {'name': currencyDetail.WesternSamoaTala,'pos': 'before','value': 'WST'},\r\n {'name': currencyDetail.SingaporeDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.NT,'pos': 'before','value': 'NT$'},\r\n {'name': currencyDetail.NewZealandDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.HungarianForint,'pos': 'before','value': 'Ft'},\r\n {'name': currencyDetail.SyrianPound,'pos': 'before','value': '£'},\r\n {'name': currencyDetail.JamaicanDollar,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.ArmenianDram,'pos': 'before','value': 'Dram'},\r\n {'name': currencyDetail.YemeniRial,'pos': 'before','value': 'Rial'},\r\n {'name': currencyDetail.IraqiDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.IranianRial,'pos': 'before','value': 'Rial'},\r\n {'name': currencyDetail.NewIsraeliShekel,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.IndianRupee,'pos': 'before','value': '?'},\r\n {'name': currencyDetail.IndonesianRupiah,'pos': 'before','value': 'Rp'},\r\n {'name': currencyDetail.JordanianDinar,'pos': 'before','value': 'din'},\r\n {'name': currencyDetail.VND,'pos': 'after','value': '?'},\r\n {'name': currencyDetail.ZambianKwacha,'pos': 'before','value': 'ZMW'},\r\n {'name': currencyDetail.GibraltarPound,'pos': 'before','value': '£'},\r\n {'name': currencyDetail.ChileanPeso,'pos': 'before','value': '$'},\r\n {'name': currencyDetail.CFAFrancBEAC,'pos': 'before','value': 'FCFA'}\r\n ];\r\n\r\n this.dateFmtList = locale().dateFmtList;\r\n\r\n this.numFmtList = [\r\n {\r\n \"name\": \"1235\",\r\n \"value\": \"0\"\r\n },\r\n {\r\n \"name\": \"1234.56\",\r\n \"value\": \"0.00\"\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": \"#,##0\"\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": \"#,##0.00\"\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": \"#,##0_);(#,##0)\"\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": \"#,##0_);[Red](#,##0)\"\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": \"#,##0.00_);(#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": \"#,##0.00_);[Red](#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"$1,235\",\r\n \"value\": \"$#,##0_);($#,##0)\"\r\n },\r\n {\r\n \"name\": \"$1,235\",\r\n \"value\": \"$#,##0_);[Red]($#,##0)\"\r\n },\r\n {\r\n \"name\": \"$1,234.56\",\r\n \"value\": \"$#,##0.00_);($#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"$1,234.56\",\r\n \"value\": \"$#,##0.00_);[Red]($#,##0.00)\"\r\n },\r\n {\r\n \"name\": \"1234.56\",\r\n \"value\": \"@\"\r\n },\r\n {\r\n \"name\": \"123456%\",\r\n \"value\": \"0%\"\r\n },\r\n {\r\n \"name\": \"123456.00%\",\r\n \"value\": \"0.00%\"\r\n },\r\n {\r\n \"name\": \"1.23E+03\",\r\n \"value\": \"0.00E+00\"\r\n },\r\n {\r\n \"name\": \"1.2E+3\",\r\n \"value\": \"##0.0E+0\"\r\n },\r\n {\r\n \"name\": \"1234 5/9\",\r\n \"value\": \"# ?/?\"\r\n },\r\n {\r\n \"name\": \"1234 14/25\",\r\n \"value\": \"# ??/??\"\r\n },\r\n {\r\n \"name\": \"$ 1,235\",\r\n \"value\": '_($* #,##0_);_(...($* \"-\"_);_(@_)'\r\n },\r\n {\r\n \"name\": \"1,235\",\r\n \"value\": '_(* #,##0_);_(*..._(* \"-\"_);_(@_)'\r\n },\r\n {\r\n \"name\": \"$ 1,234.56\",\r\n // \"value\": '_($* #,##0.00_)...* \"-\"??_);_(@_)'\r\n \"value\": '_($* #,##0.00_);_(...($* \"-\"_);_(@_)'\r\n },\r\n {\r\n \"name\": \"1,234.56\",\r\n \"value\": '_(* #,##0.00_);...* \"-\"??_);_(@_)'\r\n },\r\n ] \r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-moreFormat-dialog\").remove();\r\n\r\n let title = \"\", content = '';\r\n\r\n if(type == \"morecurrency\"){ //货币\r\n title = locale_format.titleCurrency;\r\n\r\n let listHtml = '';\r\n\r\n for(let i = 0; i < _this.moneyFmtList.length; i++){\r\n let name = _this.moneyFmtList[i][\"name\"];\r\n let pos = _this.moneyFmtList[i][\"pos\"];\r\n let value = _this.moneyFmtList[i][\"value\"];\r\n\r\n listHtml += '
'+\r\n '
'+ name +'
'+\r\n '
'+ value +'
'+\r\n ''+\r\n '
';\r\n }\r\n\r\n content = '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+ listHtml +'
'+\r\n '
';\r\n }\r\n else if(type == \"moredatetime\"){ //日期时间\r\n title = locale_format.titleDateTime;\r\n\r\n let listHtml = '';\r\n\r\n for(let i = 0; i < _this.dateFmtList.length; i++){\r\n let name = _this.dateFmtList[i][\"name\"];\r\n let value = _this.dateFmtList[i][\"value\"];\r\n\r\n listHtml += '
'+\r\n '
'+ name +'
'+\r\n '
'+ value +'
'+\r\n '
';\r\n }\r\n\r\n content = '
'+\r\n '
'+ listHtml +'
'+\r\n '
';\r\n }\r\n else if(type == \"moredigit\"){ //数字\r\n title = locale_format.titleNumber;\r\n\r\n let listHtml = '';\r\n\r\n for(let i = 0; i < _this.numFmtList.length; i++){\r\n let name = _this.numFmtList[i][\"name\"];\r\n let value = _this.numFmtList[i][\"value\"];\r\n\r\n listHtml += '
'+\r\n '
'+ name +'
'+\r\n '
'+ value +'
'+\r\n '
';\r\n }\r\n\r\n content = '
'+\r\n '
'+ listHtml +'
'+\r\n '
';\r\n }\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-moreFormat-dialog\", \r\n \"addclass\": \"luckysheet-moreFormat-dialog\", \r\n \"title\": title, \r\n \"content\": content, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-moreFormat-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 400).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-moreFormat-dialog\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n \r\n $(\"#luckysheet-moreFormat-dialog .listbox .listItem\").eq(0).addClass(\"on\");\r\n },\r\n init: function(){\r\n let _this = this;\r\n\r\n //选择格式\r\n $(document).on(\"click\", \"#luckysheet-moreFormat-dialog .listbox .listItem\", function(){\r\n $(this).addClass(\"on\").siblings().removeClass(\"on\");\r\n });\r\n\r\n //确定\r\n $(document).off(\"click.moreFormatConfirm\").on(\"click.moreFormatConfirm\", \"#luckysheet-moreFormat-dialog #luckysheet-moreFormat-dialog-confirm\", function(){\r\n $(\"#luckysheet-moreFormat-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let value = $(\"#luckysheet-moreFormat-dialog .listbox .listItem.on .value\").text();\r\n let id = $(this).parents(\"#luckysheet-moreFormat-dialog\").find(\".box\").attr(\"id\");\r\n\r\n if(id == \"morecurrency\"){ //货币\r\n if(value.indexOf(\"?\") != -1){\r\n return;\r\n }\r\n\r\n let decimal = parseInt($(\"#luckysheet-moreFormat-dialog .decimal input\").val().trim());\r\n\r\n if(decimal.toString() == \"NaN\" || decimal < 0 || decimal > 9){\r\n if(isEditMode()){\r\n alert(\"小数位数必须在0-9之间!\");\r\n } \r\n else{\r\n tooltip.info(\"小数位数必须在0-9之间!\", \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let str = \"\";\r\n\r\n if(decimal > 0){\r\n for(let i = 1; i <= decimal; i++){\r\n str += \"0\";\r\n }\r\n\r\n str = \"0.\" + str;\r\n }\r\n else{\r\n str = \"#\";\r\n }\r\n\r\n let pos = $(\"#luckysheet-moreFormat-dialog .listbox .listItem.on input:hidden\").val();\r\n\r\n if(pos == \"before\"){\r\n str = '\"' + value + '\" ' + str;\r\n }\r\n else if(pos == \"after\"){\r\n str = str + ' \"' + value + '\"';\r\n }\r\n\r\n menuButton.updateFormat(d, \"ct\", str);\r\n }\r\n else if(id == \"moredatetime\"){ //日期时间\r\n menuButton.updateFormat(d, \"ct\", value);\r\n }\r\n else if(id == \"moredigit\"){ //数字\r\n menuButton.updateFormat(d, \"ct\", value);\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default luckysheetMoreFormat;","import { replaceHtml, chatatABC } from '../utils/util';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { modelHTML, keycode } from './constant';\r\nimport { selectHightlightShow } from './select';\r\nimport sheetmanage from './sheetmanage';\r\nimport { isEditMode } from '../global/validate';\r\nimport { valueShowEs } from '../global/format';\r\nimport { setcellvalue } from '../global/setdata';\r\nimport { jfrefreshgrid } from '../global/refresh';\r\nimport editor from '../global/editor';\r\nimport tooltip from '../global/tooltip';\r\nimport func_methods from '../global/func_methods';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\n//查找替换\r\nconst luckysheetSearchReplace = {\r\n createDialog: function(source){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-search-replace\").remove();\r\n\r\n const _locale = locale();\r\n const locale_findAndReplace = _locale.findAndReplace;\r\n const locale_button = _locale.button;\r\n\r\n let content = '
' +\r\n ''+ locale_findAndReplace.find +'' +\r\n ''+ locale_findAndReplace.replace +'' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
'+ locale_findAndReplace.findTextbox +':
' +\r\n '
'+ locale_findAndReplace.replaceTextbox +':
' +\r\n '
' +\r\n '
' +\r\n '' +\r\n ''+ locale_findAndReplace.regexTextbox +'' +\r\n '
' + \r\n '
' +\r\n '' +\r\n ''+ locale_findAndReplace.wholeTextbox +'' +\r\n '
' + \r\n '
' +\r\n '' +\r\n ''+ locale_findAndReplace.distinguishTextbox +'' +\r\n '
' + \r\n '
' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
';\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-search-replace\", \r\n \"addclass\": \"luckysheet-search-replace\", \r\n \"title\": \"\", \r\n \"content\": content, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\",\r\n \"close\":locale_button.close\r\n }));\r\n let $t = $(\"#luckysheet-search-replace\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 500).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-search-replace\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n \r\n if(source == \"0\"){\r\n $(\"#luckysheet-search-replace #searchTab\").addClass(\"on\").siblings().removeClass(\"on\");\r\n $(\"#luckysheet-search-replace #replaceInput\").hide();\r\n $(\"#luckysheet-search-replace #replaceAllBtn\").hide();\r\n $(\"#luckysheet-search-replace #replaceBtn\").hide();\r\n }\r\n else if(source == \"1\"){\r\n $(\"#luckysheet-search-replace #replaceTab\").addClass(\"on\").siblings().removeClass(\"on\");\r\n $(\"#luckysheet-search-replace #replaceInput\").show();\r\n $(\"#luckysheet-search-replace #replaceAllBtn\").show();\r\n $(\"#luckysheet-search-replace #replaceBtn\").show();\r\n }\r\n },\r\n init: function(){\r\n let _this = this;\r\n\r\n //查找替换 切换\r\n $(document).off(\"click.SRtabBoxspan\").on(\"click.SRtabBoxspan\", \"#luckysheet-search-replace .tabBox span\", function(){\r\n $(this).addClass(\"on\").siblings().removeClass(\"on\");\r\n\r\n let $id = $(this).attr(\"id\");\r\n if($id == \"searchTab\"){\r\n $(\"#luckysheet-search-replace #replaceInput\").hide();\r\n $(\"#luckysheet-search-replace #replaceAllBtn\").hide();\r\n $(\"#luckysheet-search-replace #replaceBtn\").hide();\r\n\r\n $(\"#luckysheet-search-replace #searchInput input\").focus();\r\n }\r\n else if($id == \"replaceTab\"){\r\n $(\"#luckysheet-search-replace #replaceInput\").show();\r\n $(\"#luckysheet-search-replace #replaceAllBtn\").show();\r\n $(\"#luckysheet-search-replace #replaceBtn\").show();\r\n\r\n $(\"#luckysheet-search-replace #replaceInput input\").focus();\r\n }\r\n });\r\n\r\n //查找下一个\r\n $(document).off(\"keyup.SRsearchInput\").on(\"keyup.SRsearchInput\", \"#luckysheet-search-replace #searchInput input\", function(event){\r\n let kcode = event.keyCode;\r\n if(kcode == keycode.ENTER){\r\n _this.searchNext();\r\n }\r\n });\r\n $(document).off(\"click.SRsearchNextBtn\").on(\"click.SRsearchNextBtn\", \"#luckysheet-search-replace #searchNextBtn\", function(){\r\n _this.searchNext();\r\n });\r\n\r\n //查找全部\r\n $(document).off(\"click.SRsearchAllBtn\").on(\"click.SRsearchAllBtn\", \"#luckysheet-search-replace #searchAllBtn\", function(){\r\n _this.searchAll();\r\n });\r\n $(document).off(\"click.SRsearchAllboxItem\").on(\"click.SRsearchAllboxItem\", \"#luckysheet-search-replace #searchAllbox .boxItem\", function(){\r\n $(this).addClass(\"on\").siblings().removeClass(\"on\");\r\n\r\n let r = $(this).attr(\"data-row\");\r\n let c = $(this).attr(\"data-col\");\r\n let sheetIndex = $(this).attr(\"data-sheetIndex\");\r\n\r\n if(sheetIndex != Store.currentSheetIndex){\r\n sheetmanage.changeSheetExec(sheetIndex);\r\n }\r\n\r\n Store.luckysheet_select_save = [\r\n { \"row\": [r, r], \"column\": [c, c] }\r\n ];\r\n\r\n selectHightlightShow();\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft(), \r\n scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), \r\n winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col - winW + 20);\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col_pre - 20);\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row - winH + 20);\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row_pre - 20);\r\n }\r\n });\r\n\r\n //替换\r\n $(document).off(\"click.SRreplaceBtn\").on(\"click.SRreplaceBtn\", \"#luckysheet-search-replace #replaceBtn\", function(){\r\n _this.replace();\r\n });\r\n\r\n //全部替换\r\n $(document).off(\"click.SRreplaceAllBtn\").on(\"click.SRreplaceAllBtn\", \"#luckysheet-search-replace #replaceAllBtn\", function(){\r\n _this.replaceAll();\r\n });\r\n },\r\n searchNext: function(){\r\n let _this = this;\r\n\r\n let searchText = $(\"#luckysheet-search-replace #searchInput input\").val();\r\n if(searchText == \"\" || searchText == null){\r\n return;\r\n }\r\n const _locale = locale();\r\n const locale_findAndReplace = _locale.findAndReplace;\r\n let range;\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n range = [{ \r\n \"row\": [0, Store.flowdata.length - 1], \r\n \"column\": [0, Store.flowdata[0].length - 1] \r\n }];\r\n }\r\n else{\r\n range = $.extend(true, [], Store.luckysheet_select_save); \r\n }\r\n\r\n let searchIndexArr = _this.getSearchIndexArr(searchText, range);\r\n\r\n if(searchIndexArr.length == 0){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.noFindTip);\r\n }\r\n else{\r\n tooltip.info(locale_findAndReplace.noFindTip, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let count = 0;\r\n\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n if(Store.luckysheet_select_save.length == 0){\r\n count = 0;\r\n }\r\n else{\r\n for(let i = 0; i < searchIndexArr.length; i++){\r\n if(searchIndexArr[i].r == Store.luckysheet_select_save[0].row[0] && searchIndexArr[i].c == Store.luckysheet_select_save[0].column[0]){\r\n if(i == searchIndexArr.length - 1){\r\n count = 0;\r\n }\r\n else{\r\n count = i + 1;\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n Store.luckysheet_select_save = [{ \r\n \"row\": [searchIndexArr[count].r, searchIndexArr[count].r], \r\n \"column\": [searchIndexArr[count].c, searchIndexArr[count].c] \r\n }];\r\n }\r\n else{\r\n let rf = range[range.length - 1].row_focus;\r\n let cf = range[range.length - 1].column_focus;\r\n\r\n for(let i = 0; i < searchIndexArr.length; i++){\r\n if(searchIndexArr[i].r == rf && searchIndexArr[i].c == cf){\r\n if(i == searchIndexArr.length - 1){\r\n count = 0;\r\n }\r\n else{\r\n count = i + 1;\r\n }\r\n\r\n break;\r\n }\r\n }\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n if(searchIndexArr[count].r >= r1 && searchIndexArr[count].r <= r2 && searchIndexArr[count].c >= c1 && searchIndexArr[count].c <= c2){\r\n let obj = range[s];\r\n obj[\"row_focus\"] = searchIndexArr[count].r;\r\n obj[\"column_focus\"] = searchIndexArr[count].c;\r\n range.splice(s, 1);\r\n range.push(obj);\r\n\r\n break;\r\n }\r\n }\r\n\r\n Store.luckysheet_select_save = range;\r\n }\r\n\r\n selectHightlightShow();\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft(), \r\n scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), \r\n winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let row = Store.visibledatarow[searchIndexArr[count].r], \r\n row_pre = searchIndexArr[count].r - 1 == -1 ? 0 : Store.visibledatarow[searchIndexArr[count].r - 1];\r\n let col = Store.visibledatacolumn[searchIndexArr[count].c], \r\n col_pre = searchIndexArr[count].c - 1 == -1 ? 0 : Store.visibledatacolumn[searchIndexArr[count].c - 1];\r\n\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col - winW + 20);\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col_pre - 20);\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row - winH + 20);\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row_pre - 20);\r\n }\r\n \r\n if($(\"#searchAllbox\").is(\":visible\")){\r\n $(\"#luckysheet-search-replace #searchAllbox .boxItem\").removeClass(\"on\");\r\n }\r\n },\r\n searchAll: function(){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_findAndReplace = _locale.findAndReplace;\r\n\r\n $(\"#luckysheet-search-replace #searchAllbox\").remove();\r\n \r\n let searchText = $(\"#luckysheet-search-replace #searchInput input\").val();\r\n if(searchText == \"\" || searchText == null){\r\n return;\r\n }\r\n\r\n let range;\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n range = [{ \r\n \"row\": [0, Store.flowdata.length - 1], \r\n \"column\": [0, Store.flowdata[0].length - 1] \r\n }];\r\n }\r\n else{\r\n range = $.extend(true, [], Store.luckysheet_select_save); \r\n }\r\n\r\n let searchIndexArr = _this.getSearchIndexArr(searchText, range);\r\n\r\n if(searchIndexArr.length == 0){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.noFindTip);\r\n }\r\n else{\r\n tooltip.info(locale_findAndReplace.noFindTip, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let searchAllHtml = '';\r\n\r\n for(let i = 0; i < searchIndexArr.length; i++){\r\n let value_ShowEs = valueShowEs(searchIndexArr[i].r, searchIndexArr[i].c, Store.flowdata).toString();\r\n\r\n if(value_ShowEs.indexOf(\" -1 && value_ShowEs.indexOf(\">\") > -1){\r\n searchAllHtml += '
' +\r\n '' + Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].name + '' +\r\n '' + chatatABC(searchIndexArr[i].c) + (searchIndexArr[i].r + 1) + '' +\r\n '' + value_ShowEs + '' +\r\n '
';\r\n }\r\n else{\r\n searchAllHtml += '
' +\r\n '' + Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].name + '' +\r\n '' + chatatABC(searchIndexArr[i].c) + (searchIndexArr[i].r + 1) + '' +\r\n '' + value_ShowEs + '' +\r\n '
';\r\n }\r\n }\r\n \r\n $('
'+ locale_findAndReplace.searchTargetSheet +''+locale_findAndReplace.searchTargetCell+''+locale_findAndReplace.searchTargetValue+'
' + searchAllHtml + '
').appendTo($(\"#luckysheet-search-replace\"));\r\n \r\n $(\"#luckysheet-search-replace #searchAllbox .boxItem\").eq(0).addClass(\"on\").siblings().removeClass(\"on\");\r\n\r\n Store.luckysheet_select_save = [{ \r\n \"row\": [searchIndexArr[0].r, searchIndexArr[0].r], \r\n \"column\": [searchIndexArr[0].c, searchIndexArr[0].c] \r\n }];\r\n\r\n selectHightlightShow();\r\n },\r\n getSearchIndexArr: function(searchText, range){\r\n let arr = [];\r\n let obj = {};\r\n\r\n //正则表达式匹配\r\n let regCheck = false;\r\n if($(\"#luckysheet-search-replace #regCheck input[type='checkbox']\").is(\":checked\")){\r\n regCheck = true;\r\n }\r\n\r\n //整词匹配\r\n let wordCheck = false;\r\n if($(\"#luckysheet-search-replace #wordCheck input[type='checkbox']\").is(\":checked\")){\r\n wordCheck = true;\r\n }\r\n\r\n //区分大小写匹配\r\n let caseCheck = false;\r\n if($(\"#luckysheet-search-replace #caseCheck input[type='checkbox']\").is(\":checked\")){\r\n caseCheck = true;\r\n }\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0], r2 = range[s].row[1];\r\n let c1 = range[s].column[0], c2 = range[s].column[1];\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = Store.flowdata[r][c];\r\n\r\n if(cell != null){\r\n let value = valueShowEs(r, c, Store.flowdata);\r\n\r\n if(value == 0){\r\n value = value.toString();\r\n }\r\n\r\n if(value != null && value != \"\"){\r\n value = value.toString();\r\n\r\n if(wordCheck){ //整词\r\n if(caseCheck){\r\n if(searchText == value){\r\n if(!((r + \"_\" + c) in obj)){\r\n obj[r + \"_\" + c] = 0;\r\n arr.push({\"r\": r, \"c\": c});\r\n }\r\n }\r\n }\r\n else{\r\n let txt = searchText.toLowerCase();\r\n if(txt == value.toLowerCase()){\r\n if(!((r + \"_\" + c) in obj)){\r\n obj[r + \"_\" + c] = 0;\r\n arr.push({\"r\": r, \"c\": c});\r\n }\r\n }\r\n }\r\n }\r\n else if(regCheck){ //正则表达式\r\n let reg;\r\n if(caseCheck){\r\n reg = new RegExp(func_methods.getRegExpStr(searchText), \"g\");\r\n }\r\n else{\r\n reg = new RegExp(func_methods.getRegExpStr(searchText), \"ig\");\r\n }\r\n\r\n if(reg.test(value)){\r\n if(!((r + \"_\" + c) in obj)){\r\n obj[r + \"_\" + c] = 0;\r\n arr.push({\"r\": r, \"c\": c});\r\n }\r\n }\r\n }\r\n else if(caseCheck){ //区分大小写\r\n let reg = new RegExp(func_methods.getRegExpStr(searchText), \"g\");\r\n\r\n if(reg.test(value)){\r\n if(!((r + \"_\" + c) in obj)){\r\n obj[r + \"_\" + c] = 0;\r\n arr.push({\"r\": r, \"c\": c});\r\n }\r\n }\r\n }\r\n else{\r\n let reg = new RegExp(func_methods.getRegExpStr(searchText), \"ig\");\r\n\r\n if(reg.test(value)){\r\n if(!((r + \"_\" + c) in obj)){\r\n obj[r + \"_\" + c] = 0;\r\n arr.push({\"r\": r, \"c\": c});\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return arr;\r\n },\r\n replace: function(){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_findAndReplace = _locale.findAndReplace;\r\n\r\n if(!Store.allowEdit){\r\n tooltip.info(locale_findAndReplace.modeTip, \"\");\r\n return;\r\n }\r\n\r\n let searchText = $(\"#luckysheet-search-replace #searchInput input\").val();\r\n if(searchText == \"\" || searchText == null){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.searchInputTip);\r\n }\r\n else{\r\n tooltip.info(locale_findAndReplace.searchInputTip, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let range;\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n range = [{ \r\n \"row\": [0, Store.flowdata.length - 1], \r\n \"column\": [0, Store.flowdata[0].length - 1] \r\n }];\r\n }\r\n else{\r\n range = $.extend(true, [], Store.luckysheet_select_save); \r\n }\r\n\r\n let searchIndexArr = _this.getSearchIndexArr(searchText, range);\r\n\r\n if(searchIndexArr.length == 0){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.noReplceTip);\r\n }\r\n else{\r\n tooltip.info(locale_findAndReplace.noReplceTip, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let count = null;\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let rf = last.row_focus;\r\n let cf = last.column_focus;\r\n\r\n for(let i = 0; i < searchIndexArr.length; i++){\r\n if(searchIndexArr[i].r == rf && searchIndexArr[i].c == cf){\r\n count = i;\r\n break;\r\n }\r\n }\r\n\r\n if(count == null){\r\n if(searchIndexArr.length == 0){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.noMatchTip);\r\n }\r\n else{\r\n tooltip.info(locale_findAndReplace.noMatchTip, \"\");\r\n }\r\n\r\n return;\r\n }\r\n else{\r\n count = 0;\r\n }\r\n }\r\n\r\n //正则表达式匹配\r\n let regCheck = false;\r\n if($(\"#luckysheet-search-replace #regCheck input[type='checkbox']\").is(\":checked\")){\r\n regCheck = true;\r\n }\r\n\r\n //整词匹配\r\n let wordCheck = false;\r\n if($(\"#luckysheet-search-replace #wordCheck input[type='checkbox']\").is(\":checked\")){\r\n wordCheck = true;\r\n }\r\n\r\n //区分大小写匹配\r\n let caseCheck = false;\r\n if($(\"#luckysheet-search-replace #caseCheck input[type='checkbox']\").is(\":checked\")){\r\n caseCheck = true;\r\n }\r\n\r\n let replaceText = $(\"#luckysheet-search-replace #replaceInput input\").val();\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let r, c;\r\n if(wordCheck){\r\n r = searchIndexArr[count].r;\r\n c = searchIndexArr[count].c;\r\n\r\n let v = replaceText;\r\n\r\n setcellvalue(r, c, d, v);\r\n }\r\n else{\r\n let reg;\r\n if(caseCheck){\r\n reg = new RegExp(func_methods.getRegExpStr(searchText), \"g\");\r\n }\r\n else{\r\n reg = new RegExp(func_methods.getRegExpStr(searchText), \"ig\");\r\n }\r\n\r\n r = searchIndexArr[count].r;\r\n c = searchIndexArr[count].c;\r\n\r\n let v = valueShowEs(r, c, d).toString().replace(reg, replaceText);\r\n\r\n setcellvalue(r, c, d, v);\r\n }\r\n\r\n Store.luckysheet_select_save = [{ \"row\": [r, r], \"column\": [c, c] }];\r\n\r\n if($(\"#luckysheet-search-replace #searchAllbox\").is(\":visible\")){\r\n $(\"#luckysheet-search-replace #searchAllbox\").hide();\r\n }\r\n\r\n jfrefreshgrid(d, Store.luckysheet_select_save);\r\n selectHightlightShow();\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft(), \r\n scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), \r\n winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let row = Store.visibledatarow[r], \r\n row_pre = r - 1 == -1 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c], \r\n col_pre = c - 1 == -1 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col - winW + 20);\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col_pre - 20);\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row - winH + 20);\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row_pre - 20);\r\n }\r\n },\r\n replaceAll: function(){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_findAndReplace = _locale.findAndReplace;\r\n\r\n if(!Store.allowEdit){\r\n tooltip.info(locale_findAndReplace.modeTip, \"\");\r\n return;\r\n }\r\n\r\n let searchText = $(\"#luckysheet-search-replace #searchInput input\").val();\r\n if(searchText == \"\" || searchText == null){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.searchInputTip);\r\n }\r\n else{\r\n tooltip.info(locale_findAndReplace.searchInputTip, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let range;\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n range = [{ \r\n \"row\": [0, Store.flowdata.length - 1], \r\n \"column\": [0, Store.flowdata[0].length - 1] \r\n }];\r\n }\r\n else{\r\n range = $.extend(true, [], Store.luckysheet_select_save); \r\n }\r\n\r\n let searchIndexArr = _this.getSearchIndexArr(searchText, range);\r\n\r\n if(searchIndexArr.length == 0){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.noReplceTip);\r\n }\r\n else{\r\n tooltip.info(locale_findAndReplace.noReplceTip, \"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n //正则表达式匹配\r\n let regCheck = false;\r\n if($(\"#luckysheet-search-replace #regCheck input[type='checkbox']\").is(\":checked\")){\r\n regCheck = true;\r\n }\r\n\r\n //整词匹配\r\n let wordCheck = false;\r\n if($(\"#luckysheet-search-replace #wordCheck input[type='checkbox']\").is(\":checked\")){\r\n wordCheck = true;\r\n }\r\n\r\n //区分大小写匹配\r\n let caseCheck = false;\r\n if($(\"#luckysheet-search-replace #caseCheck input[type='checkbox']\").is(\":checked\")){\r\n caseCheck = true;\r\n }\r\n\r\n let replaceText = $(\"#luckysheet-search-replace #replaceInput input\").val();\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n if(wordCheck){\r\n for(let i = 0; i < searchIndexArr.length; i++){\r\n let r = searchIndexArr[i].r;\r\n let c = searchIndexArr[i].c;\r\n\r\n let v = replaceText;\r\n\r\n setcellvalue(r, c, d, v);\r\n\r\n range.push({ \"row\": [r, r], \"column\": [c, c] });\r\n }\r\n }\r\n else{\r\n let reg;\r\n if(caseCheck){\r\n reg = new RegExp(func_methods.getRegExpStr(searchText), \"g\");\r\n }\r\n else{\r\n reg = new RegExp(func_methods.getRegExpStr(searchText), \"ig\");\r\n }\r\n\r\n for(let i = 0; i < searchIndexArr.length; i++){\r\n let r = searchIndexArr[i].r;\r\n let c = searchIndexArr[i].c;\r\n\r\n let v = valueShowEs(r, c, d).toString().replace(reg, replaceText);\r\n\r\n setcellvalue(r, c, d, v);\r\n\r\n range.push({ \"row\": [r, r], \"column\": [c, c] });\r\n }\r\n }\r\n\r\n if($(\"#luckysheet-search-replace #searchAllbox\").is(\":visible\")){\r\n $(\"#luckysheet-search-replace #searchAllbox\").hide();\r\n }\r\n\r\n jfrefreshgrid(d, range);\r\n\r\n Store.luckysheet_select_save = $.extend(true, [], range);\r\n selectHightlightShow();\r\n\r\n let succeedInfo = replaceHtml(locale_findAndReplace.successTip, { \r\n \"xlength\": searchIndexArr.length\r\n });\r\n if(isEditMode()){\r\n alert(succeedInfo);\r\n }\r\n else{\r\n tooltip.info(succeedInfo, \"\");\r\n }\r\n }\r\n}\r\n\r\nexport default luckysheetSearchReplace;","import { replaceHtml } from '../utils/util';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport { isRealNull } from '../global/validate';\r\nimport { isEditMode } from '../global/validate';\r\nimport tooltip from '../global/tooltip';\r\nimport { modelHTML } from './constant';\r\nimport { selectHightlightShow } from './select';\r\nimport conditionformat from './conditionformat';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\n//定位\r\nconst luckysheetLocationCell = {\r\n createDialog: function(){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-locationCell-dialog\").remove();\r\n\r\n const _locale = locale();\r\n const locale_location = _locale.findAndReplace;\r\n const locale_button = _locale.button;\r\n\r\n let content = '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
';\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-locationCell-dialog\", \r\n \"addclass\": \"luckysheet-locationCell-dialog\", \r\n \"title\": locale_location.location, \r\n \"content\": content, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-locationCell-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 400).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-locationCell-dialog\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n },\r\n init: function(){\r\n let _this = this;\r\n\r\n const locale_location = locale().findAndReplace;\r\n\r\n $(document).on(\"click\", \"#luckysheet-locationCell-dialog .listItem input:radio\", function(e){\r\n $(\"#luckysheet-locationCell-dialog .listItem input:checkbox\").prop(\"disabled\", true);\r\n $(\"#luckysheet-locationCell-dialog .listItem .subbox label\").css(\"color\", \"#666\");\r\n\r\n $(this).siblings(\".subbox\").find(\"input:checkbox\").removeAttr(\"disabled\");\r\n $(this).siblings(\".subbox\").find(\"label\").css(\"color\", \"#000\");\r\n });\r\n\r\n $(document).off(\"click.locationCellConfirm\").on(\"click.locationCellConfirm\", \"#luckysheet-locationCell-dialog #luckysheet-locationCell-dialog-confirm\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-locationCell-dialog\").hide();\r\n\r\n let $radio = $(\"#luckysheet-locationCell-dialog .listItem input:radio:checked\");\r\n let id = $radio.attr(\"id\");\r\n\r\n if(id == \"locationConstant\" || id == \"locationFormula\"){\r\n let $checkbox = $radio.siblings(\".subbox\").find(\"input:checkbox:checked\");\r\n\r\n let value;\r\n if($checkbox.length == 0){\r\n return;\r\n }\r\n else if($checkbox.length == 5){\r\n value = \"all\";\r\n }\r\n else{\r\n let arr = [];\r\n \r\n for(let i = 0; i < $checkbox.length; i++){\r\n if($($checkbox[i]).hasClass(\"date\")){\r\n arr.push(\"d\");\r\n }\r\n else if($($checkbox[i]).hasClass(\"number\")){\r\n arr.push(\"n\");\r\n }\r\n else if($($checkbox[i]).hasClass(\"string\")){\r\n arr.push(\"s,g\");\r\n }\r\n else if($($checkbox[i]).hasClass(\"boolean\")){\r\n arr.push(\"b\");\r\n }\r\n else if($($checkbox[i]).hasClass(\"error\")){\r\n arr.push(\"e\");\r\n }\r\n }\r\n\r\n value = arr.join(\",\");\r\n }\r\n\r\n let range;\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n //单个单元格\r\n range = [{\"row\": [0, Store.flowdata.length - 1], \"column\": [0, Store.flowdata[0].length - 1]}];\r\n }\r\n else{\r\n range = $.extend(true, [], Store.luckysheet_select_save);\r\n }\r\n\r\n _this.apply(range, id, value);\r\n }\r\n else if(id == \"locationStepRow\"){\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1])){\r\n if(isEditMode()){\r\n alert(locale_location.locationTiplessTwoRow);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_location.locationTiplessTwoRow); \r\n }\r\n return; \r\n }\r\n\r\n let range = $.extend(true, [], Store.luckysheet_select_save);\r\n\r\n _this.apply(range, \"locationStepRow\");\r\n }\r\n else if(id == \"locationStepColumn\"){\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n if(isEditMode()){\r\n alert(locale_location.locationTiplessTwoColumn);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_location.locationTiplessTwoColumn); \r\n }\r\n return; \r\n }\r\n\r\n let range = $.extend(true, [], Store.luckysheet_select_save);\r\n\r\n _this.apply(range, \"locationStepColumn\");\r\n }\r\n else{\r\n let range;\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1] && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n //单个单元格\r\n range = [{\"row\": [0, Store.flowdata.length - 1], \"column\": [0, Store.flowdata[0].length - 1]}];\r\n }\r\n else{\r\n range = $.extend(true, [], Store.luckysheet_select_save);\r\n }\r\n\r\n _this.apply(range, id);\r\n }\r\n });\r\n },\r\n apply: function(range, type, value){\r\n const locale_location = locale().findAndReplace; \r\n let rangeArr = [];\r\n\r\n if(type == \"locationFormula\" || type == \"locationConstant\" || type == \"locationNull\"){ //公式 常量 空值\r\n let minR = null, maxR = null, minC = null, maxC = null, cellSave = {};\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let st_r = range[s].row[0],\r\n ed_r = range[s].row[1],\r\n st_c = range[s].column[0],\r\n ed_c = range[s].column[1];\r\n\r\n if(minR == null || minR < st_r){\r\n minR = st_r;\r\n }\r\n if(maxR == null || maxR > ed_r){\r\n maxR = ed_r;\r\n }\r\n if(minC == null || minC < st_c){\r\n minC = st_c;\r\n }\r\n if(maxC == null || maxC > ed_c){\r\n maxC = ed_c;\r\n }\r\n\r\n for(let r = st_r; r <= ed_r; r++){\r\n for(let c = st_c; c <= ed_c; c++){\r\n let cell = Store.flowdata[r][c];\r\n\r\n if(cell != null && cell.mc != null){\r\n cell = Store.flowdata[cell.mc.r][cell.mc.c];\r\n }\r\n\r\n if(type == 'locationFormula' && cell != null && !isRealNull(cell.v) && cell.f != null && (value == 'all' || (cell.ct != null && value.indexOf(cell.ct.t) > -1))){\r\n cellSave[r + '_' + c] = 0;\r\n }\r\n else if(type == 'locationConstant' && cell != null && !isRealNull(cell.v) && (value == 'all' || (cell.ct != null && value.indexOf(cell.ct.t) > -1))){\r\n cellSave[r + '_' + c] = 0;\r\n }\r\n else if(type == 'locationNull' && (cell == null || isRealNull(cell.v))){\r\n cellSave[r + '_' + c] = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n rangeArr = this.getRangeArr(minR, maxR, minC, maxC, cellSave, rangeArr);\r\n }\r\n else if(type == \"locationCF\"){ //条件格式\r\n let index = getSheetIndex(Store.currentSheetIndex);\r\n let ruleArr = Store.luckysheetfile[index][\"luckysheet_conditionformat_save\"];\r\n let data = Store.luckysheetfile[index][\"data\"];\r\n\r\n if(ruleArr == null || ruleArr.length == 0){\r\n if(isEditMode()){\r\n alert(locale_location.locationTipNotFindCell);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_location.locationTipNotFindCell);\r\n }\r\n\r\n return;\r\n }\r\n\r\n computeMap = conditionformat.compute(ruleArr, data);\r\n\r\n if(Object.keys(computeMap).length == 0){\r\n if(isEditMode()){\r\n alert(locale_location.locationTipNotFindCell);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_location.locationTipNotFindCell);\r\n }\r\n\r\n return;\r\n }\r\n\r\n let minR = null, maxR = null, minC = null, maxC = null, cellSave = {};\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let st_r = range[s].row[0],\r\n ed_r = range[s].row[1],\r\n st_c = range[s].column[0],\r\n ed_c = range[s].column[1];\r\n\r\n if(minR == null || minR < st_r){\r\n minR = st_r;\r\n }\r\n if(maxR == null || maxR > ed_r){\r\n maxR = ed_r;\r\n }\r\n if(minC == null || minC < st_c){\r\n minC = st_c;\r\n }\r\n if(maxC == null || maxC > ed_c){\r\n maxC = ed_c;\r\n }\r\n\r\n for(let r = st_r; r <= ed_r; r++){\r\n for(let c = st_c; c <= ed_c; c++){\r\n if((r + '_' + c) in computeMap){\r\n cellSave[r + '_' + c] = 0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n rangeArr = this.getRangeArr(minR, maxR, minC, maxC, cellSave, rangeArr);\r\n }\r\n else if(type == \"locationStepRow\"){ //间隔行\r\n for(let s = 0; s < range.length; s++){\r\n if(range[s].row[0] == range[s].row[1]){\r\n continue;\r\n }\r\n\r\n let st_r = range[s].row[0], ed_r = range[s].row[1];\r\n let st_c = range[s].column[0], ed_c = range[s].column[1];\r\n\r\n for(let r = st_r; r <= ed_r; r++){\r\n if((r - st_r) % 2 == 0){\r\n rangeArr.push({\"row\": [r, r], \"column\": [st_c, ed_c]});\r\n }\r\n }\r\n }\r\n }\r\n else if(type == \"locationStepColumn\"){ //间隔列\r\n for(let s = 0; s < range.length; s++){\r\n if(range[s].column[0] == range[s].column[1]){\r\n continue;\r\n }\r\n\r\n let st_r = range[s].row[0], ed_r = range[s].row[1];\r\n let st_c = range[s].column[0], ed_c = range[s].column[1];\r\n\r\n for(let c = st_c; c <= ed_c; c++){\r\n if((c - st_c) % 2 == 0){\r\n rangeArr.push({\"row\": [st_r, ed_r], \"column\": [c, c]});\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(rangeArr.length == 0){\r\n if(isEditMode()){\r\n alert(locale_location.locationTipNotFindCell);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_location.locationTipNotFindCell); \r\n }\r\n }\r\n else{\r\n Store.luckysheet_select_save = rangeArr;\r\n selectHightlightShow(); \r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft(), \r\n scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let winH = $(\"#luckysheet-cell-main\").height(), \r\n winW = $(\"#luckysheet-cell-main\").width();\r\n\r\n let r1 = Store.luckysheet_select_save[0][\"row\"][0],\r\n r2 = Store.luckysheet_select_save[0][\"row\"][1],\r\n c1 = Store.luckysheet_select_save[0][\"column\"][0],\r\n c2 = Store.luckysheet_select_save[0][\"column\"][1];\r\n\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n if (col - scrollLeft - winW + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col - winW + 20);\r\n }\r\n else if (col_pre - scrollLeft - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col_pre - 20);\r\n }\r\n\r\n if (row - scrollTop - winH + 20 > 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row - winH + 20);\r\n }\r\n else if (row_pre - scrollTop - 20 < 0) {\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row_pre - 20);\r\n }\r\n }\r\n },\r\n getRangeArr(minR, maxR, minC, maxC, cellSave, rangeArr){\r\n if(Object.keys(cellSave).length == 0){\r\n return rangeArr;\r\n }\r\n\r\n let _this = this;\r\n\r\n let stack_str = null, \r\n stack_edr = null, \r\n stack_stc = null, \r\n stack_edc = null;\r\n\r\n for(let r = minR; r <= maxR; r++){\r\n for(let c = minC; c <= maxC; c++){\r\n let cell = Store.flowdata[r][c];\r\n \r\n if((r + '_' + c) in cellSave){\r\n if(cell != null && cell.mc != null){\r\n if(stack_stc == null){\r\n let range = {\r\n 'row': [cell.mc.r, cell.mc.r + cell.mc.rs - 1],\r\n 'column': [cell.mc.c, cell.mc.c + cell.mc.cs - 1]\r\n };\r\n rangeArr.push(range);\r\n cellSave = _this.deleteCellInSave(cellSave, range);\r\n return _this.getRangeArr(minR, maxR, minC, maxC, cellSave, rangeArr);\r\n }\r\n else if(c < stack_edc){\r\n let range = {\r\n 'row': [stack_str, stack_edr],\r\n 'column': [stack_stc, stack_edc]\r\n }\r\n rangeArr.push(range);\r\n cellSave = _this.deleteCellInSave(cellSave, range);\r\n return _this.getRangeArr(minR, maxR, minC, maxC, cellSave, rangeArr);\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n else if(stack_stc == null){\r\n stack_stc = c;\r\n stack_edc = c;\r\n\r\n stack_str = r;\r\n stack_edr = r;\r\n }\r\n else if(c > stack_edc){\r\n stack_edc = c;\r\n }\r\n }\r\n else if(stack_stc != null){\r\n if(cell != null && cell.mc != null){\r\n break;\r\n }\r\n else if(c < stack_stc){\r\n\r\n }\r\n else if(c <= stack_edc){\r\n let range = {\r\n 'row': [stack_str, stack_edr],\r\n 'column': [stack_stc, stack_edc]\r\n }\r\n rangeArr.push(range);\r\n cellSave = _this.deleteCellInSave(cellSave, range);\r\n return _this.getRangeArr(minR, maxR, minC, maxC, cellSave, rangeArr);\r\n }\r\n else{\r\n stack_edr = r;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(stack_stc != null){\r\n let range = {\r\n 'row': [stack_str, stack_edr],\r\n 'column': [stack_stc, stack_edc]\r\n }\r\n rangeArr.push(range);\r\n cellSave = _this.deleteCellInSave(cellSave, range);\r\n return _this.getRangeArr(minR, maxR, minC, maxC, cellSave, rangeArr);\r\n }\r\n },\r\n deleteCellInSave(cellSave, range){\r\n for(let r = range.row[0]; r <= range.row[1]; r++){\r\n for(let c = range.column[0]; c <= range.column[1]; c++){\r\n delete cellSave[r + '_' + c];\r\n }\r\n }\r\n\r\n return cellSave;\r\n }\r\n}\r\n\r\nexport default luckysheetLocationCell;","var isRegExp = require('../internals/is-regexp');\n\nmodule.exports = function (it) {\n if (isRegExp(it)) {\n throw TypeError(\"The method doesn't accept regular expressions\");\n } return it;\n};\n","var wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar MATCH = wellKnownSymbol('match');\n\nmodule.exports = function (METHOD_NAME) {\n var regexp = /./;\n try {\n '/./'[METHOD_NAME](regexp);\n } catch (e) {\n try {\n regexp[MATCH] = false;\n return '/./'[METHOD_NAME](regexp);\n } catch (f) { /* empty */ }\n } return false;\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar notARegExp = require('../internals/not-a-regexp');\nvar requireObjectCoercible = require('../internals/require-object-coercible');\nvar correctIsRegExpLogic = require('../internals/correct-is-regexp-logic');\n\n// `String.prototype.includes` method\n// https://tc39.github.io/ecma262/#sec-string.prototype.includes\n$({ target: 'String', proto: true, forced: !correctIsRegExpLogic('includes') }, {\n includes: function includes(searchString /* , position = 0 */) {\n return !!~String(requireObjectCoercible(this))\n .indexOf(notARegExp(searchString), arguments.length > 1 ? arguments[1] : undefined);\n }\n});\n","/* flatpickr v4.6.6, @license MIT */\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = global || self, global.flatpickr = factory());\n}(this, (function () { 'use strict';\n\n /*! *****************************************************************************\r\n Copyright (c) Microsoft Corporation.\r\n\r\n Permission to use, copy, modify, and/or distribute this software for any\r\n purpose with or without fee is hereby granted.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\n REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\n AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\n INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\n LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\n OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\n PERFORMANCE OF THIS SOFTWARE.\r\n ***************************************************************************** */\r\n\r\n var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n return __assign.apply(this, arguments);\r\n };\r\n\r\n function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n }\n\n var HOOKS = [\n \"onChange\",\n \"onClose\",\n \"onDayCreate\",\n \"onDestroy\",\n \"onKeyDown\",\n \"onMonthChange\",\n \"onOpen\",\n \"onParseConfig\",\n \"onReady\",\n \"onValueUpdate\",\n \"onYearChange\",\n \"onPreCalendarPosition\",\n ];\n var defaults = {\n _disable: [],\n _enable: [],\n allowInput: false,\n allowInvalidPreload: false,\n altFormat: \"F j, Y\",\n altInput: false,\n altInputClass: \"form-control input\",\n animate: typeof window === \"object\" &&\n window.navigator.userAgent.indexOf(\"MSIE\") === -1,\n ariaDateFormat: \"F j, Y\",\n autoFillDefaultTime: true,\n clickOpens: true,\n closeOnSelect: true,\n conjunction: \", \",\n dateFormat: \"Y-m-d\",\n defaultHour: 12,\n defaultMinute: 0,\n defaultSeconds: 0,\n disable: [],\n disableMobile: false,\n enable: [],\n enableSeconds: false,\n enableTime: false,\n errorHandler: function (err) {\n return typeof console !== \"undefined\" && console.warn(err);\n },\n getWeek: function (givenDate) {\n var date = new Date(givenDate.getTime());\n date.setHours(0, 0, 0, 0);\n // Thursday in current week decides the year.\n date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7));\n // January 4 is always in week 1.\n var week1 = new Date(date.getFullYear(), 0, 4);\n // Adjust to Thursday in week 1 and count number of weeks from date to week1.\n return (1 +\n Math.round(((date.getTime() - week1.getTime()) / 86400000 -\n 3 +\n ((week1.getDay() + 6) % 7)) /\n 7));\n },\n hourIncrement: 1,\n ignoredFocusElements: [],\n inline: false,\n locale: \"default\",\n minuteIncrement: 5,\n mode: \"single\",\n monthSelectorType: \"dropdown\",\n nextArrow: \"\",\n noCalendar: false,\n now: new Date(),\n onChange: [],\n onClose: [],\n onDayCreate: [],\n onDestroy: [],\n onKeyDown: [],\n onMonthChange: [],\n onOpen: [],\n onParseConfig: [],\n onReady: [],\n onValueUpdate: [],\n onYearChange: [],\n onPreCalendarPosition: [],\n plugins: [],\n position: \"auto\",\n positionElement: undefined,\n prevArrow: \"\",\n shorthandCurrentMonth: false,\n showMonths: 1,\n static: false,\n time_24hr: false,\n weekNumbers: false,\n wrap: false,\n };\n\n var english = {\n weekdays: {\n shorthand: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n longhand: [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n ],\n },\n months: {\n shorthand: [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ],\n longhand: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n },\n daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],\n firstDayOfWeek: 0,\n ordinal: function (nth) {\n var s = nth % 100;\n if (s > 3 && s < 21)\n return \"th\";\n switch (s % 10) {\n case 1:\n return \"st\";\n case 2:\n return \"nd\";\n case 3:\n return \"rd\";\n default:\n return \"th\";\n }\n },\n rangeSeparator: \" to \",\n weekAbbreviation: \"Wk\",\n scrollTitle: \"Scroll to increment\",\n toggleTitle: \"Click to toggle\",\n amPM: [\"AM\", \"PM\"],\n yearAriaLabel: \"Year\",\n monthAriaLabel: \"Month\",\n hourAriaLabel: \"Hour\",\n minuteAriaLabel: \"Minute\",\n time_24hr: false,\n };\n\n var pad = function (number, length) {\n if (length === void 0) { length = 2; }\n return (\"000\" + number).slice(length * -1);\n };\n var int = function (bool) { return (bool === true ? 1 : 0); };\n /* istanbul ignore next */\n function debounce(func, wait, immediate) {\n if (immediate === void 0) { immediate = false; }\n var timeout;\n return function () {\n var context = this, args = arguments;\n timeout !== null && clearTimeout(timeout);\n timeout = window.setTimeout(function () {\n timeout = null;\n if (!immediate)\n func.apply(context, args);\n }, wait);\n if (immediate && !timeout)\n func.apply(context, args);\n };\n }\n var arrayify = function (obj) {\n return obj instanceof Array ? obj : [obj];\n };\n\n function toggleClass(elem, className, bool) {\n if (bool === true)\n return elem.classList.add(className);\n elem.classList.remove(className);\n }\n function createElement(tag, className, content) {\n var e = window.document.createElement(tag);\n className = className || \"\";\n content = content || \"\";\n e.className = className;\n if (content !== undefined)\n e.textContent = content;\n return e;\n }\n function clearNode(node) {\n while (node.firstChild)\n node.removeChild(node.firstChild);\n }\n function findParent(node, condition) {\n if (condition(node))\n return node;\n else if (node.parentNode)\n return findParent(node.parentNode, condition);\n return undefined; // nothing found\n }\n function createNumberInput(inputClassName, opts) {\n var wrapper = createElement(\"div\", \"numInputWrapper\"), numInput = createElement(\"input\", \"numInput \" + inputClassName), arrowUp = createElement(\"span\", \"arrowUp\"), arrowDown = createElement(\"span\", \"arrowDown\");\n if (navigator.userAgent.indexOf(\"MSIE 9.0\") === -1) {\n numInput.type = \"number\";\n }\n else {\n numInput.type = \"text\";\n numInput.pattern = \"\\\\d*\";\n }\n if (opts !== undefined)\n for (var key in opts)\n numInput.setAttribute(key, opts[key]);\n wrapper.appendChild(numInput);\n wrapper.appendChild(arrowUp);\n wrapper.appendChild(arrowDown);\n return wrapper;\n }\n function getEventTarget(event) {\n try {\n if (typeof event.composedPath === \"function\") {\n var path = event.composedPath();\n return path[0];\n }\n return event.target;\n }\n catch (error) {\n return event.target;\n }\n }\n\n var doNothing = function () { return undefined; };\n var monthToStr = function (monthNumber, shorthand, locale) { return locale.months[shorthand ? \"shorthand\" : \"longhand\"][monthNumber]; };\n var revFormat = {\n D: doNothing,\n F: function (dateObj, monthName, locale) {\n dateObj.setMonth(locale.months.longhand.indexOf(monthName));\n },\n G: function (dateObj, hour) {\n dateObj.setHours(parseFloat(hour));\n },\n H: function (dateObj, hour) {\n dateObj.setHours(parseFloat(hour));\n },\n J: function (dateObj, day) {\n dateObj.setDate(parseFloat(day));\n },\n K: function (dateObj, amPM, locale) {\n dateObj.setHours((dateObj.getHours() % 12) +\n 12 * int(new RegExp(locale.amPM[1], \"i\").test(amPM)));\n },\n M: function (dateObj, shortMonth, locale) {\n dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth));\n },\n S: function (dateObj, seconds) {\n dateObj.setSeconds(parseFloat(seconds));\n },\n U: function (_, unixSeconds) { return new Date(parseFloat(unixSeconds) * 1000); },\n W: function (dateObj, weekNum, locale) {\n var weekNumber = parseInt(weekNum);\n var date = new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0);\n date.setDate(date.getDate() - date.getDay() + locale.firstDayOfWeek);\n return date;\n },\n Y: function (dateObj, year) {\n dateObj.setFullYear(parseFloat(year));\n },\n Z: function (_, ISODate) { return new Date(ISODate); },\n d: function (dateObj, day) {\n dateObj.setDate(parseFloat(day));\n },\n h: function (dateObj, hour) {\n dateObj.setHours(parseFloat(hour));\n },\n i: function (dateObj, minutes) {\n dateObj.setMinutes(parseFloat(minutes));\n },\n j: function (dateObj, day) {\n dateObj.setDate(parseFloat(day));\n },\n l: doNothing,\n m: function (dateObj, month) {\n dateObj.setMonth(parseFloat(month) - 1);\n },\n n: function (dateObj, month) {\n dateObj.setMonth(parseFloat(month) - 1);\n },\n s: function (dateObj, seconds) {\n dateObj.setSeconds(parseFloat(seconds));\n },\n u: function (_, unixMillSeconds) {\n return new Date(parseFloat(unixMillSeconds));\n },\n w: doNothing,\n y: function (dateObj, year) {\n dateObj.setFullYear(2000 + parseFloat(year));\n },\n };\n var tokenRegex = {\n D: \"(\\\\w+)\",\n F: \"(\\\\w+)\",\n G: \"(\\\\d\\\\d|\\\\d)\",\n H: \"(\\\\d\\\\d|\\\\d)\",\n J: \"(\\\\d\\\\d|\\\\d)\\\\w+\",\n K: \"\",\n M: \"(\\\\w+)\",\n S: \"(\\\\d\\\\d|\\\\d)\",\n U: \"(.+)\",\n W: \"(\\\\d\\\\d|\\\\d)\",\n Y: \"(\\\\d{4})\",\n Z: \"(.+)\",\n d: \"(\\\\d\\\\d|\\\\d)\",\n h: \"(\\\\d\\\\d|\\\\d)\",\n i: \"(\\\\d\\\\d|\\\\d)\",\n j: \"(\\\\d\\\\d|\\\\d)\",\n l: \"(\\\\w+)\",\n m: \"(\\\\d\\\\d|\\\\d)\",\n n: \"(\\\\d\\\\d|\\\\d)\",\n s: \"(\\\\d\\\\d|\\\\d)\",\n u: \"(.+)\",\n w: \"(\\\\d\\\\d|\\\\d)\",\n y: \"(\\\\d{2})\",\n };\n var formats = {\n // get the date in UTC\n Z: function (date) { return date.toISOString(); },\n // weekday name, short, e.g. Thu\n D: function (date, locale, options) {\n return locale.weekdays.shorthand[formats.w(date, locale, options)];\n },\n // full month name e.g. January\n F: function (date, locale, options) {\n return monthToStr(formats.n(date, locale, options) - 1, false, locale);\n },\n // padded hour 1-12\n G: function (date, locale, options) {\n return pad(formats.h(date, locale, options));\n },\n // hours with leading zero e.g. 03\n H: function (date) { return pad(date.getHours()); },\n // day (1-30) with ordinal suffix e.g. 1st, 2nd\n J: function (date, locale) {\n return locale.ordinal !== undefined\n ? date.getDate() + locale.ordinal(date.getDate())\n : date.getDate();\n },\n // AM/PM\n K: function (date, locale) { return locale.amPM[int(date.getHours() > 11)]; },\n // shorthand month e.g. Jan, Sep, Oct, etc\n M: function (date, locale) {\n return monthToStr(date.getMonth(), true, locale);\n },\n // seconds 00-59\n S: function (date) { return pad(date.getSeconds()); },\n // unix timestamp\n U: function (date) { return date.getTime() / 1000; },\n W: function (date, _, options) {\n return options.getWeek(date);\n },\n // full year e.g. 2016, padded (0001-9999)\n Y: function (date) { return pad(date.getFullYear(), 4); },\n // day in month, padded (01-30)\n d: function (date) { return pad(date.getDate()); },\n // hour from 1-12 (am/pm)\n h: function (date) { return (date.getHours() % 12 ? date.getHours() % 12 : 12); },\n // minutes, padded with leading zero e.g. 09\n i: function (date) { return pad(date.getMinutes()); },\n // day in month (1-30)\n j: function (date) { return date.getDate(); },\n // weekday name, full, e.g. Thursday\n l: function (date, locale) {\n return locale.weekdays.longhand[date.getDay()];\n },\n // padded month number (01-12)\n m: function (date) { return pad(date.getMonth() + 1); },\n // the month number (1-12)\n n: function (date) { return date.getMonth() + 1; },\n // seconds 0-59\n s: function (date) { return date.getSeconds(); },\n // Unix Milliseconds\n u: function (date) { return date.getTime(); },\n // number of the day of the week\n w: function (date) { return date.getDay(); },\n // last two digits of year e.g. 16 for 2016\n y: function (date) { return String(date.getFullYear()).substring(2); },\n };\n\n var createDateFormatter = function (_a) {\n var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c, _d = _a.isMobile, isMobile = _d === void 0 ? false : _d;\n return function (dateObj, frmt, overrideLocale) {\n var locale = overrideLocale || l10n;\n if (config.formatDate !== undefined && !isMobile) {\n return config.formatDate(dateObj, frmt, locale);\n }\n return frmt\n .split(\"\")\n .map(function (c, i, arr) {\n return formats[c] && arr[i - 1] !== \"\\\\\"\n ? formats[c](dateObj, locale, config)\n : c !== \"\\\\\"\n ? c\n : \"\";\n })\n .join(\"\");\n };\n };\n var createDateParser = function (_a) {\n var _b = _a.config, config = _b === void 0 ? defaults : _b, _c = _a.l10n, l10n = _c === void 0 ? english : _c;\n return function (date, givenFormat, timeless, customLocale) {\n if (date !== 0 && !date)\n return undefined;\n var locale = customLocale || l10n;\n var parsedDate;\n var dateOrig = date;\n if (date instanceof Date)\n parsedDate = new Date(date.getTime());\n else if (typeof date !== \"string\" &&\n date.toFixed !== undefined // timestamp\n )\n // create a copy\n parsedDate = new Date(date);\n else if (typeof date === \"string\") {\n // date string\n var format = givenFormat || (config || defaults).dateFormat;\n var datestr = String(date).trim();\n if (datestr === \"today\") {\n parsedDate = new Date();\n timeless = true;\n }\n else if (/Z$/.test(datestr) ||\n /GMT$/.test(datestr) // datestrings w/ timezone\n )\n parsedDate = new Date(date);\n else if (config && config.parseDate)\n parsedDate = config.parseDate(date, format);\n else {\n parsedDate =\n !config || !config.noCalendar\n ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0)\n : new Date(new Date().setHours(0, 0, 0, 0));\n var matched = void 0, ops = [];\n for (var i = 0, matchIndex = 0, regexStr = \"\"; i < format.length; i++) {\n var token_1 = format[i];\n var isBackSlash = token_1 === \"\\\\\";\n var escaped = format[i - 1] === \"\\\\\" || isBackSlash;\n if (tokenRegex[token_1] && !escaped) {\n regexStr += tokenRegex[token_1];\n var match = new RegExp(regexStr).exec(date);\n if (match && (matched = true)) {\n ops[token_1 !== \"Y\" ? \"push\" : \"unshift\"]({\n fn: revFormat[token_1],\n val: match[++matchIndex],\n });\n }\n }\n else if (!isBackSlash)\n regexStr += \".\"; // don't really care\n ops.forEach(function (_a) {\n var fn = _a.fn, val = _a.val;\n return (parsedDate = fn(parsedDate, val, locale) || parsedDate);\n });\n }\n parsedDate = matched ? parsedDate : undefined;\n }\n }\n /* istanbul ignore next */\n if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) {\n config.errorHandler(new Error(\"Invalid date provided: \" + dateOrig));\n return undefined;\n }\n if (timeless === true)\n parsedDate.setHours(0, 0, 0, 0);\n return parsedDate;\n };\n };\n /**\n * Compute the difference in dates, measured in ms\n */\n function compareDates(date1, date2, timeless) {\n if (timeless === void 0) { timeless = true; }\n if (timeless !== false) {\n return (new Date(date1.getTime()).setHours(0, 0, 0, 0) -\n new Date(date2.getTime()).setHours(0, 0, 0, 0));\n }\n return date1.getTime() - date2.getTime();\n }\n var isBetween = function (ts, ts1, ts2) {\n return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2);\n };\n var duration = {\n DAY: 86400000,\n };\n\n if (typeof Object.assign !== \"function\") {\n Object.assign = function (target) {\n var args = [];\n for (var _i = 1; _i < arguments.length; _i++) {\n args[_i - 1] = arguments[_i];\n }\n if (!target) {\n throw TypeError(\"Cannot convert undefined or null to object\");\n }\n var _loop_1 = function (source) {\n if (source) {\n Object.keys(source).forEach(function (key) { return (target[key] = source[key]); });\n }\n };\n for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {\n var source = args_1[_a];\n _loop_1(source);\n }\n return target;\n };\n }\n\n var DEBOUNCED_CHANGE_MS = 300;\n function FlatpickrInstance(element, instanceConfig) {\n var self = {\n config: __assign(__assign({}, defaults), flatpickr.defaultConfig),\n l10n: english,\n };\n self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });\n self._handlers = [];\n self.pluginElements = [];\n self.loadedPlugins = [];\n self._bind = bind;\n self._setHoursFromDate = setHoursFromDate;\n self._positionCalendar = positionCalendar;\n self.changeMonth = changeMonth;\n self.changeYear = changeYear;\n self.clear = clear;\n self.close = close;\n self._createElement = createElement;\n self.destroy = destroy;\n self.isEnabled = isEnabled;\n self.jumpToDate = jumpToDate;\n self.open = open;\n self.redraw = redraw;\n self.set = set;\n self.setDate = setDate;\n self.toggle = toggle;\n function setupHelperFunctions() {\n self.utils = {\n getDaysInMonth: function (month, yr) {\n if (month === void 0) { month = self.currentMonth; }\n if (yr === void 0) { yr = self.currentYear; }\n if (month === 1 && ((yr % 4 === 0 && yr % 100 !== 0) || yr % 400 === 0))\n return 29;\n return self.l10n.daysInMonth[month];\n },\n };\n }\n function init() {\n self.element = self.input = element;\n self.isOpen = false;\n parseConfig();\n setupLocale();\n setupInputs();\n setupDates();\n setupHelperFunctions();\n if (!self.isMobile)\n build();\n bindEvents();\n if (self.selectedDates.length || self.config.noCalendar) {\n if (self.config.enableTime) {\n setHoursFromDate(self.config.noCalendar\n ? self.latestSelectedDateObj || self.config.minDate\n : undefined);\n }\n updateValue(false);\n }\n setCalendarWidth();\n var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n /* TODO: investigate this further\n \n Currently, there is weird positioning behavior in safari causing pages\n to scroll up. https://github.com/chmln/flatpickr/issues/563\n \n However, most browsers are not Safari and positioning is expensive when used\n in scale. https://github.com/chmln/flatpickr/issues/1096\n */\n if (!self.isMobile && isSafari) {\n positionCalendar();\n }\n triggerEvent(\"onReady\");\n }\n function bindToInstance(fn) {\n return fn.bind(self);\n }\n function setCalendarWidth() {\n var config = self.config;\n if (config.weekNumbers === false && config.showMonths === 1) {\n return;\n }\n else if (config.noCalendar !== true) {\n window.requestAnimationFrame(function () {\n if (self.calendarContainer !== undefined) {\n self.calendarContainer.style.visibility = \"hidden\";\n self.calendarContainer.style.display = \"block\";\n }\n if (self.daysContainer !== undefined) {\n var daysWidth = (self.days.offsetWidth + 1) * config.showMonths;\n self.daysContainer.style.width = daysWidth + \"px\";\n self.calendarContainer.style.width =\n daysWidth +\n (self.weekWrapper !== undefined\n ? self.weekWrapper.offsetWidth\n : 0) +\n \"px\";\n self.calendarContainer.style.removeProperty(\"visibility\");\n self.calendarContainer.style.removeProperty(\"display\");\n }\n });\n }\n }\n /**\n * The handler for all events targeting the time inputs\n */\n function updateTime(e) {\n if (self.selectedDates.length === 0) {\n var defaultDate = self.config.minDate !== undefined\n ? new Date(self.config.minDate.getTime())\n : new Date();\n var _a = getDefaultHours(), hours = _a.hours, minutes = _a.minutes, seconds = _a.seconds;\n defaultDate.setHours(hours, minutes, seconds, 0);\n self.setDate(defaultDate, false);\n }\n if (e !== undefined && e.type !== \"blur\") {\n timeWrapper(e);\n }\n var prevValue = self._input.value;\n setHoursFromInputs();\n updateValue();\n if (self._input.value !== prevValue) {\n self._debouncedChange();\n }\n }\n function ampm2military(hour, amPM) {\n return (hour % 12) + 12 * int(amPM === self.l10n.amPM[1]);\n }\n function military2ampm(hour) {\n switch (hour % 24) {\n case 0:\n case 12:\n return 12;\n default:\n return hour % 12;\n }\n }\n /**\n * Syncs the selected date object time with user's time input\n */\n function setHoursFromInputs() {\n if (self.hourElement === undefined || self.minuteElement === undefined)\n return;\n var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24, minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60, seconds = self.secondElement !== undefined\n ? (parseInt(self.secondElement.value, 10) || 0) % 60\n : 0;\n if (self.amPM !== undefined) {\n hours = ampm2military(hours, self.amPM.textContent);\n }\n var limitMinHours = self.config.minTime !== undefined ||\n (self.config.minDate &&\n self.minDateHasTime &&\n self.latestSelectedDateObj &&\n compareDates(self.latestSelectedDateObj, self.config.minDate, true) ===\n 0);\n var limitMaxHours = self.config.maxTime !== undefined ||\n (self.config.maxDate &&\n self.maxDateHasTime &&\n self.latestSelectedDateObj &&\n compareDates(self.latestSelectedDateObj, self.config.maxDate, true) ===\n 0);\n if (limitMaxHours) {\n var maxTime = self.config.maxTime !== undefined\n ? self.config.maxTime\n : self.config.maxDate;\n hours = Math.min(hours, maxTime.getHours());\n if (hours === maxTime.getHours())\n minutes = Math.min(minutes, maxTime.getMinutes());\n if (minutes === maxTime.getMinutes())\n seconds = Math.min(seconds, maxTime.getSeconds());\n }\n if (limitMinHours) {\n var minTime = self.config.minTime !== undefined\n ? self.config.minTime\n : self.config.minDate;\n hours = Math.max(hours, minTime.getHours());\n if (hours === minTime.getHours())\n minutes = Math.max(minutes, minTime.getMinutes());\n if (minutes === minTime.getMinutes())\n seconds = Math.max(seconds, minTime.getSeconds());\n }\n setHours(hours, minutes, seconds);\n }\n /**\n * Syncs time input values with a date\n */\n function setHoursFromDate(dateObj) {\n var date = dateObj || self.latestSelectedDateObj;\n if (date) {\n setHours(date.getHours(), date.getMinutes(), date.getSeconds());\n }\n }\n function getDefaultHours() {\n var hours = self.config.defaultHour;\n var minutes = self.config.defaultMinute;\n var seconds = self.config.defaultSeconds;\n if (self.config.minDate !== undefined) {\n var minHr = self.config.minDate.getHours();\n var minMinutes = self.config.minDate.getMinutes();\n hours = Math.max(hours, minHr);\n if (hours === minHr)\n minutes = Math.max(minMinutes, minutes);\n if (hours === minHr && minutes === minMinutes)\n seconds = self.config.minDate.getSeconds();\n }\n if (self.config.maxDate !== undefined) {\n var maxHr = self.config.maxDate.getHours();\n var maxMinutes = self.config.maxDate.getMinutes();\n hours = Math.min(hours, maxHr);\n if (hours === maxHr)\n minutes = Math.min(maxMinutes, minutes);\n if (hours === maxHr && minutes === maxMinutes)\n seconds = self.config.maxDate.getSeconds();\n }\n return { hours: hours, minutes: minutes, seconds: seconds };\n }\n /**\n * Sets the hours, minutes, and optionally seconds\n * of the latest selected date object and the\n * corresponding time inputs\n * @param {Number} hours the hour. whether its military\n * or am-pm gets inferred from config\n * @param {Number} minutes the minutes\n * @param {Number} seconds the seconds (optional)\n */\n function setHours(hours, minutes, seconds) {\n if (self.latestSelectedDateObj !== undefined) {\n self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);\n }\n if (!self.hourElement || !self.minuteElement || self.isMobile)\n return;\n self.hourElement.value = pad(!self.config.time_24hr\n ? ((12 + hours) % 12) + 12 * int(hours % 12 === 0)\n : hours);\n self.minuteElement.value = pad(minutes);\n if (self.amPM !== undefined)\n self.amPM.textContent = self.l10n.amPM[int(hours >= 12)];\n if (self.secondElement !== undefined)\n self.secondElement.value = pad(seconds);\n }\n /**\n * Handles the year input and incrementing events\n * @param {Event} event the keyup or increment event\n */\n function onYearInput(event) {\n var eventTarget = getEventTarget(event);\n var year = parseInt(eventTarget.value) + (event.delta || 0);\n if (year / 1000 > 1 ||\n (event.key === \"Enter\" && !/[^\\d]/.test(year.toString()))) {\n changeYear(year);\n }\n }\n /**\n * Essentially addEventListener + tracking\n * @param {Element} element the element to addEventListener to\n * @param {String} event the event name\n * @param {Function} handler the event handler\n */\n function bind(element, event, handler, options) {\n if (event instanceof Array)\n return event.forEach(function (ev) { return bind(element, ev, handler, options); });\n if (element instanceof Array)\n return element.forEach(function (el) { return bind(el, event, handler, options); });\n element.addEventListener(event, handler, options);\n self._handlers.push({\n element: element,\n event: event,\n handler: handler,\n options: options,\n });\n }\n function triggerChange() {\n triggerEvent(\"onChange\");\n }\n /**\n * Adds all the necessary event listeners\n */\n function bindEvents() {\n if (self.config.wrap) {\n [\"open\", \"close\", \"toggle\", \"clear\"].forEach(function (evt) {\n Array.prototype.forEach.call(self.element.querySelectorAll(\"[data-\" + evt + \"]\"), function (el) {\n return bind(el, \"click\", self[evt]);\n });\n });\n }\n if (self.isMobile) {\n setupMobile();\n return;\n }\n var debouncedResize = debounce(onResize, 50);\n self._debouncedChange = debounce(triggerChange, DEBOUNCED_CHANGE_MS);\n if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent))\n bind(self.daysContainer, \"mouseover\", function (e) {\n if (self.config.mode === \"range\")\n onMouseOver(getEventTarget(e));\n });\n bind(window.document.body, \"keydown\", onKeyDown);\n if (!self.config.inline && !self.config.static)\n bind(window, \"resize\", debouncedResize);\n if (window.ontouchstart !== undefined)\n bind(window.document, \"touchstart\", documentClick);\n else\n bind(window.document, \"click\", documentClick);\n bind(window.document, \"focus\", documentClick, { capture: true });\n if (self.config.clickOpens === true) {\n bind(self._input, \"focus\", self.open);\n bind(self._input, \"click\", self.open);\n }\n if (self.daysContainer !== undefined) {\n bind(self.monthNav, \"click\", onMonthNavClick);\n bind(self.monthNav, [\"keyup\", \"increment\"], onYearInput);\n bind(self.daysContainer, \"click\", selectDate);\n }\n if (self.timeContainer !== undefined &&\n self.minuteElement !== undefined &&\n self.hourElement !== undefined) {\n var selText = function (e) {\n return getEventTarget(e).select();\n };\n bind(self.timeContainer, [\"increment\"], updateTime);\n bind(self.timeContainer, \"blur\", updateTime, { capture: true });\n bind(self.timeContainer, \"click\", timeIncrement);\n bind([self.hourElement, self.minuteElement], [\"focus\", \"click\"], selText);\n if (self.secondElement !== undefined)\n bind(self.secondElement, \"focus\", function () { return self.secondElement && self.secondElement.select(); });\n if (self.amPM !== undefined) {\n bind(self.amPM, \"click\", function (e) {\n updateTime(e);\n triggerChange();\n });\n }\n }\n if (self.config.allowInput)\n bind(self._input, \"blur\", onBlur);\n }\n /**\n * Set the calendar view to a particular date.\n * @param {Date} jumpDate the date to set the view to\n * @param {boolean} triggerChange if change events should be triggered\n */\n function jumpToDate(jumpDate, triggerChange) {\n var jumpTo = jumpDate !== undefined\n ? self.parseDate(jumpDate)\n : self.latestSelectedDateObj ||\n (self.config.minDate && self.config.minDate > self.now\n ? self.config.minDate\n : self.config.maxDate && self.config.maxDate < self.now\n ? self.config.maxDate\n : self.now);\n var oldYear = self.currentYear;\n var oldMonth = self.currentMonth;\n try {\n if (jumpTo !== undefined) {\n self.currentYear = jumpTo.getFullYear();\n self.currentMonth = jumpTo.getMonth();\n }\n }\n catch (e) {\n /* istanbul ignore next */\n e.message = \"Invalid date supplied: \" + jumpTo;\n self.config.errorHandler(e);\n }\n if (triggerChange && self.currentYear !== oldYear) {\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n if (triggerChange &&\n (self.currentYear !== oldYear || self.currentMonth !== oldMonth)) {\n triggerEvent(\"onMonthChange\");\n }\n self.redraw();\n }\n /**\n * The up/down arrow handler for time inputs\n * @param {Event} e the click event\n */\n function timeIncrement(e) {\n var eventTarget = getEventTarget(e);\n if (~eventTarget.className.indexOf(\"arrow\"))\n incrementNumInput(e, eventTarget.classList.contains(\"arrowUp\") ? 1 : -1);\n }\n /**\n * Increments/decrements the value of input associ-\n * ated with the up/down arrow by dispatching an\n * \"increment\" event on the input.\n *\n * @param {Event} e the click event\n * @param {Number} delta the diff (usually 1 or -1)\n * @param {Element} inputElem the input element\n */\n function incrementNumInput(e, delta, inputElem) {\n var target = e && getEventTarget(e);\n var input = inputElem ||\n (target && target.parentNode && target.parentNode.firstChild);\n var event = createEvent(\"increment\");\n event.delta = delta;\n input && input.dispatchEvent(event);\n }\n function build() {\n var fragment = window.document.createDocumentFragment();\n self.calendarContainer = createElement(\"div\", \"flatpickr-calendar\");\n self.calendarContainer.tabIndex = -1;\n if (!self.config.noCalendar) {\n fragment.appendChild(buildMonthNav());\n self.innerContainer = createElement(\"div\", \"flatpickr-innerContainer\");\n if (self.config.weekNumbers) {\n var _a = buildWeeks(), weekWrapper = _a.weekWrapper, weekNumbers = _a.weekNumbers;\n self.innerContainer.appendChild(weekWrapper);\n self.weekNumbers = weekNumbers;\n self.weekWrapper = weekWrapper;\n }\n self.rContainer = createElement(\"div\", \"flatpickr-rContainer\");\n self.rContainer.appendChild(buildWeekdays());\n if (!self.daysContainer) {\n self.daysContainer = createElement(\"div\", \"flatpickr-days\");\n self.daysContainer.tabIndex = -1;\n }\n buildDays();\n self.rContainer.appendChild(self.daysContainer);\n self.innerContainer.appendChild(self.rContainer);\n fragment.appendChild(self.innerContainer);\n }\n if (self.config.enableTime) {\n fragment.appendChild(buildTime());\n }\n toggleClass(self.calendarContainer, \"rangeMode\", self.config.mode === \"range\");\n toggleClass(self.calendarContainer, \"animate\", self.config.animate === true);\n toggleClass(self.calendarContainer, \"multiMonth\", self.config.showMonths > 1);\n self.calendarContainer.appendChild(fragment);\n var customAppend = self.config.appendTo !== undefined &&\n self.config.appendTo.nodeType !== undefined;\n if (self.config.inline || self.config.static) {\n self.calendarContainer.classList.add(self.config.inline ? \"inline\" : \"static\");\n if (self.config.inline) {\n if (!customAppend && self.element.parentNode)\n self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);\n else if (self.config.appendTo !== undefined)\n self.config.appendTo.appendChild(self.calendarContainer);\n }\n if (self.config.static) {\n var wrapper = createElement(\"div\", \"flatpickr-wrapper\");\n if (self.element.parentNode)\n self.element.parentNode.insertBefore(wrapper, self.element);\n wrapper.appendChild(self.element);\n if (self.altInput)\n wrapper.appendChild(self.altInput);\n wrapper.appendChild(self.calendarContainer);\n }\n }\n if (!self.config.static && !self.config.inline)\n (self.config.appendTo !== undefined\n ? self.config.appendTo\n : window.document.body).appendChild(self.calendarContainer);\n }\n function createDay(className, date, dayNumber, i) {\n var dateIsEnabled = isEnabled(date, true), dayElement = createElement(\"span\", \"flatpickr-day \" + className, date.getDate().toString());\n dayElement.dateObj = date;\n dayElement.$i = i;\n dayElement.setAttribute(\"aria-label\", self.formatDate(date, self.config.ariaDateFormat));\n if (className.indexOf(\"hidden\") === -1 &&\n compareDates(date, self.now) === 0) {\n self.todayDateElem = dayElement;\n dayElement.classList.add(\"today\");\n dayElement.setAttribute(\"aria-current\", \"date\");\n }\n if (dateIsEnabled) {\n dayElement.tabIndex = -1;\n if (isDateSelected(date)) {\n dayElement.classList.add(\"selected\");\n self.selectedDateElem = dayElement;\n if (self.config.mode === \"range\") {\n toggleClass(dayElement, \"startRange\", self.selectedDates[0] &&\n compareDates(date, self.selectedDates[0], true) === 0);\n toggleClass(dayElement, \"endRange\", self.selectedDates[1] &&\n compareDates(date, self.selectedDates[1], true) === 0);\n if (className === \"nextMonthDay\")\n dayElement.classList.add(\"inRange\");\n }\n }\n }\n else {\n dayElement.classList.add(\"flatpickr-disabled\");\n }\n if (self.config.mode === \"range\") {\n if (isDateInRange(date) && !isDateSelected(date))\n dayElement.classList.add(\"inRange\");\n }\n if (self.weekNumbers &&\n self.config.showMonths === 1 &&\n className !== \"prevMonthDay\" &&\n dayNumber % 7 === 1) {\n self.weekNumbers.insertAdjacentHTML(\"beforeend\", \"\" + self.config.getWeek(date) + \"\");\n }\n triggerEvent(\"onDayCreate\", dayElement);\n return dayElement;\n }\n function focusOnDayElem(targetNode) {\n targetNode.focus();\n if (self.config.mode === \"range\")\n onMouseOver(targetNode);\n }\n function getFirstAvailableDay(delta) {\n var startMonth = delta > 0 ? 0 : self.config.showMonths - 1;\n var endMonth = delta > 0 ? self.config.showMonths : -1;\n for (var m = startMonth; m != endMonth; m += delta) {\n var month = self.daysContainer.children[m];\n var startIndex = delta > 0 ? 0 : month.children.length - 1;\n var endIndex = delta > 0 ? month.children.length : -1;\n for (var i = startIndex; i != endIndex; i += delta) {\n var c = month.children[i];\n if (c.className.indexOf(\"hidden\") === -1 && isEnabled(c.dateObj))\n return c;\n }\n }\n return undefined;\n }\n function getNextAvailableDay(current, delta) {\n var givenMonth = current.className.indexOf(\"Month\") === -1\n ? current.dateObj.getMonth()\n : self.currentMonth;\n var endMonth = delta > 0 ? self.config.showMonths : -1;\n var loopDelta = delta > 0 ? 1 : -1;\n for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) {\n var month = self.daysContainer.children[m];\n var startIndex = givenMonth - self.currentMonth === m\n ? current.$i + delta\n : delta < 0\n ? month.children.length - 1\n : 0;\n var numMonthDays = month.children.length;\n for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) {\n var c = month.children[i];\n if (c.className.indexOf(\"hidden\") === -1 &&\n isEnabled(c.dateObj) &&\n Math.abs(current.$i - i) >= Math.abs(delta))\n return focusOnDayElem(c);\n }\n }\n self.changeMonth(loopDelta);\n focusOnDay(getFirstAvailableDay(loopDelta), 0);\n return undefined;\n }\n function focusOnDay(current, offset) {\n var dayFocused = isInView(document.activeElement || document.body);\n var startElem = current !== undefined\n ? current\n : dayFocused\n ? document.activeElement\n : self.selectedDateElem !== undefined && isInView(self.selectedDateElem)\n ? self.selectedDateElem\n : self.todayDateElem !== undefined && isInView(self.todayDateElem)\n ? self.todayDateElem\n : getFirstAvailableDay(offset > 0 ? 1 : -1);\n if (startElem === undefined) {\n self._input.focus();\n }\n else if (!dayFocused) {\n focusOnDayElem(startElem);\n }\n else {\n getNextAvailableDay(startElem, offset);\n }\n }\n function buildMonthDays(year, month) {\n var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;\n var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12, year);\n var daysInMonth = self.utils.getDaysInMonth(month, year), days = window.document.createDocumentFragment(), isMultiMonth = self.config.showMonths > 1, prevMonthDayClass = isMultiMonth ? \"prevMonthDay hidden\" : \"prevMonthDay\", nextMonthDayClass = isMultiMonth ? \"nextMonthDay hidden\" : \"nextMonthDay\";\n var dayNumber = prevMonthDays + 1 - firstOfMonth, dayIndex = 0;\n // prepend days from the ending of previous month\n for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) {\n days.appendChild(createDay(prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex));\n }\n // Start at 1 since there is no 0th day\n for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {\n days.appendChild(createDay(\"\", new Date(year, month, dayNumber), dayNumber, dayIndex));\n }\n // append days from the next month\n for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth &&\n (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) {\n days.appendChild(createDay(nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex));\n }\n //updateNavigationCurrentMonth();\n var dayContainer = createElement(\"div\", \"dayContainer\");\n dayContainer.appendChild(days);\n return dayContainer;\n }\n function buildDays() {\n if (self.daysContainer === undefined) {\n return;\n }\n clearNode(self.daysContainer);\n // TODO: week numbers for each month\n if (self.weekNumbers)\n clearNode(self.weekNumbers);\n var frag = document.createDocumentFragment();\n for (var i = 0; i < self.config.showMonths; i++) {\n var d = new Date(self.currentYear, self.currentMonth, 1);\n d.setMonth(self.currentMonth + i);\n frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth()));\n }\n self.daysContainer.appendChild(frag);\n self.days = self.daysContainer.firstChild;\n if (self.config.mode === \"range\" && self.selectedDates.length === 1) {\n onMouseOver();\n }\n }\n function buildMonthSwitch() {\n if (self.config.showMonths > 1 ||\n self.config.monthSelectorType !== \"dropdown\")\n return;\n var shouldBuildMonth = function (month) {\n if (self.config.minDate !== undefined &&\n self.currentYear === self.config.minDate.getFullYear() &&\n month < self.config.minDate.getMonth()) {\n return false;\n }\n return !(self.config.maxDate !== undefined &&\n self.currentYear === self.config.maxDate.getFullYear() &&\n month > self.config.maxDate.getMonth());\n };\n self.monthsDropdownContainer.tabIndex = -1;\n self.monthsDropdownContainer.innerHTML = \"\";\n for (var i = 0; i < 12; i++) {\n if (!shouldBuildMonth(i))\n continue;\n var month = createElement(\"option\", \"flatpickr-monthDropdown-month\");\n month.value = new Date(self.currentYear, i).getMonth().toString();\n month.textContent = monthToStr(i, self.config.shorthandCurrentMonth, self.l10n);\n month.tabIndex = -1;\n if (self.currentMonth === i) {\n month.selected = true;\n }\n self.monthsDropdownContainer.appendChild(month);\n }\n }\n function buildMonth() {\n var container = createElement(\"div\", \"flatpickr-month\");\n var monthNavFragment = window.document.createDocumentFragment();\n var monthElement;\n if (self.config.showMonths > 1 ||\n self.config.monthSelectorType === \"static\") {\n monthElement = createElement(\"span\", \"cur-month\");\n }\n else {\n self.monthsDropdownContainer = createElement(\"select\", \"flatpickr-monthDropdown-months\");\n self.monthsDropdownContainer.setAttribute(\"aria-label\", self.l10n.monthAriaLabel);\n bind(self.monthsDropdownContainer, \"change\", function (e) {\n var target = getEventTarget(e);\n var selectedMonth = parseInt(target.value, 10);\n self.changeMonth(selectedMonth - self.currentMonth);\n triggerEvent(\"onMonthChange\");\n });\n buildMonthSwitch();\n monthElement = self.monthsDropdownContainer;\n }\n var yearInput = createNumberInput(\"cur-year\", { tabindex: \"-1\" });\n var yearElement = yearInput.getElementsByTagName(\"input\")[0];\n yearElement.setAttribute(\"aria-label\", self.l10n.yearAriaLabel);\n if (self.config.minDate) {\n yearElement.setAttribute(\"min\", self.config.minDate.getFullYear().toString());\n }\n if (self.config.maxDate) {\n yearElement.setAttribute(\"max\", self.config.maxDate.getFullYear().toString());\n yearElement.disabled =\n !!self.config.minDate &&\n self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();\n }\n var currentMonth = createElement(\"div\", \"flatpickr-current-month\");\n currentMonth.appendChild(monthElement);\n currentMonth.appendChild(yearInput);\n monthNavFragment.appendChild(currentMonth);\n container.appendChild(monthNavFragment);\n return {\n container: container,\n yearElement: yearElement,\n monthElement: monthElement,\n };\n }\n function buildMonths() {\n clearNode(self.monthNav);\n self.monthNav.appendChild(self.prevMonthNav);\n if (self.config.showMonths) {\n self.yearElements = [];\n self.monthElements = [];\n }\n for (var m = self.config.showMonths; m--;) {\n var month = buildMonth();\n self.yearElements.push(month.yearElement);\n self.monthElements.push(month.monthElement);\n self.monthNav.appendChild(month.container);\n }\n self.monthNav.appendChild(self.nextMonthNav);\n }\n function buildMonthNav() {\n self.monthNav = createElement(\"div\", \"flatpickr-months\");\n self.yearElements = [];\n self.monthElements = [];\n self.prevMonthNav = createElement(\"span\", \"flatpickr-prev-month\");\n self.prevMonthNav.innerHTML = self.config.prevArrow;\n self.nextMonthNav = createElement(\"span\", \"flatpickr-next-month\");\n self.nextMonthNav.innerHTML = self.config.nextArrow;\n buildMonths();\n Object.defineProperty(self, \"_hidePrevMonthArrow\", {\n get: function () { return self.__hidePrevMonthArrow; },\n set: function (bool) {\n if (self.__hidePrevMonthArrow !== bool) {\n toggleClass(self.prevMonthNav, \"flatpickr-disabled\", bool);\n self.__hidePrevMonthArrow = bool;\n }\n },\n });\n Object.defineProperty(self, \"_hideNextMonthArrow\", {\n get: function () { return self.__hideNextMonthArrow; },\n set: function (bool) {\n if (self.__hideNextMonthArrow !== bool) {\n toggleClass(self.nextMonthNav, \"flatpickr-disabled\", bool);\n self.__hideNextMonthArrow = bool;\n }\n },\n });\n self.currentYearElement = self.yearElements[0];\n updateNavigationCurrentMonth();\n return self.monthNav;\n }\n function buildTime() {\n self.calendarContainer.classList.add(\"hasTime\");\n if (self.config.noCalendar)\n self.calendarContainer.classList.add(\"noCalendar\");\n self.timeContainer = createElement(\"div\", \"flatpickr-time\");\n self.timeContainer.tabIndex = -1;\n var separator = createElement(\"span\", \"flatpickr-time-separator\", \":\");\n var hourInput = createNumberInput(\"flatpickr-hour\", {\n \"aria-label\": self.l10n.hourAriaLabel,\n });\n self.hourElement = hourInput.getElementsByTagName(\"input\")[0];\n var minuteInput = createNumberInput(\"flatpickr-minute\", {\n \"aria-label\": self.l10n.minuteAriaLabel,\n });\n self.minuteElement = minuteInput.getElementsByTagName(\"input\")[0];\n self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;\n self.hourElement.value = pad(self.latestSelectedDateObj\n ? self.latestSelectedDateObj.getHours()\n : self.config.time_24hr\n ? self.config.defaultHour\n : military2ampm(self.config.defaultHour));\n self.minuteElement.value = pad(self.latestSelectedDateObj\n ? self.latestSelectedDateObj.getMinutes()\n : self.config.defaultMinute);\n self.hourElement.setAttribute(\"step\", self.config.hourIncrement.toString());\n self.minuteElement.setAttribute(\"step\", self.config.minuteIncrement.toString());\n self.hourElement.setAttribute(\"min\", self.config.time_24hr ? \"0\" : \"1\");\n self.hourElement.setAttribute(\"max\", self.config.time_24hr ? \"23\" : \"12\");\n self.minuteElement.setAttribute(\"min\", \"0\");\n self.minuteElement.setAttribute(\"max\", \"59\");\n self.timeContainer.appendChild(hourInput);\n self.timeContainer.appendChild(separator);\n self.timeContainer.appendChild(minuteInput);\n if (self.config.time_24hr)\n self.timeContainer.classList.add(\"time24hr\");\n if (self.config.enableSeconds) {\n self.timeContainer.classList.add(\"hasSeconds\");\n var secondInput = createNumberInput(\"flatpickr-second\");\n self.secondElement = secondInput.getElementsByTagName(\"input\")[0];\n self.secondElement.value = pad(self.latestSelectedDateObj\n ? self.latestSelectedDateObj.getSeconds()\n : self.config.defaultSeconds);\n self.secondElement.setAttribute(\"step\", self.minuteElement.getAttribute(\"step\"));\n self.secondElement.setAttribute(\"min\", \"0\");\n self.secondElement.setAttribute(\"max\", \"59\");\n self.timeContainer.appendChild(createElement(\"span\", \"flatpickr-time-separator\", \":\"));\n self.timeContainer.appendChild(secondInput);\n }\n if (!self.config.time_24hr) {\n // add self.amPM if appropriate\n self.amPM = createElement(\"span\", \"flatpickr-am-pm\", self.l10n.amPM[int((self.latestSelectedDateObj\n ? self.hourElement.value\n : self.config.defaultHour) > 11)]);\n self.amPM.title = self.l10n.toggleTitle;\n self.amPM.tabIndex = -1;\n self.timeContainer.appendChild(self.amPM);\n }\n return self.timeContainer;\n }\n function buildWeekdays() {\n if (!self.weekdayContainer)\n self.weekdayContainer = createElement(\"div\", \"flatpickr-weekdays\");\n else\n clearNode(self.weekdayContainer);\n for (var i = self.config.showMonths; i--;) {\n var container = createElement(\"div\", \"flatpickr-weekdaycontainer\");\n self.weekdayContainer.appendChild(container);\n }\n updateWeekdays();\n return self.weekdayContainer;\n }\n function updateWeekdays() {\n if (!self.weekdayContainer) {\n return;\n }\n var firstDayOfWeek = self.l10n.firstDayOfWeek;\n var weekdays = __spreadArrays(self.l10n.weekdays.shorthand);\n if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {\n weekdays = __spreadArrays(weekdays.splice(firstDayOfWeek, weekdays.length), weekdays.splice(0, firstDayOfWeek));\n }\n for (var i = self.config.showMonths; i--;) {\n self.weekdayContainer.children[i].innerHTML = \"\\n \\n \" + weekdays.join(\"\") + \"\\n \\n \";\n }\n }\n /* istanbul ignore next */\n function buildWeeks() {\n self.calendarContainer.classList.add(\"hasWeeks\");\n var weekWrapper = createElement(\"div\", \"flatpickr-weekwrapper\");\n weekWrapper.appendChild(createElement(\"span\", \"flatpickr-weekday\", self.l10n.weekAbbreviation));\n var weekNumbers = createElement(\"div\", \"flatpickr-weeks\");\n weekWrapper.appendChild(weekNumbers);\n return {\n weekWrapper: weekWrapper,\n weekNumbers: weekNumbers,\n };\n }\n function changeMonth(value, isOffset) {\n if (isOffset === void 0) { isOffset = true; }\n var delta = isOffset ? value : value - self.currentMonth;\n if ((delta < 0 && self._hidePrevMonthArrow === true) ||\n (delta > 0 && self._hideNextMonthArrow === true))\n return;\n self.currentMonth += delta;\n if (self.currentMonth < 0 || self.currentMonth > 11) {\n self.currentYear += self.currentMonth > 11 ? 1 : -1;\n self.currentMonth = (self.currentMonth + 12) % 12;\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n buildDays();\n triggerEvent(\"onMonthChange\");\n updateNavigationCurrentMonth();\n }\n function clear(triggerChangeEvent, toInitial) {\n if (triggerChangeEvent === void 0) { triggerChangeEvent = true; }\n if (toInitial === void 0) { toInitial = true; }\n self.input.value = \"\";\n if (self.altInput !== undefined)\n self.altInput.value = \"\";\n if (self.mobileInput !== undefined)\n self.mobileInput.value = \"\";\n self.selectedDates = [];\n self.latestSelectedDateObj = undefined;\n if (toInitial === true) {\n self.currentYear = self._initialDate.getFullYear();\n self.currentMonth = self._initialDate.getMonth();\n }\n if (self.config.enableTime === true) {\n var _a = getDefaultHours(), hours = _a.hours, minutes = _a.minutes, seconds = _a.seconds;\n setHours(hours, minutes, seconds);\n }\n self.redraw();\n if (triggerChangeEvent)\n // triggerChangeEvent is true (default) or an Event\n triggerEvent(\"onChange\");\n }\n function close() {\n self.isOpen = false;\n if (!self.isMobile) {\n if (self.calendarContainer !== undefined) {\n self.calendarContainer.classList.remove(\"open\");\n }\n if (self._input !== undefined) {\n self._input.classList.remove(\"active\");\n }\n }\n triggerEvent(\"onClose\");\n }\n function destroy() {\n if (self.config !== undefined)\n triggerEvent(\"onDestroy\");\n for (var i = self._handlers.length; i--;) {\n var h = self._handlers[i];\n h.element.removeEventListener(h.event, h.handler, h.options);\n }\n self._handlers = [];\n if (self.mobileInput) {\n if (self.mobileInput.parentNode)\n self.mobileInput.parentNode.removeChild(self.mobileInput);\n self.mobileInput = undefined;\n }\n else if (self.calendarContainer && self.calendarContainer.parentNode) {\n if (self.config.static && self.calendarContainer.parentNode) {\n var wrapper = self.calendarContainer.parentNode;\n wrapper.lastChild && wrapper.removeChild(wrapper.lastChild);\n if (wrapper.parentNode) {\n while (wrapper.firstChild)\n wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper);\n wrapper.parentNode.removeChild(wrapper);\n }\n }\n else\n self.calendarContainer.parentNode.removeChild(self.calendarContainer);\n }\n if (self.altInput) {\n self.input.type = \"text\";\n if (self.altInput.parentNode)\n self.altInput.parentNode.removeChild(self.altInput);\n delete self.altInput;\n }\n if (self.input) {\n self.input.type = self.input._type;\n self.input.classList.remove(\"flatpickr-input\");\n self.input.removeAttribute(\"readonly\");\n }\n [\n \"_showTimeInput\",\n \"latestSelectedDateObj\",\n \"_hideNextMonthArrow\",\n \"_hidePrevMonthArrow\",\n \"__hideNextMonthArrow\",\n \"__hidePrevMonthArrow\",\n \"isMobile\",\n \"isOpen\",\n \"selectedDateElem\",\n \"minDateHasTime\",\n \"maxDateHasTime\",\n \"days\",\n \"daysContainer\",\n \"_input\",\n \"_positionElement\",\n \"innerContainer\",\n \"rContainer\",\n \"monthNav\",\n \"todayDateElem\",\n \"calendarContainer\",\n \"weekdayContainer\",\n \"prevMonthNav\",\n \"nextMonthNav\",\n \"monthsDropdownContainer\",\n \"currentMonthElement\",\n \"currentYearElement\",\n \"navigationCurrentMonth\",\n \"selectedDateElem\",\n \"config\",\n ].forEach(function (k) {\n try {\n delete self[k];\n }\n catch (_) { }\n });\n }\n function isCalendarElem(elem) {\n if (self.config.appendTo && self.config.appendTo.contains(elem))\n return true;\n return self.calendarContainer.contains(elem);\n }\n function documentClick(e) {\n if (self.isOpen && !self.config.inline) {\n var eventTarget_1 = getEventTarget(e);\n var isCalendarElement = isCalendarElem(eventTarget_1);\n var isInput = eventTarget_1 === self.input ||\n eventTarget_1 === self.altInput ||\n self.element.contains(eventTarget_1) ||\n // web components\n // e.path is not present in all browsers. circumventing typechecks\n (e.path &&\n e.path.indexOf &&\n (~e.path.indexOf(self.input) ||\n ~e.path.indexOf(self.altInput)));\n var lostFocus = e.type === \"blur\"\n ? isInput &&\n e.relatedTarget &&\n !isCalendarElem(e.relatedTarget)\n : !isInput &&\n !isCalendarElement &&\n !isCalendarElem(e.relatedTarget);\n var isIgnored = !self.config.ignoredFocusElements.some(function (elem) {\n return elem.contains(eventTarget_1);\n });\n if (lostFocus && isIgnored) {\n if (self.timeContainer !== undefined &&\n self.minuteElement !== undefined &&\n self.hourElement !== undefined &&\n self.input.value !== \"\" &&\n self.input.value !== undefined) {\n updateTime();\n }\n self.close();\n if (self.config &&\n self.config.mode === \"range\" &&\n self.selectedDates.length === 1) {\n self.clear(false);\n self.redraw();\n }\n }\n }\n }\n function changeYear(newYear) {\n if (!newYear ||\n (self.config.minDate && newYear < self.config.minDate.getFullYear()) ||\n (self.config.maxDate && newYear > self.config.maxDate.getFullYear()))\n return;\n var newYearNum = newYear, isNewYear = self.currentYear !== newYearNum;\n self.currentYear = newYearNum || self.currentYear;\n if (self.config.maxDate &&\n self.currentYear === self.config.maxDate.getFullYear()) {\n self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);\n }\n else if (self.config.minDate &&\n self.currentYear === self.config.minDate.getFullYear()) {\n self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);\n }\n if (isNewYear) {\n self.redraw();\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n }\n function isEnabled(date, timeless) {\n if (timeless === void 0) { timeless = true; }\n var dateToCheck = self.parseDate(date, undefined, timeless); // timeless\n if ((self.config.minDate &&\n dateToCheck &&\n compareDates(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0) ||\n (self.config.maxDate &&\n dateToCheck &&\n compareDates(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0))\n return false;\n if (self.config.enable.length === 0 && self.config.disable.length === 0)\n return true;\n if (dateToCheck === undefined)\n return false;\n var bool = self.config.enable.length > 0, array = bool ? self.config.enable : self.config.disable;\n for (var i = 0, d = void 0; i < array.length; i++) {\n d = array[i];\n if (typeof d === \"function\" &&\n d(dateToCheck) // disabled by function\n )\n return bool;\n else if (d instanceof Date &&\n dateToCheck !== undefined &&\n d.getTime() === dateToCheck.getTime())\n // disabled by date\n return bool;\n else if (typeof d === \"string\" && dateToCheck !== undefined) {\n // disabled by date string\n var parsed = self.parseDate(d, undefined, true);\n return parsed && parsed.getTime() === dateToCheck.getTime()\n ? bool\n : !bool;\n }\n else if (\n // disabled by range\n typeof d === \"object\" &&\n dateToCheck !== undefined &&\n d.from &&\n d.to &&\n dateToCheck.getTime() >= d.from.getTime() &&\n dateToCheck.getTime() <= d.to.getTime())\n return bool;\n }\n return !bool;\n }\n function isInView(elem) {\n if (self.daysContainer !== undefined)\n return (elem.className.indexOf(\"hidden\") === -1 &&\n elem.className.indexOf(\"flatpickr-disabled\") === -1 &&\n self.daysContainer.contains(elem));\n return false;\n }\n function onBlur(e) {\n var isInput = e.target === self._input;\n if (isInput &&\n !(e.relatedTarget && isCalendarElem(e.relatedTarget))) {\n self.setDate(self._input.value, true, e.target === self.altInput\n ? self.config.altFormat\n : self.config.dateFormat);\n }\n }\n function onKeyDown(e) {\n // e.key e.keyCode\n // \"Backspace\" 8\n // \"Tab\" 9\n // \"Enter\" 13\n // \"Escape\" (IE \"Esc\") 27\n // \"ArrowLeft\" (IE \"Left\") 37\n // \"ArrowUp\" (IE \"Up\") 38\n // \"ArrowRight\" (IE \"Right\") 39\n // \"ArrowDown\" (IE \"Down\") 40\n // \"Delete\" (IE \"Del\") 46\n var eventTarget = getEventTarget(e);\n var isInput = self.config.wrap\n ? element.contains(eventTarget)\n : eventTarget === self._input;\n var allowInput = self.config.allowInput;\n var allowKeydown = self.isOpen && (!allowInput || !isInput);\n var allowInlineKeydown = self.config.inline && isInput && !allowInput;\n if (e.keyCode === 13 && isInput) {\n if (allowInput) {\n self.setDate(self._input.value, true, eventTarget === self.altInput\n ? self.config.altFormat\n : self.config.dateFormat);\n return eventTarget.blur();\n }\n else {\n self.open();\n }\n }\n else if (isCalendarElem(eventTarget) ||\n allowKeydown ||\n allowInlineKeydown) {\n var isTimeObj = !!self.timeContainer &&\n self.timeContainer.contains(eventTarget);\n switch (e.keyCode) {\n case 13:\n if (isTimeObj) {\n e.preventDefault();\n updateTime();\n focusAndClose();\n }\n else\n selectDate(e);\n break;\n case 27: // escape\n e.preventDefault();\n focusAndClose();\n break;\n case 8:\n case 46:\n if (isInput && !self.config.allowInput) {\n e.preventDefault();\n self.clear();\n }\n break;\n case 37:\n case 39:\n if (!isTimeObj && !isInput) {\n e.preventDefault();\n if (self.daysContainer !== undefined &&\n (allowInput === false ||\n (document.activeElement && isInView(document.activeElement)))) {\n var delta_1 = e.keyCode === 39 ? 1 : -1;\n if (!e.ctrlKey)\n focusOnDay(undefined, delta_1);\n else {\n e.stopPropagation();\n changeMonth(delta_1);\n focusOnDay(getFirstAvailableDay(1), 0);\n }\n }\n }\n else if (self.hourElement)\n self.hourElement.focus();\n break;\n case 38:\n case 40:\n e.preventDefault();\n var delta = e.keyCode === 40 ? 1 : -1;\n if ((self.daysContainer &&\n eventTarget.$i !== undefined) ||\n eventTarget === self.input ||\n eventTarget === self.altInput) {\n if (e.ctrlKey) {\n e.stopPropagation();\n changeYear(self.currentYear - delta);\n focusOnDay(getFirstAvailableDay(1), 0);\n }\n else if (!isTimeObj)\n focusOnDay(undefined, delta * 7);\n }\n else if (eventTarget === self.currentYearElement) {\n changeYear(self.currentYear - delta);\n }\n else if (self.config.enableTime) {\n if (!isTimeObj && self.hourElement)\n self.hourElement.focus();\n updateTime(e);\n self._debouncedChange();\n }\n break;\n case 9:\n if (isTimeObj) {\n var elems = [\n self.hourElement,\n self.minuteElement,\n self.secondElement,\n self.amPM,\n ]\n .concat(self.pluginElements)\n .filter(function (x) { return x; });\n var i = elems.indexOf(eventTarget);\n if (i !== -1) {\n var target = elems[i + (e.shiftKey ? -1 : 1)];\n e.preventDefault();\n (target || self._input).focus();\n }\n }\n else if (!self.config.noCalendar &&\n self.daysContainer &&\n self.daysContainer.contains(eventTarget) &&\n e.shiftKey) {\n e.preventDefault();\n self._input.focus();\n }\n break;\n }\n }\n if (self.amPM !== undefined && eventTarget === self.amPM) {\n switch (e.key) {\n case self.l10n.amPM[0].charAt(0):\n case self.l10n.amPM[0].charAt(0).toLowerCase():\n self.amPM.textContent = self.l10n.amPM[0];\n setHoursFromInputs();\n updateValue();\n break;\n case self.l10n.amPM[1].charAt(0):\n case self.l10n.amPM[1].charAt(0).toLowerCase():\n self.amPM.textContent = self.l10n.amPM[1];\n setHoursFromInputs();\n updateValue();\n break;\n }\n }\n if (isInput || isCalendarElem(eventTarget)) {\n triggerEvent(\"onKeyDown\", e);\n }\n }\n function onMouseOver(elem) {\n if (self.selectedDates.length !== 1 ||\n (elem &&\n (!elem.classList.contains(\"flatpickr-day\") ||\n elem.classList.contains(\"flatpickr-disabled\"))))\n return;\n var hoverDate = elem\n ? elem.dateObj.getTime()\n : self.days.firstElementChild.dateObj.getTime(), initialDate = self.parseDate(self.selectedDates[0], undefined, true).getTime(), rangeStartDate = Math.min(hoverDate, self.selectedDates[0].getTime()), rangeEndDate = Math.max(hoverDate, self.selectedDates[0].getTime());\n var containsDisabled = false;\n var minRange = 0, maxRange = 0;\n for (var t = rangeStartDate; t < rangeEndDate; t += duration.DAY) {\n if (!isEnabled(new Date(t), true)) {\n containsDisabled =\n containsDisabled || (t > rangeStartDate && t < rangeEndDate);\n if (t < initialDate && (!minRange || t > minRange))\n minRange = t;\n else if (t > initialDate && (!maxRange || t < maxRange))\n maxRange = t;\n }\n }\n for (var m = 0; m < self.config.showMonths; m++) {\n var month = self.daysContainer.children[m];\n var _loop_1 = function (i, l) {\n var dayElem = month.children[i], date = dayElem.dateObj;\n var timestamp = date.getTime();\n var outOfRange = (minRange > 0 && timestamp < minRange) ||\n (maxRange > 0 && timestamp > maxRange);\n if (outOfRange) {\n dayElem.classList.add(\"notAllowed\");\n [\"inRange\", \"startRange\", \"endRange\"].forEach(function (c) {\n dayElem.classList.remove(c);\n });\n return \"continue\";\n }\n else if (containsDisabled && !outOfRange)\n return \"continue\";\n [\"startRange\", \"inRange\", \"endRange\", \"notAllowed\"].forEach(function (c) {\n dayElem.classList.remove(c);\n });\n if (elem !== undefined) {\n elem.classList.add(hoverDate <= self.selectedDates[0].getTime()\n ? \"startRange\"\n : \"endRange\");\n if (initialDate < hoverDate && timestamp === initialDate)\n dayElem.classList.add(\"startRange\");\n else if (initialDate > hoverDate && timestamp === initialDate)\n dayElem.classList.add(\"endRange\");\n if (timestamp >= minRange &&\n (maxRange === 0 || timestamp <= maxRange) &&\n isBetween(timestamp, initialDate, hoverDate))\n dayElem.classList.add(\"inRange\");\n }\n };\n for (var i = 0, l = month.children.length; i < l; i++) {\n _loop_1(i, l);\n }\n }\n }\n function onResize() {\n if (self.isOpen && !self.config.static && !self.config.inline)\n positionCalendar();\n }\n function open(e, positionElement) {\n if (positionElement === void 0) { positionElement = self._positionElement; }\n if (self.isMobile === true) {\n if (e) {\n e.preventDefault();\n var eventTarget = getEventTarget(e);\n eventTarget && eventTarget.blur();\n }\n if (self.mobileInput !== undefined) {\n self.mobileInput.focus();\n self.mobileInput.click();\n }\n triggerEvent(\"onOpen\");\n return;\n }\n if (self._input.disabled || self.config.inline)\n return;\n var wasOpen = self.isOpen;\n self.isOpen = true;\n if (!wasOpen) {\n self.calendarContainer.classList.add(\"open\");\n self._input.classList.add(\"active\");\n triggerEvent(\"onOpen\");\n positionCalendar(positionElement);\n }\n if (self.config.enableTime === true && self.config.noCalendar === true) {\n if (self.config.allowInput === false &&\n (e === undefined ||\n !self.timeContainer.contains(e.relatedTarget))) {\n setTimeout(function () { return self.hourElement.select(); }, 50);\n }\n }\n }\n function minMaxDateSetter(type) {\n return function (date) {\n var dateObj = (self.config[\"_\" + type + \"Date\"] = self.parseDate(date, self.config.dateFormat));\n var inverseDateObj = self.config[\"_\" + (type === \"min\" ? \"max\" : \"min\") + \"Date\"];\n if (dateObj !== undefined) {\n self[type === \"min\" ? \"minDateHasTime\" : \"maxDateHasTime\"] =\n dateObj.getHours() > 0 ||\n dateObj.getMinutes() > 0 ||\n dateObj.getSeconds() > 0;\n }\n if (self.selectedDates) {\n self.selectedDates = self.selectedDates.filter(function (d) { return isEnabled(d); });\n if (!self.selectedDates.length && type === \"min\")\n setHoursFromDate(dateObj);\n updateValue();\n }\n if (self.daysContainer) {\n redraw();\n if (dateObj !== undefined)\n self.currentYearElement[type] = dateObj.getFullYear().toString();\n else\n self.currentYearElement.removeAttribute(type);\n self.currentYearElement.disabled =\n !!inverseDateObj &&\n dateObj !== undefined &&\n inverseDateObj.getFullYear() === dateObj.getFullYear();\n }\n };\n }\n function parseConfig() {\n var boolOpts = [\n \"wrap\",\n \"weekNumbers\",\n \"allowInput\",\n \"allowInvalidPreload\",\n \"clickOpens\",\n \"time_24hr\",\n \"enableTime\",\n \"noCalendar\",\n \"altInput\",\n \"shorthandCurrentMonth\",\n \"inline\",\n \"static\",\n \"enableSeconds\",\n \"disableMobile\",\n ];\n var userConfig = __assign(__assign({}, JSON.parse(JSON.stringify(element.dataset || {}))), instanceConfig);\n var formats = {};\n self.config.parseDate = userConfig.parseDate;\n self.config.formatDate = userConfig.formatDate;\n Object.defineProperty(self.config, \"enable\", {\n get: function () { return self.config._enable; },\n set: function (dates) {\n self.config._enable = parseDateRules(dates);\n },\n });\n Object.defineProperty(self.config, \"disable\", {\n get: function () { return self.config._disable; },\n set: function (dates) {\n self.config._disable = parseDateRules(dates);\n },\n });\n var timeMode = userConfig.mode === \"time\";\n if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) {\n var defaultDateFormat = flatpickr.defaultConfig.dateFormat || defaults.dateFormat;\n formats.dateFormat =\n userConfig.noCalendar || timeMode\n ? \"H:i\" + (userConfig.enableSeconds ? \":S\" : \"\")\n : defaultDateFormat + \" H:i\" + (userConfig.enableSeconds ? \":S\" : \"\");\n }\n if (userConfig.altInput &&\n (userConfig.enableTime || timeMode) &&\n !userConfig.altFormat) {\n var defaultAltFormat = flatpickr.defaultConfig.altFormat || defaults.altFormat;\n formats.altFormat =\n userConfig.noCalendar || timeMode\n ? \"h:i\" + (userConfig.enableSeconds ? \":S K\" : \" K\")\n : defaultAltFormat + (\" h:i\" + (userConfig.enableSeconds ? \":S\" : \"\") + \" K\");\n }\n Object.defineProperty(self.config, \"minDate\", {\n get: function () { return self.config._minDate; },\n set: minMaxDateSetter(\"min\"),\n });\n Object.defineProperty(self.config, \"maxDate\", {\n get: function () { return self.config._maxDate; },\n set: minMaxDateSetter(\"max\"),\n });\n var minMaxTimeSetter = function (type) { return function (val) {\n self.config[type === \"min\" ? \"_minTime\" : \"_maxTime\"] = self.parseDate(val, \"H:i:S\");\n }; };\n Object.defineProperty(self.config, \"minTime\", {\n get: function () { return self.config._minTime; },\n set: minMaxTimeSetter(\"min\"),\n });\n Object.defineProperty(self.config, \"maxTime\", {\n get: function () { return self.config._maxTime; },\n set: minMaxTimeSetter(\"max\"),\n });\n if (userConfig.mode === \"time\") {\n self.config.noCalendar = true;\n self.config.enableTime = true;\n }\n Object.assign(self.config, formats, userConfig);\n for (var i = 0; i < boolOpts.length; i++)\n // https://github.com/microsoft/TypeScript/issues/31663\n self.config[boolOpts[i]] =\n self.config[boolOpts[i]] === true ||\n self.config[boolOpts[i]] === \"true\";\n HOOKS.filter(function (hook) { return self.config[hook] !== undefined; }).forEach(function (hook) {\n self.config[hook] = arrayify(self.config[hook] || []).map(bindToInstance);\n });\n self.isMobile =\n !self.config.disableMobile &&\n !self.config.inline &&\n self.config.mode === \"single\" &&\n !self.config.disable.length &&\n !self.config.enable.length &&\n !self.config.weekNumbers &&\n /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n for (var i = 0; i < self.config.plugins.length; i++) {\n var pluginConf = self.config.plugins[i](self) || {};\n for (var key in pluginConf) {\n if (HOOKS.indexOf(key) > -1) {\n self.config[key] = arrayify(pluginConf[key])\n .map(bindToInstance)\n .concat(self.config[key]);\n }\n else if (typeof userConfig[key] === \"undefined\")\n self.config[key] = pluginConf[key];\n }\n }\n if (!userConfig.altInputClass) {\n self.config.altInputClass =\n getInputElem().className + \" \" + self.config.altInputClass;\n }\n triggerEvent(\"onParseConfig\");\n }\n function getInputElem() {\n return self.config.wrap\n ? element.querySelector(\"[data-input]\")\n : element;\n }\n function setupLocale() {\n if (typeof self.config.locale !== \"object\" &&\n typeof flatpickr.l10ns[self.config.locale] === \"undefined\")\n self.config.errorHandler(new Error(\"flatpickr: invalid locale \" + self.config.locale));\n self.l10n = __assign(__assign({}, flatpickr.l10ns.default), (typeof self.config.locale === \"object\"\n ? self.config.locale\n : self.config.locale !== \"default\"\n ? flatpickr.l10ns[self.config.locale]\n : undefined));\n tokenRegex.K = \"(\" + self.l10n.amPM[0] + \"|\" + self.l10n.amPM[1] + \"|\" + self.l10n.amPM[0].toLowerCase() + \"|\" + self.l10n.amPM[1].toLowerCase() + \")\";\n var userConfig = __assign(__assign({}, instanceConfig), JSON.parse(JSON.stringify(element.dataset || {})));\n if (userConfig.time_24hr === undefined &&\n flatpickr.defaultConfig.time_24hr === undefined) {\n self.config.time_24hr = self.l10n.time_24hr;\n }\n self.formatDate = createDateFormatter(self);\n self.parseDate = createDateParser({ config: self.config, l10n: self.l10n });\n }\n function positionCalendar(customPositionElement) {\n if (self.calendarContainer === undefined)\n return;\n triggerEvent(\"onPreCalendarPosition\");\n var positionElement = customPositionElement || self._positionElement;\n var calendarHeight = Array.prototype.reduce.call(self.calendarContainer.children, (function (acc, child) { return acc + child.offsetHeight; }), 0), calendarWidth = self.calendarContainer.offsetWidth, configPos = self.config.position.split(\" \"), configPosVertical = configPos[0], configPosHorizontal = configPos.length > 1 ? configPos[1] : null, inputBounds = positionElement.getBoundingClientRect(), distanceFromBottom = window.innerHeight - inputBounds.bottom, showOnTop = configPosVertical === \"above\" ||\n (configPosVertical !== \"below\" &&\n distanceFromBottom < calendarHeight &&\n inputBounds.top > calendarHeight);\n var top = window.pageYOffset +\n inputBounds.top +\n (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2);\n toggleClass(self.calendarContainer, \"arrowTop\", !showOnTop);\n toggleClass(self.calendarContainer, \"arrowBottom\", showOnTop);\n if (self.config.inline)\n return;\n var left = window.pageXOffset + inputBounds.left;\n var isCenter = false;\n var isRight = false;\n if (configPosHorizontal === \"center\") {\n left -= (calendarWidth - inputBounds.width) / 2;\n isCenter = true;\n }\n else if (configPosHorizontal === \"right\") {\n left -= calendarWidth - inputBounds.width;\n isRight = true;\n }\n toggleClass(self.calendarContainer, \"arrowLeft\", !isCenter && !isRight);\n toggleClass(self.calendarContainer, \"arrowCenter\", isCenter);\n toggleClass(self.calendarContainer, \"arrowRight\", isRight);\n var right = window.document.body.offsetWidth -\n (window.pageXOffset + inputBounds.right);\n var rightMost = left + calendarWidth > window.document.body.offsetWidth;\n var centerMost = right + calendarWidth > window.document.body.offsetWidth;\n toggleClass(self.calendarContainer, \"rightMost\", rightMost);\n if (self.config.static)\n return;\n self.calendarContainer.style.top = top + \"px\";\n if (!rightMost) {\n self.calendarContainer.style.left = left + \"px\";\n self.calendarContainer.style.right = \"auto\";\n }\n else if (!centerMost) {\n self.calendarContainer.style.left = \"auto\";\n self.calendarContainer.style.right = right + \"px\";\n }\n else {\n var doc = getDocumentStyleSheet();\n // some testing environments don't have css support\n if (doc === undefined)\n return;\n var bodyWidth = window.document.body.offsetWidth;\n var centerLeft = Math.max(0, bodyWidth / 2 - calendarWidth / 2);\n var centerBefore = \".flatpickr-calendar.centerMost:before\";\n var centerAfter = \".flatpickr-calendar.centerMost:after\";\n var centerIndex = doc.cssRules.length;\n var centerStyle = \"{left:\" + inputBounds.left + \"px;right:auto;}\";\n toggleClass(self.calendarContainer, \"rightMost\", false);\n toggleClass(self.calendarContainer, \"centerMost\", true);\n doc.insertRule(centerBefore + \",\" + centerAfter + centerStyle, centerIndex);\n self.calendarContainer.style.left = centerLeft + \"px\";\n self.calendarContainer.style.right = \"auto\";\n }\n }\n function getDocumentStyleSheet() {\n var editableSheet = null;\n for (var i = 0; i < document.styleSheets.length; i++) {\n var sheet = document.styleSheets[i];\n try {\n sheet.cssRules;\n }\n catch (err) {\n continue;\n }\n editableSheet = sheet;\n break;\n }\n return editableSheet != null ? editableSheet : createStyleSheet();\n }\n function createStyleSheet() {\n var style = document.createElement(\"style\");\n document.head.appendChild(style);\n return style.sheet;\n }\n function redraw() {\n if (self.config.noCalendar || self.isMobile)\n return;\n buildMonthSwitch();\n updateNavigationCurrentMonth();\n buildDays();\n }\n function focusAndClose() {\n self._input.focus();\n if (window.navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.msMaxTouchPoints !== undefined) {\n // hack - bugs in the way IE handles focus keeps the calendar open\n setTimeout(self.close, 0);\n }\n else {\n self.close();\n }\n }\n function selectDate(e) {\n e.preventDefault();\n e.stopPropagation();\n var isSelectable = function (day) {\n return day.classList &&\n day.classList.contains(\"flatpickr-day\") &&\n !day.classList.contains(\"flatpickr-disabled\") &&\n !day.classList.contains(\"notAllowed\");\n };\n var t = findParent(getEventTarget(e), isSelectable);\n if (t === undefined)\n return;\n var target = t;\n var selectedDate = (self.latestSelectedDateObj = new Date(target.dateObj.getTime()));\n var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth ||\n selectedDate.getMonth() >\n self.currentMonth + self.config.showMonths - 1) &&\n self.config.mode !== \"range\";\n self.selectedDateElem = target;\n if (self.config.mode === \"single\")\n self.selectedDates = [selectedDate];\n else if (self.config.mode === \"multiple\") {\n var selectedIndex = isDateSelected(selectedDate);\n if (selectedIndex)\n self.selectedDates.splice(parseInt(selectedIndex), 1);\n else\n self.selectedDates.push(selectedDate);\n }\n else if (self.config.mode === \"range\") {\n if (self.selectedDates.length === 2) {\n self.clear(false, false);\n }\n self.latestSelectedDateObj = selectedDate;\n self.selectedDates.push(selectedDate);\n // unless selecting same date twice, sort ascendingly\n if (compareDates(selectedDate, self.selectedDates[0], true) !== 0)\n self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });\n }\n setHoursFromInputs();\n if (shouldChangeMonth) {\n var isNewYear = self.currentYear !== selectedDate.getFullYear();\n self.currentYear = selectedDate.getFullYear();\n self.currentMonth = selectedDate.getMonth();\n if (isNewYear) {\n triggerEvent(\"onYearChange\");\n buildMonthSwitch();\n }\n triggerEvent(\"onMonthChange\");\n }\n updateNavigationCurrentMonth();\n buildDays();\n updateValue();\n // maintain focus\n if (!shouldChangeMonth &&\n self.config.mode !== \"range\" &&\n self.config.showMonths === 1)\n focusOnDayElem(target);\n else if (self.selectedDateElem !== undefined &&\n self.hourElement === undefined) {\n self.selectedDateElem && self.selectedDateElem.focus();\n }\n if (self.hourElement !== undefined)\n self.hourElement !== undefined && self.hourElement.focus();\n if (self.config.closeOnSelect) {\n var single = self.config.mode === \"single\" && !self.config.enableTime;\n var range = self.config.mode === \"range\" &&\n self.selectedDates.length === 2 &&\n !self.config.enableTime;\n if (single || range) {\n focusAndClose();\n }\n }\n triggerChange();\n }\n var CALLBACKS = {\n locale: [setupLocale, updateWeekdays],\n showMonths: [buildMonths, setCalendarWidth, buildWeekdays],\n minDate: [jumpToDate],\n maxDate: [jumpToDate],\n };\n function set(option, value) {\n if (option !== null && typeof option === \"object\") {\n Object.assign(self.config, option);\n for (var key in option) {\n if (CALLBACKS[key] !== undefined)\n CALLBACKS[key].forEach(function (x) { return x(); });\n }\n }\n else {\n self.config[option] = value;\n if (CALLBACKS[option] !== undefined)\n CALLBACKS[option].forEach(function (x) { return x(); });\n else if (HOOKS.indexOf(option) > -1)\n self.config[option] = arrayify(value);\n }\n self.redraw();\n updateValue(true);\n }\n function setSelectedDate(inputDate, format) {\n var dates = [];\n if (inputDate instanceof Array)\n dates = inputDate.map(function (d) { return self.parseDate(d, format); });\n else if (inputDate instanceof Date || typeof inputDate === \"number\")\n dates = [self.parseDate(inputDate, format)];\n else if (typeof inputDate === \"string\") {\n switch (self.config.mode) {\n case \"single\":\n case \"time\":\n dates = [self.parseDate(inputDate, format)];\n break;\n case \"multiple\":\n dates = inputDate\n .split(self.config.conjunction)\n .map(function (date) { return self.parseDate(date, format); });\n break;\n case \"range\":\n dates = inputDate\n .split(self.l10n.rangeSeparator)\n .map(function (date) { return self.parseDate(date, format); });\n break;\n }\n }\n else\n self.config.errorHandler(new Error(\"Invalid date supplied: \" + JSON.stringify(inputDate)));\n self.selectedDates = (self.config.allowInvalidPreload\n ? dates\n : dates.filter(function (d) { return d instanceof Date && isEnabled(d, false); }));\n if (self.config.mode === \"range\")\n self.selectedDates.sort(function (a, b) { return a.getTime() - b.getTime(); });\n }\n function setDate(date, triggerChange, format) {\n if (triggerChange === void 0) { triggerChange = false; }\n if (format === void 0) { format = self.config.dateFormat; }\n if ((date !== 0 && !date) || (date instanceof Array && date.length === 0))\n return self.clear(triggerChange);\n setSelectedDate(date, format);\n self.latestSelectedDateObj =\n self.selectedDates[self.selectedDates.length - 1];\n self.redraw();\n jumpToDate(undefined, triggerChange);\n setHoursFromDate();\n if (self.selectedDates.length === 0) {\n self.clear(false);\n }\n updateValue(triggerChange);\n if (triggerChange)\n triggerEvent(\"onChange\");\n }\n function parseDateRules(arr) {\n return arr\n .slice()\n .map(function (rule) {\n if (typeof rule === \"string\" ||\n typeof rule === \"number\" ||\n rule instanceof Date) {\n return self.parseDate(rule, undefined, true);\n }\n else if (rule &&\n typeof rule === \"object\" &&\n rule.from &&\n rule.to)\n return {\n from: self.parseDate(rule.from, undefined),\n to: self.parseDate(rule.to, undefined),\n };\n return rule;\n })\n .filter(function (x) { return x; }); // remove falsy values\n }\n function setupDates() {\n self.selectedDates = [];\n self.now = self.parseDate(self.config.now) || new Date();\n // Workaround IE11 setting placeholder as the input's value\n var preloadedDate = self.config.defaultDate ||\n ((self.input.nodeName === \"INPUT\" ||\n self.input.nodeName === \"TEXTAREA\") &&\n self.input.placeholder &&\n self.input.value === self.input.placeholder\n ? null\n : self.input.value);\n if (preloadedDate)\n setSelectedDate(preloadedDate, self.config.dateFormat);\n self._initialDate =\n self.selectedDates.length > 0\n ? self.selectedDates[0]\n : self.config.minDate &&\n self.config.minDate.getTime() > self.now.getTime()\n ? self.config.minDate\n : self.config.maxDate &&\n self.config.maxDate.getTime() < self.now.getTime()\n ? self.config.maxDate\n : self.now;\n self.currentYear = self._initialDate.getFullYear();\n self.currentMonth = self._initialDate.getMonth();\n if (self.selectedDates.length > 0)\n self.latestSelectedDateObj = self.selectedDates[0];\n if (self.config.minTime !== undefined)\n self.config.minTime = self.parseDate(self.config.minTime, \"H:i\");\n if (self.config.maxTime !== undefined)\n self.config.maxTime = self.parseDate(self.config.maxTime, \"H:i\");\n self.minDateHasTime =\n !!self.config.minDate &&\n (self.config.minDate.getHours() > 0 ||\n self.config.minDate.getMinutes() > 0 ||\n self.config.minDate.getSeconds() > 0);\n self.maxDateHasTime =\n !!self.config.maxDate &&\n (self.config.maxDate.getHours() > 0 ||\n self.config.maxDate.getMinutes() > 0 ||\n self.config.maxDate.getSeconds() > 0);\n }\n function setupInputs() {\n self.input = getInputElem();\n /* istanbul ignore next */\n if (!self.input) {\n self.config.errorHandler(new Error(\"Invalid input element specified\"));\n return;\n }\n // hack: store previous type to restore it after destroy()\n self.input._type = self.input.type;\n self.input.type = \"text\";\n self.input.classList.add(\"flatpickr-input\");\n self._input = self.input;\n if (self.config.altInput) {\n // replicate self.element\n self.altInput = createElement(self.input.nodeName, self.config.altInputClass);\n self._input = self.altInput;\n self.altInput.placeholder = self.input.placeholder;\n self.altInput.disabled = self.input.disabled;\n self.altInput.required = self.input.required;\n self.altInput.tabIndex = self.input.tabIndex;\n self.altInput.type = \"text\";\n self.input.setAttribute(\"type\", \"hidden\");\n if (!self.config.static && self.input.parentNode)\n self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);\n }\n if (!self.config.allowInput)\n self._input.setAttribute(\"readonly\", \"readonly\");\n self._positionElement = self.config.positionElement || self._input;\n }\n function setupMobile() {\n var inputType = self.config.enableTime\n ? self.config.noCalendar\n ? \"time\"\n : \"datetime-local\"\n : \"date\";\n self.mobileInput = createElement(\"input\", self.input.className + \" flatpickr-mobile\");\n self.mobileInput.tabIndex = 1;\n self.mobileInput.type = inputType;\n self.mobileInput.disabled = self.input.disabled;\n self.mobileInput.required = self.input.required;\n self.mobileInput.placeholder = self.input.placeholder;\n self.mobileFormatStr =\n inputType === \"datetime-local\"\n ? \"Y-m-d\\\\TH:i:S\"\n : inputType === \"date\"\n ? \"Y-m-d\"\n : \"H:i:S\";\n if (self.selectedDates.length > 0) {\n self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);\n }\n if (self.config.minDate)\n self.mobileInput.min = self.formatDate(self.config.minDate, \"Y-m-d\");\n if (self.config.maxDate)\n self.mobileInput.max = self.formatDate(self.config.maxDate, \"Y-m-d\");\n if (self.input.getAttribute(\"step\"))\n self.mobileInput.step = String(self.input.getAttribute(\"step\"));\n self.input.type = \"hidden\";\n if (self.altInput !== undefined)\n self.altInput.type = \"hidden\";\n try {\n if (self.input.parentNode)\n self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);\n }\n catch (_a) { }\n bind(self.mobileInput, \"change\", function (e) {\n self.setDate(getEventTarget(e).value, false, self.mobileFormatStr);\n triggerEvent(\"onChange\");\n triggerEvent(\"onClose\");\n });\n }\n function toggle(e) {\n if (self.isOpen === true)\n return self.close();\n self.open(e);\n }\n function triggerEvent(event, data) {\n // If the instance has been destroyed already, all hooks have been removed\n if (self.config === undefined)\n return;\n var hooks = self.config[event];\n if (hooks !== undefined && hooks.length > 0) {\n for (var i = 0; hooks[i] && i < hooks.length; i++)\n hooks[i](self.selectedDates, self.input.value, self, data);\n }\n if (event === \"onChange\") {\n self.input.dispatchEvent(createEvent(\"change\"));\n // many front-end frameworks bind to the input event\n self.input.dispatchEvent(createEvent(\"input\"));\n }\n }\n function createEvent(name) {\n var e = document.createEvent(\"Event\");\n e.initEvent(name, true, true);\n return e;\n }\n function isDateSelected(date) {\n for (var i = 0; i < self.selectedDates.length; i++) {\n if (compareDates(self.selectedDates[i], date) === 0)\n return \"\" + i;\n }\n return false;\n }\n function isDateInRange(date) {\n if (self.config.mode !== \"range\" || self.selectedDates.length < 2)\n return false;\n return (compareDates(date, self.selectedDates[0]) >= 0 &&\n compareDates(date, self.selectedDates[1]) <= 0);\n }\n function updateNavigationCurrentMonth() {\n if (self.config.noCalendar || self.isMobile || !self.monthNav)\n return;\n self.yearElements.forEach(function (yearElement, i) {\n var d = new Date(self.currentYear, self.currentMonth, 1);\n d.setMonth(self.currentMonth + i);\n if (self.config.showMonths > 1 ||\n self.config.monthSelectorType === \"static\") {\n self.monthElements[i].textContent =\n monthToStr(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) + \" \";\n }\n else {\n self.monthsDropdownContainer.value = d.getMonth().toString();\n }\n yearElement.value = d.getFullYear().toString();\n });\n self._hidePrevMonthArrow =\n self.config.minDate !== undefined &&\n (self.currentYear === self.config.minDate.getFullYear()\n ? self.currentMonth <= self.config.minDate.getMonth()\n : self.currentYear < self.config.minDate.getFullYear());\n self._hideNextMonthArrow =\n self.config.maxDate !== undefined &&\n (self.currentYear === self.config.maxDate.getFullYear()\n ? self.currentMonth + 1 > self.config.maxDate.getMonth()\n : self.currentYear > self.config.maxDate.getFullYear());\n }\n function getDateStr(format) {\n return self.selectedDates\n .map(function (dObj) { return self.formatDate(dObj, format); })\n .filter(function (d, i, arr) {\n return self.config.mode !== \"range\" ||\n self.config.enableTime ||\n arr.indexOf(d) === i;\n })\n .join(self.config.mode !== \"range\"\n ? self.config.conjunction\n : self.l10n.rangeSeparator);\n }\n /**\n * Updates the values of inputs associated with the calendar\n */\n function updateValue(triggerChange) {\n if (triggerChange === void 0) { triggerChange = true; }\n if (self.mobileInput !== undefined && self.mobileFormatStr) {\n self.mobileInput.value =\n self.latestSelectedDateObj !== undefined\n ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr)\n : \"\";\n }\n self.input.value = getDateStr(self.config.dateFormat);\n if (self.altInput !== undefined) {\n self.altInput.value = getDateStr(self.config.altFormat);\n }\n if (triggerChange !== false)\n triggerEvent(\"onValueUpdate\");\n }\n function onMonthNavClick(e) {\n var eventTarget = getEventTarget(e);\n var isPrevMonth = self.prevMonthNav.contains(eventTarget);\n var isNextMonth = self.nextMonthNav.contains(eventTarget);\n if (isPrevMonth || isNextMonth) {\n changeMonth(isPrevMonth ? -1 : 1);\n }\n else if (self.yearElements.indexOf(eventTarget) >= 0) {\n eventTarget.select();\n }\n else if (eventTarget.classList.contains(\"arrowUp\")) {\n self.changeYear(self.currentYear + 1);\n }\n else if (eventTarget.classList.contains(\"arrowDown\")) {\n self.changeYear(self.currentYear - 1);\n }\n }\n function timeWrapper(e) {\n e.preventDefault();\n var isKeyDown = e.type === \"keydown\", eventTarget = getEventTarget(e), input = eventTarget;\n if (self.amPM !== undefined && eventTarget === self.amPM) {\n self.amPM.textContent =\n self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];\n }\n var min = parseFloat(input.getAttribute(\"min\")), max = parseFloat(input.getAttribute(\"max\")), step = parseFloat(input.getAttribute(\"step\")), curValue = parseInt(input.value, 10), delta = e.delta ||\n (isKeyDown ? (e.which === 38 ? 1 : -1) : 0);\n var newValue = curValue + step * delta;\n if (typeof input.value !== \"undefined\" && input.value.length === 2) {\n var isHourElem = input === self.hourElement, isMinuteElem = input === self.minuteElement;\n if (newValue < min) {\n newValue =\n max +\n newValue +\n int(!isHourElem) +\n (int(isHourElem) && int(!self.amPM));\n if (isMinuteElem)\n incrementNumInput(undefined, -1, self.hourElement);\n }\n else if (newValue > max) {\n newValue =\n input === self.hourElement ? newValue - max - int(!self.amPM) : min;\n if (isMinuteElem)\n incrementNumInput(undefined, 1, self.hourElement);\n }\n if (self.amPM &&\n isHourElem &&\n (step === 1\n ? newValue + curValue === 23\n : Math.abs(newValue - curValue) > step)) {\n self.amPM.textContent =\n self.l10n.amPM[int(self.amPM.textContent === self.l10n.amPM[0])];\n }\n input.value = pad(newValue);\n }\n }\n init();\n return self;\n }\n /* istanbul ignore next */\n function _flatpickr(nodeList, config) {\n // static list\n var nodes = Array.prototype.slice\n .call(nodeList)\n .filter(function (x) { return x instanceof HTMLElement; });\n var instances = [];\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n try {\n if (node.getAttribute(\"data-fp-omit\") !== null)\n continue;\n if (node._flatpickr !== undefined) {\n node._flatpickr.destroy();\n node._flatpickr = undefined;\n }\n node._flatpickr = FlatpickrInstance(node, config || {});\n instances.push(node._flatpickr);\n }\n catch (e) {\n console.error(e);\n }\n }\n return instances.length === 1 ? instances[0] : instances;\n }\n /* istanbul ignore next */\n if (typeof HTMLElement !== \"undefined\" &&\n typeof HTMLCollection !== \"undefined\" &&\n typeof NodeList !== \"undefined\") {\n // browser env\n HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {\n return _flatpickr(this, config);\n };\n HTMLElement.prototype.flatpickr = function (config) {\n return _flatpickr([this], config);\n };\n }\n /* istanbul ignore next */\n var flatpickr = function (selector, config) {\n if (typeof selector === \"string\") {\n return _flatpickr(window.document.querySelectorAll(selector), config);\n }\n else if (selector instanceof Node) {\n return _flatpickr([selector], config);\n }\n else {\n return _flatpickr(selector, config);\n }\n };\n /* istanbul ignore next */\n flatpickr.defaultConfig = {};\n flatpickr.l10ns = {\n en: __assign({}, english),\n default: __assign({}, english),\n };\n flatpickr.localize = function (l10n) {\n flatpickr.l10ns.default = __assign(__assign({}, flatpickr.l10ns.default), l10n);\n };\n flatpickr.setDefaults = function (config) {\n flatpickr.defaultConfig = __assign(__assign({}, flatpickr.defaultConfig), config);\n };\n flatpickr.parseDate = createDateParser({});\n flatpickr.formatDate = createDateFormatter({});\n flatpickr.compareDates = compareDates;\n /* istanbul ignore next */\n if (typeof jQuery !== \"undefined\" && typeof jQuery.fn !== \"undefined\") {\n jQuery.fn.flatpickr = function (config) {\n return _flatpickr(this, config);\n };\n }\n // eslint-disable-next-line @typescript-eslint/camelcase\n Date.prototype.fp_incr = function (days) {\n return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === \"string\" ? parseInt(days, 10) : days));\n };\n if (typeof window !== \"undefined\") {\n window.flatpickr = flatpickr;\n }\n\n return flatpickr;\n\n})));\n","// `Math.sign` method implementation\n// https://tc39.github.io/ecma262/#sec-math.sign\nmodule.exports = Math.sign || function sign(x) {\n // eslint-disable-next-line no-self-compare\n return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;\n};\n","var $ = require('../internals/export');\nvar sign = require('../internals/math-sign');\n\nvar abs = Math.abs;\nvar pow = Math.pow;\n\n// `Math.cbrt` method\n// https://tc39.github.io/ecma262/#sec-math.cbrt\n$({ target: 'Math', stat: true }, {\n cbrt: function cbrt(x) {\n return sign(x = +x) * pow(abs(x), 1 / 3);\n }\n});\n","import sheetmanage from './sheetmanage';\r\nimport server from './server';\r\nimport pivotTable from './pivotTable';\r\nimport conditionformat from './conditionformat';\r\nimport luckysheetPostil from './postil';\r\nimport imageCtrl from './imageCtrl';\r\nimport dataVerificationCtrl from './dataVerificationCtrl';\r\nimport hyperlinkCtrl from './hyperlinkCtrl';\r\nimport {zoomRefreshView,zoomNumberDomBind} from './zoom';\r\nimport { createFilter, createFilterOptions, labelFilterOptionState } from './filter';\r\nimport formula from '../global/formula';\r\nimport json from '../global/json';\r\nimport cleargridelement from '../global/cleargridelement';\r\nimport { \r\n jfrefreshgrid, \r\n jfrefreshgridall, \r\n jfrefreshrange, \r\n jfrefreshgrid_rhcw, \r\n jfrefreshgrid_adRC,\r\n jfrefreshgrid_deleteCell,\r\n jfrefreshgrid_pastcut,\r\n luckysheetrefreshgrid \r\n} from '../global/refresh';\r\nimport { getSheetIndex } from '../methods/get';\r\nimport Store from '../store';\r\nimport { selectHightlightShow } from './select';\r\nimport method from '../global/method';\r\nimport {refreshMenuButtonFocus} from \"../global/api\";\r\n\r\nfunction formulaHistoryHanddler(ctr, type=\"redo\"){\r\n if(ctr==null){\r\n return;\r\n }\r\n\r\n let data = ctr.data;\r\n if(type==\"undo\"){\r\n data = ctr.curdata;\r\n }\r\n for(let s = 0; s < ctr.range.length; s++){\r\n let st_r = ctr.range[s].row[0];\r\n let ed_r = ctr.range[s].row[1];\r\n let st_c = ctr.range[s].column[0];\r\n let ed_c = ctr.range[s].column[1];\r\n\r\n for(let r = st_r;r < ed_r + 1; r++){\r\n for(let c = st_c; c < ed_c +1; c++){\r\n if(r > data.length - 1){\r\n break;\r\n }\r\n // formula.execFunctionExist.push({ \"r\": r, \"c\": c, \"i\": ctr.sheetIndex });\r\n if(data[r][c] == null || data[r][c].f==null || data[r][c].f==\"\"){\r\n formula.delFunctionGroup(r,c,ctr.sheetIndex);\r\n }\r\n else if(data[r][c] != null && data[r][c].f!=null && data[r][c].f.length>0){\r\n formula.insertUpdateFunctionGroup(r,c,ctr.sheetIndex);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst controlHistory = {\r\n redo: function (e) {\r\n if (Store.jfredo.length == 0) {\r\n return;\r\n }\r\n\r\n let ctr = Store.jfredo.pop();\r\n Store.jfundo.push(ctr);\r\n Store.clearjfundo = false;\r\n \r\n if (sheetmanage.hasSheet(ctr.sheetIndex) && Store.currentSheetIndex != ctr.sheetIndex) {\r\n sheetmanage.changeSheetExec(ctr.sheetIndex);\r\n }\r\n\r\n // formula.execFunctionExist = [];\r\n\r\n if (ctr.type == \"datachange\") {\r\n //如果有单元格为null,则对应公式应该删除\r\n formulaHistoryHanddler(ctr);\r\n \r\n let allParam = {\r\n \"cfg\": ctr.config,\r\n \"RowlChange\": ctr.RowlChange,\r\n \"cdformat\": ctr.cdformat,\r\n \"dataVerification\": ctr.dataVerification,\r\n \"dynamicArray\": ctr.dynamicArray\r\n }\r\n jfrefreshgrid(ctr.data, ctr.range, allParam);\r\n // formula.execFunctionGroup(null, null, null, null, ctr.data);//取之前的数据\r\n }\r\n else if (ctr.type == \"pasteCut\") {\r\n let s = {\r\n \"sheetIndex\": ctr.source[\"sheetIndex\"],\r\n \"data\": ctr.source[\"curData\"],\r\n \"curData\": ctr.source[\"data\"],\r\n \"config\": ctr.source[\"curConfig\"],\r\n \"curConfig\": ctr.source[\"config\"],\r\n \"cdformat\": ctr.source[\"curCdformat\"],\r\n \"curCdformat\": ctr.source[\"cdformat\"],\r\n \"dataVerification\": ctr.source[\"curDataVerification\"],\r\n \"curDataVerification\": ctr.source[\"dataVerification\"],\r\n \"range\": ctr.source[\"range\"]\r\n }\r\n let t = {\r\n \"sheetIndex\": ctr.target[\"sheetIndex\"],\r\n \"data\": ctr.target[\"curData\"],\r\n \"curData\": ctr.target[\"data\"],\r\n \"config\": ctr.target[\"curConfig\"],\r\n \"curConfig\": ctr.target[\"config\"],\r\n \"cdformat\": ctr.target[\"curCdformat\"],\r\n \"curCdformat\": ctr.target[\"cdformat\"],\r\n \"dataVerification\": ctr.target[\"curDataVerification\"],\r\n \"curDataVerification\": ctr.target[\"dataVerification\"],\r\n \"range\": ctr.target[\"range\"]\r\n }\r\n jfrefreshgrid_pastcut(s, t, ctr.RowlChange);\r\n }\r\n else if (ctr.type == \"rangechange\") {\r\n //如果有单元格为null,则对应公式应该删除\r\n formulaHistoryHanddler(ctr);\r\n \r\n jfrefreshrange(ctr.data, ctr.range, ctr.cdformat);\r\n // formula.execFunctionGroup(null, null, null, null, ctr.data);//取之前的数据\r\n }\r\n else if (ctr.type == \"resize\") {\r\n Store.config = ctr.config;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = Store.config;\r\n\r\n if(ctr.ctrlType == \"resizeR\"){\r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.config[\"rowlen\"], { \"k\": \"rowlen\" });\r\n }\r\n else if(ctr.ctrlType == \"resizeC\"){\r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.config[\"columnlen\"], { \"k\": \"columnlen\" });\r\n }\r\n\r\n let images = $.extend(true, {}, ctr.images);\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].images = images;\r\n server.saveParam(\"all\", ctr.sheetIndex, images, { \"k\": \"images\" });\r\n imageCtrl.images = images;\r\n imageCtrl.allImagesShow();\r\n\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n else if (ctr.type == \"cellRowChange\") {\r\n jfrefreshgridall(ctr.data[0].length, ctr.data.length, ctr.data, ctr.config, ctr.range, ctr.ctrlType, ctr.ctrlValue, ctr.cdformat);\r\n }\r\n else if (ctr.type == \"extend\") {\r\n jfrefreshgridall(ctr.data[0].length, ctr.data.length, ctr.data, ctr.config, ctr.range, \"dele\", ctr.ctrlValue);\r\n }\r\n else if (ctr.type == \"dele\") {\r\n let ctrlValue1 = $.extend(true, {}, ctr.ctrlValue);\r\n ctrlValue1.restore = true;\r\n jfrefreshgridall(ctr.data[0].length, ctr.data.length, ctr.data, ctr.config, ctr.range, \"extend\", ctrlValue1);\r\n }\r\n else if (ctr.type == \"addRC\") { //增加行列撤销操作\r\n let ctrlValue = $.extend(true, {}, ctr.ctrlValue);\r\n if(ctrlValue.direction == \"rightbottom\"){\r\n ctrlValue.index = ctrlValue.index + 1;\r\n }\r\n\r\n jfrefreshgrid_adRC(\r\n ctr.data, \r\n ctr.config, \r\n \"delRC\", \r\n ctrlValue, \r\n ctr.calc, \r\n ctr.filterObj, \r\n ctr.cf, \r\n ctr.af, \r\n ctr.freezen,\r\n ctr.dataVerification,\r\n ctr.hyperlink\r\n );\r\n }\r\n else if (ctr.type == \"delRC\") { //删除行列撤销操作\r\n let ctrlValue = $.extend(true, {}, ctr.ctrlValue);\r\n ctrlValue.restore = true;\r\n ctrlValue.direction = \"lefttop\";\r\n\r\n jfrefreshgrid_adRC(\r\n ctr.data, \r\n ctr.config, \r\n \"addRC\", \r\n ctrlValue, \r\n ctr.calc, \r\n ctr.filterObj, \r\n ctr.cf, \r\n ctr.af, \r\n ctr.freezen,\r\n ctr.dataVerification,\r\n ctr.hyperlink\r\n );\r\n }\r\n else if (ctr.type == \"deleteCell\") { //删除单元格撤销操作\r\n jfrefreshgrid_deleteCell(\r\n ctr.data, \r\n ctr.config, \r\n ctr.ctrl, \r\n ctr.calc, \r\n ctr.filterObj, \r\n ctr.cf,\r\n ctr.dataVerification,\r\n ctr.hyperlink\r\n );\r\n }\r\n else if (ctr.type == \"showHidRows\") { // 隐藏、显示行 撤销操作\r\n //config\r\n Store.config = ctr.config;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = ctr.config;\r\n \r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.config[\"rowhidden\"], { \"k\": \"rowhidden\" });\r\n \r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n else if (ctr.type == \"showHidCols\") { // 隐藏、显示列 撤销操作\r\n //config\r\n Store.config = ctr.config;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = ctr.config;\r\n \r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.config[\"colhidden\"], { \"k\": \"colhidden\" });\r\n \r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n else if (ctr.type == \"datachangeAll\") {\r\n formula.execFunctionGroup();\r\n jfrefreshgridall(ctr.data[0].length, ctr.data.length, ctr.data, null, ctr.range, \"datachangeAll\", ctr.ctrlValue);\r\n }\r\n else if (ctr.type == \"datachangeAll_filter_clear\") {\r\n createFilterOptions(ctr.filter_save);\r\n\r\n $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").each(function(i){\r\n let $top = $(this);\r\n let item = ctr.optiongroups[i];\r\n labelFilterOptionState($top, item.optionstate, item.rowhidden, item.caljs, false, item.st_r, item.ed_r, item.cindex, item.st_c, item.ed_c);\r\n });\r\n\r\n server.saveParam(\"fsr\", Store.currentSheetIndex, { \"filter\": ctr.optiongroups, \"filter_select\": ctr.filter_save });\r\n\r\n //config\r\n Store.config = ctr.config;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n if(Store.config[\"rowhidden\"] == null){\r\n Store.config[\"rowhidden\"] = {};\r\n }\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, Store.config[\"rowhidden\"], { \"k\": \"rowhidden\" });\r\n\r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n }\r\n else if (ctr.type == \"datachangeAll_filter\") {\r\n let $top = $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").eq(ctr[\"optionsindex\"]);\r\n let st_r = $top.data(\"str\"), \r\n ed_r = $top.data(\"edr\"), \r\n cindex = $top.data(\"cindex\"), \r\n st_c = $top.data(\"stc\"), \r\n ed_c = $top.data(\"edc\");\r\n\r\n labelFilterOptionState($top, json.hasKey(ctr.rowhidenPre), ctr.rowhidenPre, ctr.caljs, true, st_r, ed_r, cindex, st_c, ed_c);\r\n\r\n //config\r\n Store.config = ctr.config;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n if(Store.config[\"rowhidden\"] == null){\r\n Store.config[\"rowhidden\"] = {};\r\n }\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, Store.config[\"rowhidden\"], { \"k\": \"rowhidden\" });\r\n\r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n \r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n }\r\n else if (ctr.type == \"filtershow\") {\r\n $('#luckysheet-filter-selected-sheet' + ctr.sheetIndex + ', #luckysheet-filter-options-sheet' + ctr.sheetIndex).remove();\r\n \r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", ctr.sheetIndex, null, { \"k\": \"filter_select\" });\r\n }\r\n }\r\n else if(ctr.type == \"pivotTable_change\"){\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].pivotTable = ctr.pivotTable;\r\n\r\n pivotTable.getCellData(ctr.sheetIndex);\r\n pivotTable.initialPivotManage(true);\r\n\r\n pivotTable.refreshPivotTable();\r\n }\r\n else if (ctr.type == \"addSheet\") {\r\n sheetmanage.deleteSheet(ctr.index);\r\n sheetmanage.changeSheetExec(ctr.currentSheetIndex);\r\n $(\"#luckysheet-input-box\").removeAttr(\"style\");\r\n $(\"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu\").hide();\r\n }\r\n else if (ctr.type == \"copySheet\") {\r\n sheetmanage.deleteSheet(ctr.index);\r\n sheetmanage.changeSheetExec(ctr.copyindex);\r\n }\r\n else if (ctr.type == \"deleteSheet\") {\r\n let isDupName = false;\r\n\r\n for(let i = 0; i < Store.luckysheetfile.length; i++){\r\n if(Store.luckysheetfile[i].name == ctr.name){\r\n isDupName = true;\r\n }\r\n }\r\n\r\n if(!isDupName){\r\n sheetmanage.createSheetbydata(ctr, \"isrenew\");\r\n $(\"#luckysheet-input-box\").removeAttr(\"style\");\r\n $(\"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu\").hide();\r\n }\r\n }\r\n else if (ctr.type == \"sheetName\") {\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].name = ctr.oldtxt;\r\n $(\"#luckysheet-sheets-item\" + ctr.sheetIndex).find(\".luckysheet-sheets-item-name\").html(ctr.oldtxt);\r\n\r\n server.saveParam(\"all\", ctr.sheetIndex, ctr.oldtxt, { \"k\": \"name\" });\r\n }\r\n else if (ctr.type == \"sheetColor\") {\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].color = ctr.oldcolor;\r\n \r\n let luckysheetcurrentSheetitem = $(\"#luckysheet-sheets-item\" + ctr.sheetIndex);\r\n luckysheetcurrentSheetitem.find(\".luckysheet-sheets-item-color\").remove();\r\n\r\n if(ctr.oldcolor != null){\r\n luckysheetcurrentSheetitem.append('
');\r\n }\r\n\r\n server.saveParam(\"all\", ctr.sheetIndex, ctr.oldcolor, { \"k\": \"color\" });\r\n }\r\n else if (ctr.type == \"mergeChange\") {\r\n let allParam = {\r\n \"cfg\": ctr.config,\r\n }\r\n\r\n jfrefreshgrid(ctr.data, ctr.range, allParam);\r\n }\r\n else if (ctr.type == \"updateDataVerification\"){\r\n dataVerificationCtrl.ref(ctr.currentDataVerification, ctr.historyDataVerification, ctr.sheetIndex);\r\n }\r\n else if (ctr.type == \"updateDataVerificationOfCheckbox\"){\r\n dataVerificationCtrl.refOfCheckbox(ctr.currentDataVerification, ctr.historyDataVerification, ctr.sheetIndex, ctr.data, ctr.range);\r\n }\r\n else if (ctr.type == \"updateHyperlink\"){\r\n hyperlinkCtrl.ref(ctr.currentHyperlink, ctr.historyHyperlink, ctr.sheetIndex, ctr.data, ctr.range);\r\n }\r\n else if (ctr.type == \"updateCF\"){\r\n let historyRules = ctr[\"data\"][\"historyRules\"];\r\n\r\n for(let i = 0; i < historyRules.length; i++){\r\n //条件规则\r\n let sheetIndex = historyRules[i][\"sheetIndex\"];\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"] = historyRules[i][\"luckysheet_conditionformat_save\"];\r\n \r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", sheetIndex, historyRules[i][\"luckysheet_conditionformat_save\"], { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n }\r\n\r\n //刷新一次表格\r\n conditionformat.ref();\r\n }\r\n else if (ctr.type == \"updateAF\"){\r\n let historyRules = ctr[\"data\"][\"historyRules\"];\r\n\r\n let index = getSheetIndex(ctr[\"sheetIndex\"]);\r\n\r\n Store.luckysheetfile[index][\"luckysheet_alternateformat_save\"] = $.extend(true, [], historyRules);\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n else if (ctr.type == \"borderChange\"){\r\n if(ctr.config[\"borderInfo\"] == null){\r\n server.saveParam(\"cg\", ctr.sheetIndex, [], { \"k\": \"borderInfo\" });\r\n }\r\n else{\r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.config[\"borderInfo\"], { \"k\": \"borderInfo\" });\r\n }\r\n\r\n Store.config = ctr.config;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = Store.config;\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n else if (ctr.type == \"postil\"){\r\n luckysheetPostil.ref(ctr.data, ctr.rc);\r\n\r\n for(let i = 0; i < ctr.rc.length; i++){\r\n let r = ctr.rc[i].split(\"_\")[0];\r\n let c = ctr.rc[i].split(\"_\")[1];\r\n\r\n if(ctr.data[r][c] != null && ctr.data[r][c].ps != null){\r\n luckysheetPostil.buildPs(r, c, ctr.data[r][c].ps);\r\n }\r\n else{\r\n luckysheetPostil.buildPs(r, c, null);\r\n }\r\n }\r\n }\r\n else if (ctr.type == \"imageCtrl\"){\r\n imageCtrl.images = $.extend(true, {}, ctr.images);\r\n imageCtrl.allImagesShow();\r\n imageCtrl.ref();\r\n }\r\n else if (ctr.type==\"zoomChange\"){\r\n Store.zoomRatio = ctr.zoomRatio;\r\n server.saveParam(\"all\", ctr.currentSheetIndex, ctr.zoomRatio, { \"k\": \"zoomRatio\" });\r\n zoomNumberDomBind();\r\n zoomRefreshView();\r\n }\r\n \r\n cleargridelement(e);\r\n if (ctr.range) {\r\n Store.luckysheet_select_save = ctr.range;\r\n selectHightlightShow();\r\n }\r\n Store.clearjfundo = true;\r\n\r\n /* 刷新当前状态栏 */\r\n refreshMenuButtonFocus();\r\n\r\n // 撤销的时候curdata 跟 data 数据要调换一下\r\n let newCtr = {...ctr, ...{data: ctr.curdata, curdata: ctr.data}}\r\n // 钩子函数\r\n method.createHookFunction('updated', newCtr)\r\n \r\n },\r\n undo: function () {\r\n if (Store.jfundo.length == 0) {\r\n return;\r\n }\r\n\r\n let ctr = Store.jfundo.pop();\r\n Store.jfredo.push(ctr);\r\n Store.clearjfundo = false;\r\n\r\n if (sheetmanage.hasSheet(ctr.sheetIndex) && Store.currentSheetIndex != ctr.sheetIndex) {\r\n sheetmanage.changeSheetExec(ctr.sheetIndex);\r\n }\r\n\r\n if (ctr.type == \"datachange\") {\r\n formula.execFunctionGroup();\r\n\r\n let allParam = {\r\n \"cfg\": ctr.curConfig,\r\n \"RowlChange\": ctr.RowlChange,\r\n \"cdformat\": ctr.curCdformat,\r\n \"dataVerification\": ctr.curDataVerification,\r\n \"dynamicArray\": ctr.curDynamicArray\r\n }\r\n\r\n formulaHistoryHanddler(ctr, \"undo\");\r\n\r\n jfrefreshgrid(ctr.curdata, ctr.range, allParam);\r\n }\r\n else if (ctr.type == \"pasteCut\") {\r\n jfrefreshgrid_pastcut(ctr.source, ctr.target, ctr.RowlChange);\r\n }\r\n else if (ctr.type == \"rangechange\") {\r\n // formula.execFunctionGroup();\r\n formulaHistoryHanddler(ctr, \"undo\");\r\n jfrefreshrange(ctr.curdata, ctr.range, ctr.curCdformat);\r\n }\r\n else if (ctr.type == \"resize\") {\r\n Store.config = ctr.curconfig;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = Store.config;\r\n\r\n if(ctr.ctrlType == \"resizeR\"){\r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.curconfig[\"rowlen\"], { \"k\": \"rowlen\" });\r\n }\r\n else if(ctr.ctrlType == \"resizeC\"){\r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.curconfig[\"columnlen\"], { \"k\": \"columnlen\" });\r\n }\r\n\r\n let images = $.extend(true, {}, ctr.curImages);\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].images = images;\r\n server.saveParam(\"all\", ctr.sheetIndex, images, { \"k\": \"images\" });\r\n imageCtrl.images = images;\r\n imageCtrl.allImagesShow();\r\n\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n else if (ctr.type == \"cellRowChange\") {\r\n jfrefreshgridall(ctr.curdata[0].length, ctr.curdata.length, ctr.curdata, ctr.curconfig, ctr.currange, ctr.ctrlType, ctr.ctrlValue, ctr.curCdformat);\r\n }\r\n else if (ctr.type == \"extend\") {\r\n jfrefreshgridall(ctr.curdata[0].length, ctr.curdata.length, ctr.curdata, ctr.curconfig, ctr.currange, ctr.ctrlType, ctr.ctrlValue);\r\n }\r\n else if (ctr.type == \"dele\") {\r\n let ctrlValue1 = $.extend(true, {}, ctr.ctrlValue);\r\n ctrlValue1.restore = true;\r\n jfrefreshgridall(ctr.curdata[0].length, ctr.curdata.length, ctr.curdata, ctr.curconfig, ctr.currange, ctr.ctrlType, ctr.ctrlValue);\r\n }\r\n else if (ctr.type == \"addRC\") { //增加行列重做操作\r\n jfrefreshgrid_adRC(\r\n ctr.curData, \r\n ctr.curConfig, \r\n \"addRC\", \r\n ctr.ctrlValue, \r\n ctr.curCalc, \r\n ctr.curFilterObj, \r\n ctr.curCf, \r\n ctr.curAf, \r\n ctr.curFreezen,\r\n ctr.curDataVerification,\r\n ctr.curHyperlink\r\n );\r\n }\r\n else if (ctr.type == \"delRC\") { //删除行列重做操作\r\n jfrefreshgrid_adRC(\r\n ctr.curData, \r\n ctr.curConfig, \r\n \"delRC\", \r\n ctr.ctrlValue, \r\n ctr.curCalc, \r\n ctr.curFilterObj, \r\n ctr.curCf, \r\n ctr.curAf, \r\n ctr.curFreezen,\r\n ctr.curDataVerification,\r\n ctr.curHyperlink\r\n );\r\n }\r\n else if (ctr.type == \"deleteCell\") { //删除单元格重做操作\r\n jfrefreshgrid_deleteCell(\r\n ctr.curData, \r\n ctr.curConfig, \r\n ctr.ctrl, \r\n ctr.curCalc, \r\n ctr.curFilterObj, \r\n ctr.curCf,\r\n ctr.curDataVerification,\r\n ctr.curHyperlink\r\n );\r\n }\r\n else if (ctr.type == \"showHidRows\") { // 隐藏、显示行 重做操作\r\n //config\r\n Store.config = ctr.curconfig;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = ctr.curconfig;\r\n \r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.curconfig[\"rowhidden\"], { \"k\": \"rowhidden\" });\r\n \r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n else if (ctr.type == \"showHidCols\") { // 隐藏、显示列 重做操作\r\n //config\r\n Store.config = ctr.curconfig;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = ctr.curconfig;\r\n \r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.curconfig[\"colhidden\"], { \"k\": \"colhidden\" });\r\n \r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n else if (ctr.type == \"datachangeAll\") {\r\n formula.execFunctionGroup();\r\n jfrefreshgridall(ctr.curdata[0].length, ctr.curdata.length, ctr.curdata, null, ctr.currange, \"datachangeAll\", ctr.ctrlValue);\r\n }\r\n else if (ctr.type == \"datachangeAll_filter_clear\") {\r\n server.saveParam(\"fsc\", Store.currentSheetIndex, null);\r\n \r\n //config\r\n Store.config = ctr.curconfig;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, {}, { \"k\": \"rowhidden\" });\r\n\r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n \r\n\r\n $(\"#luckysheet-filter-menu .luckysheet-filter-selected-input\").hide().find(\"input\").val();\r\n $(\"#luckysheet-filter-selected span\").data(\"type\", \"0\").data(\"type\", null).text(\"无\");\r\n\r\n $('#luckysheet-filter-selected-sheet' + Store.currentSheetIndex + ', #luckysheet-filter-options-sheet' + Store.currentSheetIndex).remove();\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n }\r\n else if (ctr.type == \"datachangeAll_filter\") {\r\n let $top = $(\"#luckysheet-filter-options-sheet\" + Store.currentSheetIndex + \" .luckysheet-filter-options\").eq(ctr[\"optionsindex\"]);\r\n let st_r = $top.data(\"str\"), \r\n ed_r = $top.data(\"edr\"), \r\n cindex = $top.data(\"cindex\"), \r\n st_c = $top.data(\"stc\"), \r\n ed_c = $top.data(\"edc\");\r\n\r\n labelFilterOptionState($top, json.hasKey(ctr.rowhidden), ctr.rowhidden, ctr.caljs, true, st_r, ed_r, cindex, st_c, ed_c);\r\n\r\n //config\r\n Store.config = ctr.curconfig;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, Store.config[\"rowhidden\"], { \"k\": \"rowhidden\" });\r\n\r\n //行高、列宽 刷新 \r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n\r\n $(\"#luckysheet-filter-menu, #luckysheet-filter-submenu\").hide();\r\n }\r\n else if (ctr.type == \"filtershow\") {\r\n Store.luckysheet_select_save = [ctr.filter_save];\r\n Store.filterchage = false;\r\n createFilter();\r\n Store.filterchage = true;\r\n server.saveParam(\"all\", ctr.sheetIndex, ctr.filter_save, { \"k\": \"filter_select\" });\r\n }\r\n else if (ctr.type == \"pivotTable_change\") {\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].pivotTable = ctr.pivotTablecur;\r\n pivotTable.getCellData(ctr.sheetIndex);\r\n pivotTable.initialPivotManage(true);\r\n pivotTable.refreshPivotTable();\r\n }\r\n else if (ctr.type == \"addSheet\") {\r\n sheetmanage.createSheetbydata(ctr.sheetconfig);\r\n $(\"#luckysheet-input-box\").removeAttr(\"style\");\r\n $(\"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu\").hide();\r\n }\r\n else if (ctr.type == \"copySheet\") {\r\n sheetmanage.copySheet(ctr.copyindex);\r\n }\r\n else if (ctr.type == \"deleteSheet\") {\r\n sheetmanage.deleteSheet(ctr.index);\r\n\r\n if (ctr.order == 0) {\r\n sheetmanage.changeSheetExec(Store.luckysheetfile[0].index);\r\n }\r\n else {\r\n sheetmanage.changeSheetExec(Store.luckysheetfile[ctr.order - 1].index);\r\n }\r\n \r\n $(\"#luckysheet-input-box\").removeAttr(\"style\");\r\n $(\"#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu\").hide();\r\n }\r\n else if (ctr.type == \"sheetName\") {\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].name = ctr.txt;\r\n $(\"#luckysheet-sheets-item\" + ctr.sheetIndex).find(\".luckysheet-sheets-item-name\").html(ctr.txt);\r\n \r\n server.saveParam(\"all\", ctr.sheetIndex, ctr.txt, { \"k\": \"name\" });\r\n }\r\n else if (ctr.type == \"sheetColor\") {\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].color = ctr.color;\r\n\r\n let luckysheetcurrentSheetitem = $(\"#luckysheet-sheets-item\" + ctr.sheetIndex);\r\n luckysheetcurrentSheetitem.find(\".luckysheet-sheets-item-color\").remove();\r\n \r\n if(ctr.color != null){\r\n luckysheetcurrentSheetitem.append('
');\r\n }\r\n \r\n server.saveParam(\"all\", ctr.sheetIndex, ctr.color, { \"k\": \"color\" });\r\n }\r\n else if (ctr.type == \"mergeChange\") {\r\n let allParam = {\r\n \"cfg\": ctr.curConfig,\r\n }\r\n\r\n jfrefreshgrid(ctr.curData, ctr.range, allParam);\r\n }\r\n else if (ctr.type == \"updateDataVerification\"){\r\n dataVerificationCtrl.ref(ctr.historyDataVerification, ctr.currentDataVerification, ctr.sheetIndex);\r\n }\r\n else if (ctr.type == \"updateDataVerificationOfCheckbox\"){\r\n dataVerificationCtrl.refOfCheckbox(ctr.historyDataVerification, ctr.currentDataVerification, ctr.sheetIndex, ctr.curData, ctr.range);\r\n }\r\n else if (ctr.type == \"updateHyperlink\") {\r\n hyperlinkCtrl.ref(ctr.historyHyperlink, ctr.currentHyperlink, ctr.sheetIndex, ctr.curData, ctr.range);\r\n }\r\n else if (ctr.type == \"updateCF\"){\r\n let currentRules = ctr[\"data\"][\"currentRules\"];\r\n\r\n for(let i = 0; i < currentRules.length; i++){\r\n //条件规则\r\n let sheetIndex = currentRules[i][\"sheetIndex\"];\r\n Store.luckysheetfile[getSheetIndex(sheetIndex)][\"luckysheet_conditionformat_save\"] = currentRules[i][\"luckysheet_conditionformat_save\"];\r\n \r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", sheetIndex, currentRules[i][\"luckysheet_conditionformat_save\"], { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n }\r\n\r\n //刷新一次表格\r\n conditionformat.ref();\r\n }\r\n else if (ctr.type == \"updateAF\"){\r\n let currentRules = ctr[\"data\"][\"currentRules\"];\r\n\r\n let index = getSheetIndex(ctr[\"sheetIndex\"]);\r\n\r\n Store.luckysheetfile[index][\"luckysheet_alternateformat_save\"] = $.extend(true, [], currentRules);\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n else if (ctr.type == \"borderChange\"){\r\n server.saveParam(\"cg\", ctr.sheetIndex, ctr.curconfig[\"borderInfo\"], { \"k\": \"borderInfo\" });\r\n\r\n Store.config = ctr.curconfig;\r\n Store.luckysheetfile[getSheetIndex(ctr.sheetIndex)].config = Store.config;\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n else if (ctr.type == \"postil\"){\r\n luckysheetPostil.ref(ctr.curdata, ctr.rc);\r\n\r\n for(let i = 0; i < ctr.rc.length; i++){\r\n let r = ctr.rc[i].split(\"_\")[0];\r\n let c = ctr.rc[i].split(\"_\")[1];\r\n\r\n if(ctr.curdata[r][c] != null && ctr.curdata[r][c].ps != null){\r\n luckysheetPostil.buildPs(r, c, ctr.curdata[r][c].ps);\r\n }\r\n else{\r\n luckysheetPostil.buildPs(r, c, null);\r\n }\r\n }\r\n }\r\n else if (ctr.type == \"imageCtrl\"){\r\n imageCtrl.images = $.extend(true, {}, ctr.curImages);\r\n imageCtrl.allImagesShow();\r\n imageCtrl.ref();\r\n }\r\n else if (ctr.type==\"zoomChange\"){\r\n Store.zoomRatio = ctr.curZoomRatio;\r\n server.saveParam(\"all\", ctr.currentSheetIndex, ctr.curZoomRatio, { \"k\": \"zoomRatio\" });\r\n zoomNumberDomBind();\r\n zoomRefreshView();\r\n }\r\n\r\n if (ctr.range) {\r\n Store.luckysheet_select_save = ctr.range;\r\n selectHightlightShow();\r\n }\r\n Store.clearjfundo = true;\r\n\r\n /* 刷新当前状态栏 */\r\n refreshMenuButtonFocus();\r\n }\r\n};\r\n\r\nexport default controlHistory;","import Store from \"../store\";\r\nimport { replaceHtml, getObjType, chatatABC, luckysheetactiveCell } from \"../utils/util\";\r\nimport { getSheetIndex, getluckysheet_select_save, getluckysheetfile } from \"../methods/get\";\r\nimport locale from \"../locale/locale\";\r\nimport method from './method';\r\nimport formula from './formula';\r\nimport func_methods from \"./func_methods\";\r\nimport tooltip from \"./tooltip\";\r\nimport json from \"./json\";\r\nimport editor from \"./editor\";\r\nimport luckysheetformula from './formula';\r\nimport cleargridelement from './cleargridelement';\r\nimport { genarate, update } from './format';\r\nimport { setAccuracy,setcellvalue } from \"./setdata\";\r\nimport { orderbydata } from \"./sort\";\r\nimport { rowlenByRange } from \"./getRowlen\";\r\nimport { getdatabyselection, getcellvalue } from \"./getdata\";\r\nimport { luckysheetrefreshgrid, jfrefreshgrid, jfrefreshgrid_rhcw } from \"./refresh\";\r\nimport { luckysheetDeleteCell, luckysheetextendtable, luckysheetdeletetable } from \"./extend\";\r\nimport { isRealNull, valueIsError, isRealNum, isEditMode, hasPartMC } from \"./validate\";\r\nimport { isdatetime, diff } from \"./datecontroll\";\r\nimport { getBorderInfoCompute } from './border';\r\nimport { luckysheetDrawMain } from './draw';\r\n\r\nimport server from \"../controllers/server\";\r\nimport menuButton from '../controllers/menuButton';\r\nimport selection from \"../controllers/selection\";\r\nimport luckysheetConfigsetting from \"../controllers/luckysheetConfigsetting\";\r\nimport luckysheetFreezen from \"../controllers/freezen\";\r\nimport luckysheetsizeauto from '../controllers/resize';\r\nimport sheetmanage from '../controllers/sheetmanage';\r\nimport conditionformat from '../controllers/conditionformat';\r\nimport { luckysheet_searcharray } from \"../controllers/sheetSearch\";\r\nimport { selectHightlightShow, selectIsOverlap } from '../controllers/select';\r\nimport { sheetHTML, luckysheetdefaultstyle } from '../controllers/constant';\r\nimport { createFilterOptions } from '../controllers/filter';\r\nimport controlHistory from '../controllers/controlHistory';\r\nimport { zoomRefreshView, zoomNumberDomBind } from '../controllers/zoom';\r\nimport dataVerificationCtrl from \"../controllers/dataVerificationCtrl\";\r\nimport imageCtrl from '../controllers/imageCtrl';\r\nimport dayjs from \"dayjs\";\r\nimport {getRangetxt } from '../methods/get';\r\nimport {luckysheetupdateCell} from '../controllers/updateCell';\r\nconst IDCardReg = /^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[12])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i;\r\n\r\n/**\r\n * 获取单元格的值\r\n * @param {Number} row 单元格所在行数;从0开始的整数,0表示第一行\r\n * @param {Number} column 单元格所在列数;从0开始的整数,0表示第一列\r\n * @param {Object} options 可选参数\r\n * @param {String} options.type 单元格的值类型,可以设置为原始值\"v\"或者显示值\"m\";默认值为'v',表示获取单元格的实际值\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n */\r\nexport function getCellValue(row, column, options = {}) {\r\n if (!isRealNum(row) || !isRealNum(column)) {\r\n return tooltip.info('Arguments row or column cannot be null or undefined.', '')\r\n }\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n type = 'v',\r\n order = curSheetOrder\r\n } = { ...options };\r\n let targetSheetData = Store.luckysheetfile[order].data;\r\n let cellData = targetSheetData[row][column];\r\n let return_v;\r\n\r\n if(getObjType(cellData) == \"object\"){\r\n return_v = cellData[type];\r\n\r\n if (type == \"f\" && return_v != null) {\r\n return_v = formula.functionHTMLGenerate(return_v);\r\n }\r\n else if(type == \"f\") {\r\n return_v = cellData[\"v\"];\r\n }\r\n else if(cellData && cellData.ct && cellData.ct.fa == 'yyyy-MM-dd') {\r\n return_v = cellData.m;\r\n }\r\n }\r\n\r\n if(return_v == undefined){\r\n return_v = null;\r\n }\r\n\r\n return return_v;\r\n}\r\n\r\n/**\r\n * 设置单元格的值\r\n *\r\n * 关键点:如果设置了公式,则需要更新公式链insertUpdateFunctionGroup,如果设置了不是公式,判断之前是公式,则需要清除公式delFunctionGroup\r\n *\r\n * @param {Number} row 单元格所在行数;从0开始的整数,0表示第一行\r\n * @param {Number} column 单元格所在列数;从0开始的整数,0表示第一列\r\n * @param {Object | String | Number} value 要设置的值;可以为字符串或数字,或为符合Luckysheet单元格格式的对象\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Boolean} options.isRefresh 是否刷新界面;默认为`true`\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setCellValue(row, column, value, options = {}) {\r\n\r\n let curv = Store.flowdata[row][column];\r\n\r\n // Store old value for hook function\r\n const oldValue = JSON.stringify(curv);\r\n\r\n if (!isRealNum(row) || !isRealNum(column)) {\r\n return tooltip.info('The row or column parameter is invalid.', '');\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n isRefresh = true,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n /* cell更新前触发 */\r\n if (!method.createHookFunction(\"cellUpdateBefore\", row, column, value, isRefresh)) {\r\n /* 如果cellUpdateBefore函数返回false 则不执行后续的更新 */\r\n return;\r\n }\r\n\r\n let data = file.data;\r\n if(isRefresh) {\r\n data = $.extend(true, [], file.data);\r\n }\r\n if(data.length == 0){\r\n data = sheetmanage.buildGridData(file);\r\n }\r\n\r\n // luckysheetformula.updatecell(row, column, value);\r\n let formatList = {\r\n //ct:1, //celltype,Cell value format: text, time, etc.\r\n bg: 1,//background,#fff000\r\n ff: 1,//fontfamily,\r\n fc: 1,//fontcolor\r\n bl: 1,//Bold\r\n it: 1,//italic\r\n fs: 1,//font size\r\n cl: 1,//Cancelline, 0 Regular, 1 Cancelline\r\n un: 1,//underline, 0 Regular, 1 underlines, fonts\r\n vt: 1,//Vertical alignment, 0 middle, 1 up, 2 down\r\n ht: 1,//Horizontal alignment,0 center, 1 left, 2 right\r\n mc: 1, //Merge Cells\r\n tr: 1, //Text rotation,0: 0、1: 45 、2: -45、3 Vertical text、4: 90 、5: -90\r\n tb: 1, //Text wrap,0 truncation, 1 overflow, 2 word wrap\r\n //v: 1, //Original value\r\n //m: 1, //Display value\r\n rt:1, //text rotation angle 0-180 alignment\r\n //f: 1, //formula\r\n qp:1 //quotePrefix, show number as string\r\n }\r\n\r\n if(value == null || value.toString().length == 0){\r\n formula.delFunctionGroup(row, column);\r\n setcellvalue(row, column, data, value);\r\n }\r\n else if(value instanceof Object){\r\n let curv = {};\r\n let cell = data[row][column];\r\n if(isRealNull(cell)){\r\n cell = {};\r\n }\r\n if(value.f!=null && value.v==null){\r\n curv.f = value.f;\r\n if(value.ct!=null){\r\n curv.ct = value.ct;\r\n }\r\n data = luckysheetformula.updatecell(row, column, curv, false).data;//update formula value\r\n }\r\n else{\r\n if(value.ct!=null){\r\n curv.ct = value.ct;\r\n }\r\n if(value.f!=null){\r\n curv.f = value.f;\r\n }\r\n if(value.v!=null){\r\n curv.v = value.v;\r\n }\r\n else {\r\n curv.v = cell.v;\r\n }\r\n if(value.m!=null){\r\n curv.m = value.m;\r\n }\r\n formula.delFunctionGroup(row, column);\r\n setcellvalue(row, column, data, curv);//update text value\r\n }\r\n for(let attr in value){\r\n let v = value[attr];\r\n if(attr in formatList){\r\n menuButton.updateFormatCell(data, attr, v, row, row, column, column);//change range format\r\n }\r\n else {\r\n cell[attr] = v;\r\n }\r\n }\r\n data[row][column] = cell;\r\n }\r\n else{\r\n if(value.toString().substr(0,1)==\"=\" || value.toString().substr(0,5)==\" {\r\n // Hook function\r\n method.createHookFunction(\"cellUpdated\", row, column, JSON.parse(oldValue), Store.flowdata[row][column], isRefresh);\r\n }, 0);\r\n\r\n if(file.index == Store.currentSheetIndex && isRefresh){\r\n jfrefreshgrid(data, [{ \"row\": [row, row], \"column\": [column, column] }]);//update data, meanwhile refresh canvas and store data to history\r\n }\r\n else{\r\n file.data = data;//only update data\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success(data);\r\n }\r\n}\r\n\r\n/**\r\n * 清除指定工作表指定单元格的内容,返回清除掉的数据,不同于删除单元格的功能,不需要设定单元格移动情况\r\n * @param {Number} row 单元格所在行数;从0开始的整数,0表示第一行\r\n * @param {Number} column 单元格所在列数;从0开始的整数,0表示第一列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function clearCell(row, column, options = {}) {\r\n if (!isRealNum(row) || !isRealNum(column)) {\r\n return tooltip.info('Arguments row and column cannot be null or undefined.', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let targetSheetData = $.extend(true, [], Store.luckysheetfile[order].data);\r\n let cell = targetSheetData[row][column];\r\n\r\n if(getObjType(cell) == \"object\"){\r\n delete cell[\"m\"];\r\n delete cell[\"v\"];\r\n\r\n if(cell[\"f\"] != null){\r\n delete cell[\"f\"];\r\n formula.delFunctionGroup(row, column, order);\r\n\r\n delete cell[\"spl\"];\r\n }\r\n }\r\n else{\r\n cell = null;\r\n }\r\n\r\n // 若操作为当前sheet页,则刷新当前sheet页\r\n if (order === curSheetOrder) {\r\n jfrefreshgrid(targetSheetData, [{\r\n row: [row, row],\r\n column: [column, column]\r\n }])\r\n }\r\n else{\r\n Store.luckysheetfile[order].data = targetSheetData;\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success(cell)\r\n }\r\n}\r\n\r\n/**\r\n * 删除指定工作表指定单元格,返回删除掉的数据,同时,指定是右侧单元格左移还是下方单元格上移\r\n * @param {String} move 删除后,右侧还是下方的单元格移动。可选值为 'left'、'up'\r\n * @param {Number} row 单元格所在行数;从0开始的整数,0表示第一行\r\n * @param {Number} column 单元格所在列数;从0开始的整数,0表示第一列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteCell(move, row, column, options = {}) {\r\n let moveTypes = ['left', 'up'];\r\n if (!move || moveTypes.indexOf(move) < 0) {\r\n return tooltip.info('Arguments move cannot be null or undefined and its value must be \\'left\\' or \\'up\\'', '')\r\n }\r\n\r\n if (!isRealNum(row) || !isRealNum(column)) {\r\n return tooltip.info('Arguments row and column cannot be null or undefined.', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let moveType = 'move' + move.replace(move[0], move[0].toUpperCase()); // left-moveLeft; up-moveUp\r\n\r\n let sheetIndex;\r\n if(order){\r\n if(Store.luckysheetfile[order]){\r\n sheetIndex = Store.luckysheetfile[order].index;\r\n }\r\n }\r\n\r\n luckysheetDeleteCell(moveType, row, row, column, column, sheetIndex);\r\n\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n}\r\n\r\n/**\r\n * 设置某个单元格的属性,如果要设置单元格的值或者同时设置多个单元格属性,推荐使用setCellValue\r\n * @param {Number} row 单元格所在行数;从0开始的整数,0表示第一行\r\n * @param {Number} column 单元格所在列数;从0开始的整数,0表示第一列\r\n * @param {String} attr\r\n * @param {Number | String | Object} value 具体的设置值,一个属性会对应多个值,参考 单元格属性表的值示例,特殊情况:如果属性类型attr是单元格格式ct,则设置值value应提供ct.fa,比如设置A1单元格的格式为百分比格式:luckysheet.setCellFormat(0, 0, \"ct\", \"0.00%\")\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数, callback参数为改变后的cell对象\r\n */\r\nexport function setCellFormat(row, column, attr, value, options = {}) {\r\n if (!isRealNum(row) || !isRealNum(column)) {\r\n return tooltip.info('Arguments row or column cannot be null or undefined.', '')\r\n }\r\n\r\n if (!attr) {\r\n return tooltip.info('Arguments attr cannot be null or undefined.', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curSheetOrder,\r\n success\r\n } = { ...options };\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let targetSheetData = $.extend(true, [], file.data);\r\n if(targetSheetData.length == 0){\r\n targetSheetData = sheetmanage.buildGridData(file);\r\n }\r\n\r\n let cellData = targetSheetData[row][column] || {};\r\n let cfg = $.extend(true, {}, file.config);\r\n\r\n // 特殊格式\r\n if (attr == 'ct' && (!value || !value.hasOwnProperty('fa') || !value.hasOwnProperty('t'))) {\r\n return new TypeError('While set attribute \\'ct\\' to cell, the value must have property \\'fa\\' and \\'t\\'')\r\n }\r\n\r\n if (attr == 'bd') {\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n let borderInfo = {\r\n rangeType: \"range\",\r\n borderType: \"border-all\",\r\n color: \"#000\",\r\n style: \"1\",\r\n range: [{\r\n column: [column, column],\r\n row: [row, row]\r\n }],\r\n ...value,\r\n }\r\n\r\n cfg[\"borderInfo\"].push(borderInfo);\r\n } else {\r\n cellData[attr] = value;\r\n }\r\n\r\n targetSheetData[row][column] = cellData;\r\n\r\n // refresh\r\n if(file.index == Store.currentSheetIndex){\r\n file.config = cfg;\r\n Store.config = cfg;\r\n jfrefreshgrid(targetSheetData, [{ \"row\": [row, row], \"column\": [column, column] }]);\r\n }\r\n else {\r\n file.config = cfg;\r\n file.data = targetSheetData;\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success(cellData);\r\n }\r\n}\r\n\r\n/**\r\n * 查找一个工作表中的指定内容,返回查找到的内容组成的单元格一位数组,数据格式同celldata\r\n * @param {String} content 要查找的内容 可以为正则表达式(不包含前后'/')\r\n * @param {Object} options 可选参数\r\n * @param {Boolean} options.isRegularExpression 是否正则表达式匹配;默认为 false. 注意:正则中的规则需要转义,如\\S需要写成 \\\\S\r\n * @param {Boolean} options.isWholeWord 是否整词匹配;默认为 false\r\n * @param {Boolean} options.isCaseSensitive 是否区分大小写匹配;默认为 false\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {String} options.type 单元格属性;默认值为m\r\n */\r\nexport function find(content, options = {}) {\r\n if (!content && content != 0) {\r\n return tooltip.info('Search content cannot be null or empty', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n isRegularExpression = false,\r\n isWholeWord = false,\r\n isCaseSensitive = false,\r\n order = curSheetOrder,\r\n type = \"m\"\r\n } = { ...options };\r\n let targetSheetData = Store.luckysheetfile[order].data;\r\n\r\n let result = [];\r\n for (let i = 0; i < targetSheetData.length; i++) {\r\n const rowArr = targetSheetData[i];\r\n\r\n for (let j = 0; j < rowArr.length; j++) {\r\n const cell = rowArr[j];\r\n\r\n if (!cell) {\r\n continue;\r\n }\r\n\r\n // 添加cell的row, column属性\r\n // replace方法中的setCellValue中需要使用该属性\r\n cell.row = i;\r\n cell.column = j;\r\n\r\n if (isWholeWord) {\r\n if (isCaseSensitive) {\r\n if (content.toString() == cell[type]) {\r\n result.push(cell)\r\n }\r\n } else {\r\n if (cell[type] && content.toString().toLowerCase() == cell[type].toLowerCase()) {\r\n result.push(cell)\r\n }\r\n }\r\n } else if (isRegularExpression) {\r\n let reg;\r\n if (isCaseSensitive) {\r\n reg = new RegExp(func_methods.getRegExpStr(content), 'g')\r\n } else {\r\n reg = new RegExp(func_methods.getRegExpStr(content), 'ig')\r\n }\r\n if (reg.test(cell[type])) {\r\n result.push(cell)\r\n }\r\n } else if (isCaseSensitive) {\r\n let reg = new RegExp(func_methods.getRegExpStr(content), 'g');\r\n if (reg.test(cell[type])) {\r\n result.push(cell);\r\n }\r\n } else {\r\n let reg = new RegExp(func_methods.getRegExpStr(content), 'ig');\r\n if (reg.test(cell[type])) {\r\n result.push(cell);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * 查找一个工作表中的指定内容并替换成新的内容,返回替换后的内容组成的单元格一位数组,数据格式同celldata。\r\n * @param {String} content 要查找的内容\r\n * @param {String} replaceContent 要替换的内容\r\n * @param {Object} options 可选参数\r\n * @param {Boolean} options.isRegularExpression 是否正则表达式匹配;默认为 false\r\n * @param {Boolean} options.isWholeWord 是否整词匹配;默认为 false\r\n * @param {Boolean} options.isCaseSensitive 是否区分大小写匹配;默认为 false\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数, callback参数为替换后的cell集合\r\n */\r\nexport function replace(content, replaceContent, options = {}) {\r\n let matchCells = find(content, options)\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curSheetOrder,\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n let sheetData = $.extend(true, [], file.data);\r\n\r\n matchCells.forEach(cell => {\r\n cell.m = replaceContent;\r\n setCellValue(cell.row, cell.column, replaceContent, {order: order, isRefresh: false});\r\n })\r\n\r\n let fileData = $.extend(true, [], file.data);\r\n file.data.length = 0;\r\n file.data.push(...sheetData);\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n jfrefreshgrid(fileData, undefined, undefined, true, false);\r\n }\r\n\r\n luckysheetrefreshgrid();\r\n\r\n if (options.success && typeof options.success === 'function') {\r\n options.success(matchCells)\r\n }\r\n return matchCells;\r\n}\r\n\r\n\r\n/**\r\n * 手动触发退出编辑模式\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function exitEditMode(options = {}){\r\n if(parseInt($(\"#luckysheet-input-box\").css(\"top\")) > 0){\r\n\r\n\r\n if ($(\"#luckysheet-formula-search-c\").is(\":visible\") && formula.searchFunctionCell != null) {\r\n formula.searchFunctionEnter($(\"#luckysheet-formula-search-c\").find(\".luckysheet-formula-search-item-active\"));\r\n }\r\n else {\r\n formula.updatecell(Store.luckysheetCellUpdate[0], Store.luckysheetCellUpdate[1]);\r\n Store.luckysheet_select_save = [{\r\n \"row\": [Store.luckysheetCellUpdate[0], Store.luckysheetCellUpdate[0]],\r\n \"column\": [Store.luckysheetCellUpdate[1], Store.luckysheetCellUpdate[1]],\r\n \"row_focus\": Store.luckysheetCellUpdate[0],\r\n \"column_focus\": Store.luckysheetCellUpdate[1]\r\n }];\r\n }\r\n\r\n //若有参数弹出框,隐藏\r\n if($(\"#luckysheet-search-formula-parm\").is(\":visible\")){\r\n $(\"#luckysheet-search-formula-parm\").hide();\r\n }\r\n //若有参数选取范围弹出框,隐藏\r\n if($(\"#luckysheet-search-formula-parm-select\").is(\":visible\")){\r\n $(\"#luckysheet-search-formula-parm-select\").hide();\r\n }\r\n\r\n }\r\n\r\n if (options.success && typeof options.success === 'function') {\r\n options.success();\r\n }\r\n}\r\n\r\n/**\r\n * 手动触发进入编辑模式\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function enterEditMode(options = {}){\r\n\r\n if($(\"#luckysheet-conditionformat-dialog\").is(\":visible\")){\r\n return;\r\n }\r\n else if ($(\"#luckysheet-cell-selected\").is(\":visible\")) {\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n\r\n let row_index = last[\"row_focus\"], col_index = last[\"column_focus\"];\r\n\r\n luckysheetupdateCell(row_index, col_index, Store.flowdata);\r\n }\r\n\r\n if (options.success && typeof options.success === 'function') {\r\n options.success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 冻结首行\r\n * 若设置冻结的sheet不是当前sheet页,只设置参数不渲染\r\n * @param {Number | String} order 工作表索引\r\n */\r\nexport function frozenFirstRow(order) {\r\n // store frozen\r\n luckysheetFreezen.saveFrozen(\"freezenRow\", order);\r\n\r\n // 冻结为当前sheet页\r\n if (!order || order == getSheetIndex(Store.currentSheetIndex)) {\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [\r\n Store.visibledatarow[row_st],\r\n row_st + 1,\r\n scrollTop,\r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),\r\n top\r\n ];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n if (luckysheetFreezen.freezenverticaldata != null) {\r\n luckysheetFreezen.cancelFreezenVertical();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n}\r\n\r\n/**\r\n * 冻结首列\r\n * 若设置冻结的sheet不是当前sheet页,只设置参数不渲染\r\n * @param {Number | String} order 工作表索引\r\n */\r\nexport function frozenFirstColumn(order) {\r\n // store frozen\r\n luckysheetFreezen.saveFrozen(\"freezenColumn\", order);\r\n\r\n // 冻结为当前sheet页\r\n if (!order || order == getSheetIndex(Store.currentSheetIndex)) {\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [\r\n Store.visibledatacolumn[col_st],\r\n col_st + 1,\r\n scrollLeft,\r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),\r\n left\r\n ];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n if (luckysheetFreezen.freezenhorizontaldata != null) {\r\n luckysheetFreezen.cancelFreezenHorizontal();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n}\r\n\r\n/**\r\n * 冻结行选区\r\n * @param {Object} range 行选区范围的focus单元格的行列值构成的对象;格式为{ row_focus:0, column_focus:0 }\r\n * @param {Number | String} order 工作表索引\r\n */\r\nexport function frozenRowRange(range, order) {\r\n const locale_frozen = locale().freezen;\r\n\r\n if (!range || (!range.hasOwnProperty('row_focus') && !formula.iscelldata(range))) {\r\n if(isEditMode()){\r\n alert(locale_frozen.noSeletionError);\r\n } else{\r\n tooltip.info(locale_frozen.noSeletionError, \"\");\r\n }\r\n return\r\n }\r\n\r\n if (typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n range = {\r\n row_focus: range.row[0],\r\n column_focus: range.column[0]\r\n }\r\n }\r\n // store frozen\r\n luckysheetFreezen.saveFrozen(\"freezenRowRange\", order, range);\r\n\r\n if (!order || order == getSheetIndex(Store.currentSheetIndex)) {\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n\r\n let row_focus = range.row_focus;\r\n if(row_focus > row_st){\r\n row_st = row_focus;\r\n }\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [\r\n Store.visibledatarow[row_st],\r\n row_st + 1,\r\n scrollTop,\r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),\r\n top\r\n ];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n if (luckysheetFreezen.freezenverticaldata != null) {\r\n luckysheetFreezen.cancelFreezenVertical();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n}\r\n\r\n/**\r\n * 冻结列选区\r\n * @param {Object} range 列选区范围的focus单元格的行列值构成的对象;格式为{ row_focus:0, column_focus:0 }\r\n * @param {Number | String} order 工作表索引\r\n */\r\nexport function frozenColumnRange(range, order) {\r\n const locale_frozen = locale().freezen;\r\n let isStringRange = typeof range === 'string' && formula.iscelldata(range);\r\n\r\n if (!range || (!range.hasOwnProperty('column_focus') && !isStringRange)) {\r\n if(isEditMode()){\r\n alert(locale_frozen.noSeletionError);\r\n } else{\r\n tooltip.info(locale_frozen.noSeletionError, \"\");\r\n }\r\n return\r\n }\r\n\r\n if (isStringRange) {\r\n range = formula.getcellrange(range)\r\n range = {\r\n row_focus: range.row[0],\r\n column_focus: range.column[0]\r\n }\r\n }\r\n // store frozen\r\n luckysheetFreezen.saveFrozen(\"freezenColumnRange\", order, range);\r\n\r\n if (!order || order == getSheetIndex(Store.currentSheetIndex)) {\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n\r\n let column_focus = range.column_focus;\r\n if(column_focus > col_st){\r\n col_st = column_focus;\r\n }\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [\r\n Store.visibledatacolumn[col_st],\r\n col_st + 1,\r\n scrollLeft,\r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),\r\n left\r\n ];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n if (luckysheetFreezen.freezenhorizontaldata != null) {\r\n luckysheetFreezen.cancelFreezenHorizontal();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n}\r\n\r\n/**\r\n * 取消冻结\r\n * @param {Number | String} order\r\n */\r\nexport function cancelFrozen(order) {\r\n luckysheetFreezen.saveFrozen(\"freezenCancel\", order);\r\n\r\n // 取消当前sheet冻结时,刷新canvas\r\n if (!order || order == getSheetIndex(Store.currentSheetIndex)) {\r\n if (luckysheetFreezen.freezenverticaldata != null) {\r\n luckysheetFreezen.cancelFreezenVertical();\r\n }\r\n if (luckysheetFreezen.freezenhorizontaldata != null) {\r\n luckysheetFreezen.cancelFreezenHorizontal();\r\n }\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n}\r\n\r\n/**\r\n * 冻结行操作。特别注意,只有在isRange设置为true的时候,才需要设置setting中的range,且与一般的range格式不同。\r\n * @param {Boolean} isRange 是否冻结行到选区 true-冻结行到选区 false-冻结首行\r\n * @param {Object} options 可选参数\r\n * @param {Object} options.range isRange为true的时候设置,开启冻结的单元格位置,格式为{ row_focus:0, column_focus:0 },意为当前激活的单元格的行数和列数;默认从当前选区最后的一个选区中取得\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setHorizontalFrozen(isRange, options = {}) {\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n range,\r\n order = curSheetOrder,\r\n success\r\n } = { ...options };\r\n\r\n // 若已存在冻结,取消之前的冻结效果\r\n cancelFrozen(order);\r\n\r\n if (!isRange) {\r\n frozenFirstRow(order)\r\n } else { // 选区行冻结\r\n frozenRowRange(range, order);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n}\r\n\r\n/**\r\n * 冻结列操作。特别注意,只有在isRange设置为true的时候,才需要设置setting中的range,且与一般的range格式不同。\r\n * @param {Boolean} isRange 是否冻结列到选区 true-冻结列到选区 false-冻结首列\r\n * @param {Object} options 可选参数\r\n * @param {Object} options.range isRange为true的时候设置,开启冻结的单元格位置,格式为{ row_focus:0, column_focus:0 },意为当前激活的单元格的行数和列数;默认从当前选区最后的一个选区中取得\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setVerticalFrozen(isRange, options = {}) {\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n range,\r\n order = curSheetOrder,\r\n success\r\n } = { ...options };\r\n\r\n // 若已存在冻结,取消之前的冻结效果\r\n cancelFrozen(order);\r\n\r\n if (!isRange) {\r\n frozenFirstColumn(order);\r\n } else {\r\n frozenColumnRange(range, order);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n}\r\n\r\n/**\r\n * 冻结行列操作。特别注意,只有在isRange设置为true的时候,才需要设置setting中的range,且与一般的range格式不同。\r\n * @param {Boolean} isRange 是否冻结行列到选区 true-冻结行列到选区 false-冻结首行列\r\n * @param {Object} options 可选参数\r\n * @param {Object} options.range isRange为true的时候设置,开启冻结的单元格位置,格式为{ row_focus:0, column_focus:0 },意为当前激活的单元格的行数和列数;默认从当前选区最后的一个选区中取得\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setBothFrozen(isRange, options = {}) {\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n range,\r\n order = curSheetOrder,\r\n success\r\n } = { ...options };\r\n\r\n let isCurrentSheet = !order || order == getSheetIndex(Store.currentSheetIndex);\r\n const locale_frozen = locale().freezen;\r\n\r\n // 若已存在冻结,取消之前的冻结效果\r\n cancelFrozen(order);\r\n\r\n // 冻结首行列\r\n if (!isRange) {\r\n // store frozen\r\n luckysheetFreezen.saveFrozen(\"freezenRC\", order)\r\n\r\n if (isCurrentSheet) {\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [\r\n Store.visibledatarow[row_st],\r\n row_st + 1,\r\n scrollTop,\r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),\r\n top\r\n ];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [\r\n Store.visibledatacolumn[col_st],\r\n col_st + 1,\r\n scrollLeft,\r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),\r\n left\r\n ];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n } else { // 冻结行列到选区\r\n // store frozen\r\n luckysheetFreezen.saveFrozen(\"freezenRCRange\", order, range)\r\n\r\n let isStringRange = typeof range === 'string' && formula.iscelldata(range);\r\n if (isCurrentSheet) {\r\n if ((!range || !(range.hasOwnProperty('column_focus') && range.hasOwnProperty('row_focus'))) && !isStringRange) {\r\n if(isEditMode()){\r\n alert(locale_frozen.noSeletionError);\r\n } else{\r\n tooltip.info(locale_frozen.noSeletionError, \"\");\r\n }\r\n return\r\n }\r\n\r\n if (isStringRange) {\r\n range = formula.getcellrange(range)\r\n range = {\r\n row_focus: range.row[0],\r\n column_focus: range.column[0]\r\n }\r\n }\r\n\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n\r\n let row_focus = range.row_focus;\r\n\r\n if(row_focus > row_st){\r\n row_st = row_focus;\r\n }\r\n\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [\r\n Store.visibledatarow[row_st],\r\n row_st + 1,\r\n scrollTop,\r\n luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),\r\n top\r\n ];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n\r\n let column_focus = range.column_focus;\r\n\r\n if(column_focus > col_st){\r\n col_st = column_focus;\r\n }\r\n\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [\r\n Store.visibledatacolumn[col_st],\r\n col_st + 1,\r\n scrollLeft,\r\n luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),\r\n left\r\n ];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 在第index行或列的位置,插入number行或列\r\n * @param {String} type 插入行或列 row-行 column-列\r\n * @param {Number} index 在第几行插入空白行,从0开始\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.number 插入的空白行数;默认为 1\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function insertRowOrColumn(type, index = 0, options = {}) {\r\n if(!isRealNum(index)){\r\n return tooltip.info('The index parameter is invalid.', '');\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n number = 1,\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let _locale = locale();\r\n let locale_info = _locale.info;\r\n if (!isRealNum(number)) {\r\n if(isEditMode()){\r\n alert(locale_info.tipInputNumber);\r\n } else{\r\n tooltip.info(locale_info.tipInputNumber, \"\");\r\n }\r\n return;\r\n }\r\n\r\n number = parseInt(number);\r\n if (number < 1 || number > 100) {\r\n if(isEditMode()){\r\n alert(locale_info.tipInputNumberLimit);\r\n } else{\r\n tooltip.info(locale_info.tipInputNumberLimit, \"\");\r\n }\r\n return;\r\n }\r\n\r\n // 默认在行上方增加行,列左侧增加列\r\n let sheetIndex;\r\n if(order){\r\n if(Store.luckysheetfile[order]){\r\n sheetIndex = Store.luckysheetfile[order].index;\r\n }\r\n }\r\n\r\n luckysheetextendtable(type, index, number, \"lefttop\", sheetIndex);\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 在第row行的位置,插入number行空白行\r\n * @param {Number} row 在第几行插入空白行,从0开始\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.number 插入的空白行数;默认为 1\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function insertRow(row = 0, options = {}) {\r\n insertRowOrColumn('row', row, options)\r\n}\r\n\r\n/**\r\n * 在第column列的位置,插入number列空白列\r\n * @param {Number} column 在第几列插入空白列,从0开始\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.number 插入的空白列数;默认为 1\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function insertColumn(column = 0, options = {}) {\r\n insertRowOrColumn('column', column, options)\r\n}\r\n\r\n/**\r\n * 删除指定的行或列。删除行列之后,行列的序号并不会变化,下面的行(右侧的列)会补充到上(左)面,注意观察数据是否被正确删除即可。\r\n * @param {String} type 删除行或列 row-行 column-列\r\n * @param {Number} startIndex 要删除的起始行或列\r\n * @param {Number} endIndex 要删除的结束行或列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteRowOrColumn(type, startIndex, endIndex, options = {}) {\r\n if (!isRealNum(startIndex) || !isRealNum(endIndex)) {\r\n return tooltip.info('Please enter the index for deleting rows or columns correctly.', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n\r\n let sheetIndex;\r\n if(order){\r\n if(Store.luckysheetfile[order]){\r\n sheetIndex = Store.luckysheetfile[order].index;\r\n }\r\n }\r\n luckysheetdeletetable(type, startIndex, endIndex, sheetIndex);\r\n\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n}\r\n\r\n/**\r\n * 删除指定的行。\r\n * @param {Number} rowStart 要删除的起始行\r\n * @param {Number} rowEnd 要删除的结束行\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteRow(rowStart, rowEnd, options = {}) {\r\n deleteRowOrColumn('row', rowStart, rowEnd, options)\r\n}\r\n\r\n/**\r\n * 删除指定的列。\r\n * @param {Number} columnStart 要删除的起始列\r\n * @param {Number} columnEnd 要删除的结束列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteColumn(columnStart, columnEnd, options = {}) {\r\n deleteRowOrColumn('column', columnStart, columnEnd, options)\r\n}\r\n\r\n/**\r\n * 隐藏行或列\r\n * @param {String} type 隐藏行或列 row-隐藏行 column-隐藏列\r\n * @param {Number} startIndex 起始行或列\r\n * @param {Number} endIndex 结束行或列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function hideRowOrColumn(type, startIndex, endIndex, options = {}) {\r\n if (!isRealNum(startIndex) || !isRealNum(endIndex)) {\r\n return tooltip.info('Please enter the index for deleting rows or columns correctly.', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n let cfgKey = type === 'row' ? 'rowhidden': 'colhidden';\r\n let cfg = $.extend(true, {}, file.config);\r\n if(cfg[cfgKey] == null) {\r\n cfg[cfgKey] = {};\r\n }\r\n\r\n for (let i = startIndex; i <= endIndex; i++) {\r\n cfg[cfgKey][i] = 0;\r\n }\r\n\r\n //保存撤销\r\n if(Store.clearjfundo){\r\n let redo = {};\r\n redo[\"type\"] = type === 'row' ? 'showHidRows' : 'showHidCols';\r\n redo[\"sheetIndex\"] = file.index;\r\n redo[\"config\"] = $.extend(true, {}, file.config);\r\n redo[\"curconfig\"] = cfg;\r\n\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n Store.luckysheetfile[order].config = cfg;\r\n server.saveParam(\"cg\", file.index, cfg[cfgKey], { \"k\": cfgKey });\r\n\r\n // 若操作sheet为当前sheet页,行高、列宽 刷新\r\n if (order == curSheetOrder) {\r\n //config\r\n Store.config = cfg;\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 显示隐藏的行或列\r\n * @param {String} type 显示行或列 row-显示行 column-显示列\r\n * @param {Number} startIndex 起始行或列\r\n * @param {Number} endIndex 结束行或列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function showRowOrColumn(type, startIndex, endIndex, options = {}) {\r\n if (!isRealNum(startIndex) || !isRealNum(endIndex)) {\r\n return tooltip.info('Please enter the index for deleting rows or columns correctly.', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n let cfgKey = type === 'row' ? 'rowhidden': 'colhidden';\r\n let cfg = $.extend(true, {}, file.config);\r\n if(cfg[cfgKey] == null) {\r\n return;\r\n }\r\n\r\n for (let i = startIndex; i <= endIndex; i++) {\r\n delete cfg[cfgKey][i];\r\n }\r\n\r\n //保存撤销\r\n if(Store.clearjfundo){\r\n let redo = {};\r\n redo[\"type\"] = type === 'row' ? 'showHidRows' : 'showHidCols';\r\n redo[\"sheetIndex\"] = file.index;\r\n redo[\"config\"] = $.extend(true, {}, file.config);\r\n redo[\"curconfig\"] = cfg;\r\n\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n //config\r\n Store.luckysheetfile[order].config = Store.config;\r\n\r\n server.saveParam(\"cg\", file.index, cfg[cfgKey], { \"k\": cfgKey });\r\n\r\n // 若操作sheet为当前sheet页,行高、列宽 刷新\r\n if (order === curSheetOrder) {\r\n Store.config = cfg;\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 隐藏行\r\n * @param {Number} startIndex 起始行\r\n * @param {Number} endIndex 结束行\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function hideRow(startIndex, endIndex, options = {}) {\r\n hideRowOrColumn('row', startIndex, endIndex, options);\r\n}\r\n\r\n/**\r\n * 显示行\r\n * @param {Number} startIndex 起始行\r\n * @param {Number} endIndex 结束行\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function showRow(startIndex, endIndex, options = {}) {\r\n showRowOrColumn('row', startIndex, endIndex, options);\r\n}\r\n\r\n/**\r\n * 隐藏列\r\n * @param {Number} startIndex 起始列\r\n * @param {Number} endIndex 结束列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function hideColumn(startIndex, endIndex, options = {}) {\r\n hideRowOrColumn('column', startIndex, endIndex, options);\r\n}\r\n\r\n/**\r\n * 显示列\r\n * @param {Number} startIndex 起始列\r\n * @param {Number} endIndex 结束列\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function showColumn(startIndex, endIndex, options = {}) {\r\n showRowOrColumn('column', startIndex, endIndex, options);\r\n}\r\n\r\n\r\n/**\r\n * 设置指定行的高度\r\n * @param {Object} rowInfo 行数和高度对应关系\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRowHeight(rowInfo, options = {}) {\r\n if(getObjType(rowInfo) != 'object'){\r\n return tooltip.info(\"The rowInfo parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let cfg = $.extend(true, {}, file.config);\r\n if(cfg['rowlen'] == null){\r\n cfg['rowlen'] = {};\r\n }\r\n\r\n for(let r in rowInfo){\r\n if(parseInt(r) >= 0){\r\n let len = rowInfo[r];\r\n\r\n if(Number(len) >= 0){\r\n cfg['rowlen'][parseInt(r)] = Number(len);\r\n }\r\n }\r\n }\r\n\r\n file.config = cfg;\r\n\r\n server.saveParam(\"cg\", file.index, cfg[\"rowlen\"], { \"k\": \"rowlen\" });\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n Store.config = cfg;\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 设置指定列的宽度\r\n * @param {Object} columnInfo 行数和高度对应关系\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setColumnWidth(columnInfo, options = {}) {\r\n if(getObjType(columnInfo) != 'object'){\r\n return tooltip.info(\"The columnInfo parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let cfg = $.extend(true, {}, file.config);\r\n if(cfg['columnlen'] == null){\r\n cfg['columnlen'] = {};\r\n }\r\n\r\n for(let c in columnInfo){\r\n if(parseInt(c) >= 0){\r\n let len = columnInfo[c];\r\n\r\n if(Number(len) >= 0){\r\n cfg['columnlen'][parseInt(c)] = Number(len);\r\n }\r\n }\r\n }\r\n\r\n file.config = cfg;\r\n\r\n server.saveParam(\"cg\", file.index, cfg[\"columnlen\"], { \"k\": \"columnlen\" });\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n Store.config = cfg;\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 获取指定工作表指定行的高度,得到行号和高度对应关系的对象\r\n * @param {Array} rowInfo 行号下标组成的数组;行号下标从0开始;\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function getRowHeight(rowInfo, options = {}) {\r\n if(getObjType(rowInfo) != 'array' || rowInfo.length == 0){\r\n return tooltip.info(\"The rowInfo parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let cfg = $.extend(true, {}, file.config);\r\n let rowlen = cfg[\"rowlen\"] || {};\r\n\r\n let rowlenObj = {};\r\n\r\n rowInfo.forEach((item) => {\r\n if(parseInt(item) >= 0){\r\n let size = rowlen[parseInt(item)] || Store.defaultrowlen;\r\n rowlenObj[parseInt(item)] = size;\r\n }\r\n })\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n }, 1)\r\n\r\n return rowlenObj;\r\n}\r\n\r\n\r\n/**\r\n * 获取指定工作表指定列的宽度,得到列号和宽度对应关系的对象\r\n * @param {Array} columnInfo 行号下标组成的数组;行号下标从0开始;\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function getColumnWidth(columnInfo, options = {}) {\r\n if(getObjType(columnInfo) != 'array' || columnInfo.length == 0){\r\n return tooltip.info(\"The columnInfo parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let cfg = $.extend(true, {}, file.config);\r\n let columnlen = cfg[\"columnlen\"] || {};\r\n\r\n let columnlenObj = {};\r\n\r\n columnInfo.forEach((item) => {\r\n if(parseInt(item) >= 0){\r\n let size = columnlen[parseInt(item)] || Store.defaultcollen;\r\n columnlenObj[parseInt(item)] = size;\r\n }\r\n })\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n }, 1)\r\n\r\n return columnlenObj;\r\n}\r\n\r\n\r\n/**\r\n * 获取工作表的默认行高\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function getDefaultRowHeight(options = {}) {\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n }, 1)\r\n\r\n return Store.luckysheetfile[order].defaultRowHeight;\r\n}\r\n\r\n\r\n/**\r\n * 获取工作表的默认列宽\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function getDefaultColWidth(options = {}) {\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n }, 1)\r\n\r\n return Store.luckysheetfile[order].defaultColWidth;\r\n}\r\n\r\n\r\n/**\r\n * 返回当前选区对象的数组,可能存在多个选区。\r\n * 每个选区的格式为row/column信息组成的对象{row:[0,1],column:[0,1]}\r\n * @returns {Array}\r\n */\r\nexport function getRange() {\r\n let rangeArr = Store.luckysheet_select_save;\r\n let result = [];\r\n\r\n for (let i = 0; i < rangeArr.length; i++) {\r\n let rangeItem = rangeArr[i];\r\n let temp = {\r\n row: rangeItem.row,\r\n column: rangeItem.column\r\n }\r\n result.push(temp)\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * 返回表示指定区域内所有单元格位置的数组,区别getRange方法,该方法以cell单元格(而非某块连续的区域)为单位来组织选区的数据\r\n * @param {Array} range 可选参数,默认为当前选中区域\r\n * @returns {Array} 对象数组\r\n */\r\nexport function getRangeWithFlatten(range){\r\n range = range || getRange();\r\n\r\n let result = [];\r\n\r\n range.forEach(ele=>{\r\n // 这个data可能是个范围或者是单个cell\r\n let rs = ele.row;\r\n let cs = ele.column;\r\n for(let r = rs[0]; r <= rs[1]; r++){\r\n for(let c = cs[0]; c <= cs[1]; c++){\r\n // r c 当前的r和当前的c\r\n result.push({r,c});\r\n }\r\n }\r\n })\r\n return result;\r\n}\r\n\r\n/**\r\n * 返回表示指定区域内所有单元格内容的对象数组\r\n * @param {Array} range 可选参数,默认为当前选中区域扁平化后的对象,结构形如[{r:0,c:0},{r:0,c:1}...]\r\n * @returns {Array} 对象数组\r\n */\r\nexport function getRangeValuesWithFlatte(range){\r\n range = range || getRangeWithFlatten();\r\n\r\n let values = [];\r\n\r\n // 获取到的这个数据不是最新的数据\r\n range.forEach(item=> {\r\n values.push(Store.flowdata[item.r][item.c]);\r\n });\r\n return values;\r\n}\r\n\r\n\r\n/**\r\n * 返回对应当前选区的坐标字符串数组,可能存在多个选区。\r\n * 每个选区可能是单个单元格(如 A1)或多个单元格组成的矩形区域(如 D9:E12)\r\n * @returns {Array}\r\n */\r\nexport function getRangeAxis() {\r\n let result = [];\r\n let rangeArr = Store.luckysheet_select_save;\r\n let sheetIndex = Store.currentSheetIndex;\r\n\r\n rangeArr.forEach(ele=>{\r\n let axisText = getRangetxt(sheetIndex, {column:ele.column,row:ele.row});\r\n result.push(axisText);\r\n })\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * 返回指定工作表指定范围的单元格二维数组数据,每个单元格为一个对象\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n */\r\nexport function getRangeValue(options = {}) {\r\n let curOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n range,\r\n order = curOrder\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if (!range || typeof range === 'object') {\r\n return getdatabyselection(range, file.index);\r\n } else if (typeof range === 'string') {\r\n if (formula.iscelldata(range)) {\r\n return getdatabyselection(formula.getcellrange(range), file.index)\r\n } else {\r\n tooltip.info('The range is invalid, please check range parameter.', '')\r\n }\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 复制指定工作表指定单元格区域的数据,返回包含``html格式的数据,可用于粘贴到excel中保持单元格样式。\r\n * @param {Object} options 可选参数\r\n * @param {Array | Object | String} options.range 选区范围\r\n * @param {order} options.order 工作表下标\r\n */\r\nexport function getRangeHtml(options = {}) {\r\n let {\r\n range = Store.luckysheet_select_save,\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = [{\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n }]\r\n }\r\n else if(getObjType(range) == 'object'){\r\n if(range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n range = [{\r\n \"row\": range.row,\r\n \"column\": range.column\r\n }];\r\n }\r\n\r\n if(getObjType(range) != 'array'){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n //复制范围内包含部分合并单元格,提示\r\n let cfg = $.extend(true, {}, file.config);\r\n if (cfg[\"merge\"] != null) {\r\n let has_PartMC = false;\r\n\r\n for (let s = 0; s < range.length; s++) {\r\n let r1 = range[s].row[0],\r\n r2 = range[s].row[1];\r\n let c1 = range[s].column[0],\r\n c2 = range[s].column[1];\r\n\r\n has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);\r\n\r\n if (has_PartMC) {\r\n break;\r\n }\r\n }\r\n\r\n if (has_PartMC) {\r\n return tooltip.info(\"Cannot perform this operation on partially merged cells\", \"\");\r\n }\r\n }\r\n\r\n //多重选区 有条件格式时 提示\r\n let cdformat = $.extend(true, [], file.luckysheet_conditionformat_save);\r\n if (range.length > 1 && cdformat.length > 0) {\r\n let hasCF = false;\r\n let cf_compute = conditionformat.getComputeMap(file.index);\r\n\r\n for (let s = 0; s < range.length; s++) {\r\n let r1 = range[s].row[0],\r\n r2 = range[s].row[1];\r\n let c1 = range[s].column[0],\r\n c2 = range[s].column[1];\r\n\r\n for (let r = r1; r <= r2; r++) {\r\n for (let c = c1; c <= c2; c++) {\r\n if (conditionformat.checksCF(r, c, cf_compute) != null) {\r\n hasCF = true;\r\n break;\r\n }\r\n }\r\n\r\n if (hasCF) {\r\n break;\r\n }\r\n }\r\n\r\n if (hasCF) {\r\n break;\r\n }\r\n }\r\n\r\n if (hasCF) {\r\n return tooltip.info(\"Cannot perform this operation on multiple selection areas, please select a single area\", \"\");\r\n }\r\n }\r\n\r\n //多重选区 行不一样且列不一样时 提示\r\n if (range.length > 1) {\r\n let isSameRow = true,\r\n str_r = range[0].row[0],\r\n end_r = range[0].row[1];\r\n let isSameCol = true,\r\n str_c = range[0].column[0],\r\n end_c = range[0].column[1];\r\n\r\n for (let s = 1; s < range.length; s++) {\r\n if (range[s].row[0] != str_r || range[s].row[1] != end_r) {\r\n isSameRow = false;\r\n }\r\n\r\n if (range[s].column[0] != str_c || range[s].column[1] != end_c) {\r\n isSameCol = false;\r\n }\r\n }\r\n\r\n if ((!isSameRow && !isSameCol) || selectIsOverlap(range)) {\r\n return tooltip.info(\"Cannot perform this operation on multiple selection areas, please select a single area\", \"\");\r\n }\r\n }\r\n\r\n let rowIndexArr = [], colIndexArr = [];\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0],\r\n r2 = range[s].row[1];\r\n let c1 = range[s].column[0],\r\n c2 = range[s].column[1];\r\n\r\n for(let r = r1; r <= r2; r++){\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n if(!rowIndexArr.includes(r)){\r\n rowIndexArr.push(r);\r\n }\r\n\r\n for(let c = c1; c <= c2; c++){\r\n if (cfg[\"colhidden\"] != null && cfg[\"colhidden\"][c] != null) {\r\n continue;\r\n }\r\n\r\n if(!colIndexArr.includes(c)){\r\n colIndexArr.push(c);\r\n }\r\n }\r\n }\r\n }\r\n\r\n let borderInfoCompute;\r\n if(cfg[\"borderInfo\"] && cfg[\"borderInfo\"].length > 0){ //边框\r\n borderInfoCompute = getBorderInfoCompute(file.index);\r\n }\r\n\r\n let d = file.data;\r\n if(d == null || d.length == 0){\r\n d = sheetmanage.buildGridData(file);\r\n }\r\n\r\n let cpdata = \"\";\r\n let colgroup = \"\";\r\n\r\n rowIndexArr = rowIndexArr.sort();\r\n colIndexArr = colIndexArr.sort();\r\n\r\n for (let i = 0; i < rowIndexArr.length; i++) {\r\n let r = rowIndexArr[i];\r\n\r\n if (cfg[\"rowhidden\"] != null && cfg[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n cpdata += '';\r\n\r\n for (let j = 0; j < colIndexArr.length; j++) {\r\n let c = colIndexArr[j];\r\n\r\n if (cfg[\"colhidden\"] != null && cfg[\"colhidden\"][c] != null) {\r\n continue;\r\n }\r\n\r\n let column = '';\r\n }\r\n else {\r\n colgroup += '';\r\n }\r\n }\r\n\r\n if(c == colIndexArr[0]){\r\n if(cfg[\"rowlen\"] == null || cfg[\"rowlen\"][r.toString()] == null){\r\n style += 'height:19px;';\r\n }\r\n else {\r\n style += 'height:'+ cfg[\"rowlen\"][r.toString()] + 'px;';\r\n }\r\n }\r\n\r\n let reg = /^(w|W)((0?)|(0\\.0+))$/;\r\n let c_value;\r\n if(d[r][c].ct != null && d[r][c].ct.fa != null && d[r][c].ct.fa.match(reg)){\r\n c_value = getcellvalue(r, c, d);\r\n }\r\n else{\r\n c_value = getcellvalue(r, c, d, \"m\");\r\n }\r\n\r\n style += menuButton.getStyleByCell(d, r, c);\r\n\r\n if(getObjType(d[r][c]) == \"object\" && (\"mc\" in d[r][c])){\r\n if(\"rs\" in d[r][c][\"mc\"]){\r\n span = 'rowspan=\"'+ d[r][c][\"mc\"].rs +'\" colspan=\"'+ d[r][c][\"mc\"].cs +'\"';\r\n\r\n //边框\r\n if(borderInfoCompute && borderInfoCompute[r + \"_\" + c]){\r\n let bl_obj = { \"color\": {}, \"style\": {} },\r\n br_obj = { \"color\": {}, \"style\": {} },\r\n bt_obj = { \"color\": {}, \"style\": {} },\r\n bb_obj = { \"color\": {}, \"style\": {} };\r\n\r\n for(let bd_r = r; bd_r < (r + d[r][c][\"mc\"].rs); bd_r++){\r\n for(let bd_c = c; bd_c < (c + d[r][c][\"mc\"].cs); bd_c++){\r\n if(bd_r == r && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].t){\r\n let linetype = borderInfoCompute[bd_r + \"_\" + bd_c].t.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].t.color;\r\n\r\n if(bt_obj[\"style\"][linetype] == null){\r\n bt_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n bt_obj[\"style\"][linetype] = bt_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(bt_obj[\"color\"][bcolor] == null){\r\n bt_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n bt_obj[\"color\"][bcolor] = bt_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n\r\n if(bd_r == (r + d[r][c][\"mc\"].rs - 1) && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].b){\r\n let linetype = borderInfoCompute[bd_r + \"_\" + bd_c].b.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].b.color;\r\n\r\n if(bb_obj[\"style\"][linetype] == null){\r\n bb_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n bb_obj[\"style\"][linetype] = bb_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(bb_obj[\"color\"][bcolor] == null){\r\n bb_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n bb_obj[\"color\"][bcolor] = bb_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n\r\n if(bd_c == c && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].l){\r\n let linetype = borderInfoCompute[r + \"_\" + c].l.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].l.color;\r\n\r\n if(bl_obj[\"style\"][linetype] == null){\r\n bl_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n bl_obj[\"style\"][linetype] = bl_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(bl_obj[\"color\"][bcolor] == null){\r\n bl_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n bl_obj[\"color\"][bcolor] = bl_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n\r\n if(bd_c == (c + d[r][c][\"mc\"].cs - 1) && borderInfoCompute[bd_r + \"_\" + bd_c] && borderInfoCompute[bd_r + \"_\" + bd_c].r){\r\n let linetype = borderInfoCompute[bd_r + \"_\" + bd_c].r.style;\r\n let bcolor = borderInfoCompute[bd_r + \"_\" + bd_c].r.color;\r\n\r\n if(br_obj[\"style\"][linetype] == null){\r\n br_obj[\"style\"][linetype] = 1;\r\n }\r\n else{\r\n br_obj[\"style\"][linetype] = br_obj[\"style\"][linetype] + 1;\r\n }\r\n\r\n if(br_obj[\"color\"][bcolor] == null){\r\n br_obj[\"color\"][bcolor] = 1;\r\n }\r\n else{\r\n br_obj[\"color\"][bcolor] = br_obj[\"color\"][bcolor] + 1;\r\n }\r\n }\r\n }\r\n }\r\n\r\n let rowlen = d[r][c][\"mc\"].rs, collen = d[r][c][\"mc\"].cs;\r\n\r\n if(JSON.stringify(bl_obj).length > 23){\r\n let bl_color = null, bl_style = null;\r\n\r\n for(let x in bl_obj.color){\r\n if(bl_obj.color[x] >= (rowlen / 2)){\r\n bl_color = x;\r\n }\r\n }\r\n\r\n for(let x in bl_obj.style){\r\n if(bl_obj.style[x] >= (rowlen / 2)){\r\n bl_style = x;\r\n }\r\n }\r\n\r\n if(bl_color != null && bl_style != null){\r\n style += \"border-left:\" + selection.getHtmlBorderStyle(bl_style, bl_color);\r\n }\r\n }\r\n\r\n if(JSON.stringify(br_obj).length > 23){\r\n let br_color = null, br_style = null;\r\n\r\n for(let x in br_obj.color){\r\n if(br_obj.color[x] >= (rowlen / 2)){\r\n br_color = x;\r\n }\r\n }\r\n\r\n for(let x in br_obj.style){\r\n if(br_obj.style[x] >= (rowlen / 2)){\r\n br_style = x;\r\n }\r\n }\r\n\r\n if(br_color != null && br_style != null){\r\n style += \"border-right:\" + selection.getHtmlBorderStyle(br_style, br_color);\r\n }\r\n }\r\n\r\n if(JSON.stringify(bt_obj).length > 23){\r\n let bt_color = null, bt_style = null;\r\n\r\n for(let x in bt_obj.color){\r\n if(bt_obj.color[x] >= (collen / 2)){\r\n bt_color = x;\r\n }\r\n }\r\n\r\n for(let x in bt_obj.style){\r\n if(bt_obj.style[x] >= (collen / 2)){\r\n bt_style = x;\r\n }\r\n }\r\n\r\n if(bt_color != null && bt_style != null){\r\n style += \"border-top:\" + selection.getHtmlBorderStyle(bt_style, bt_color);\r\n }\r\n }\r\n\r\n if(JSON.stringify(bb_obj).length > 23){\r\n let bb_color = null, bb_style = null;\r\n\r\n for(let x in bb_obj.color){\r\n if(bb_obj.color[x] >= (collen / 2)){\r\n bb_color = x;\r\n }\r\n }\r\n\r\n for(let x in bb_obj.style){\r\n if(bb_obj.style[x] >= (collen / 2)){\r\n bb_style = x;\r\n }\r\n }\r\n\r\n if(bb_color != null && bb_style != null){\r\n style += \"border-bottom:\" + selection.getHtmlBorderStyle(bb_style, bb_color);\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n continue;\r\n }\r\n }\r\n else{\r\n //边框\r\n if(borderInfoCompute && borderInfoCompute[r + \"_\" + c]){\r\n //左边框\r\n if(borderInfoCompute[r + \"_\" + c].l){\r\n let linetype = borderInfoCompute[r + \"_\" + c].l.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].l.color;\r\n style += \"border-left:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //右边框\r\n if(borderInfoCompute[r + \"_\" + c].r){\r\n let linetype = borderInfoCompute[r + \"_\" + c].r.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].r.color;\r\n style += \"border-right:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //下边框\r\n if(borderInfoCompute[r + \"_\" + c].b){\r\n let linetype = borderInfoCompute[r + \"_\" + c].b.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].b.color;\r\n style += \"border-bottom:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //上边框\r\n if(borderInfoCompute[r + \"_\" + c].t){\r\n let linetype = borderInfoCompute[r + \"_\" + c].t.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].t.color;\r\n style += \"border-top:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n }\r\n }\r\n\r\n column = replaceHtml(column, {\"style\": style, \"span\": span});\r\n\r\n if(c_value == null){\r\n c_value = getcellvalue(r, c, d);\r\n }\r\n\r\n if(c_value == null){\r\n c_value = \" \";\r\n }\r\n\r\n column += c_value;\r\n }\r\n else {\r\n let style = \"\";\r\n\r\n //边框\r\n if(borderInfoCompute && borderInfoCompute[r + \"_\" + c]){\r\n //左边框\r\n if(borderInfoCompute[r + \"_\" + c].l){\r\n let linetype = borderInfoCompute[r + \"_\" + c].l.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].l.color;\r\n style += \"border-left:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //右边框\r\n if(borderInfoCompute[r + \"_\" + c].r){\r\n let linetype = borderInfoCompute[r + \"_\" + c].r.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].r.color;\r\n style += \"border-right:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //下边框\r\n if(borderInfoCompute[r + \"_\" + c].b){\r\n let linetype = borderInfoCompute[r + \"_\" + c].b.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].b.color;\r\n style += \"border-bottom:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n\r\n //上边框\r\n if(borderInfoCompute[r + \"_\" + c].t){\r\n let linetype = borderInfoCompute[r + \"_\" + c].t.style;\r\n let bcolor = borderInfoCompute[r + \"_\" + c].t.color;\r\n style += \"border-top:\" + selection.getHtmlBorderStyle(linetype, bcolor);\r\n }\r\n }\r\n\r\n column += \"\";\r\n\r\n if(r == rowIndexArr[0]){\r\n if(cfg[\"columnlen\"] == null || cfg[\"columnlen\"][c.toString()] == null){\r\n colgroup += '';\r\n }\r\n else {\r\n colgroup += '';\r\n }\r\n }\r\n\r\n if(c == colIndexArr[0]){\r\n if(cfg[\"rowlen\"] == null || cfg[\"rowlen\"][r.toString()] == null){\r\n style += 'height:19px;';\r\n }\r\n else {\r\n style += 'height:'+ cfg[\"rowlen\"][r.toString()] + 'px;';\r\n }\r\n }\r\n\r\n column = replaceHtml(column, {\"style\": style, \"span\": \"\"});\r\n column += \" \";\r\n }\r\n\r\n column += '';\r\n cpdata += column;\r\n }\r\n\r\n cpdata += \"\";\r\n }\r\n\r\n cpdata = '
';\r\n\r\n if (d[r] != null && d[r][c] != null) {\r\n let style = \"\", span = \"\";\r\n\r\n if(r == rowIndexArr[0]){\r\n if(cfg[\"columnlen\"] == null || cfg[\"columnlen\"][c.toString()] == null){\r\n colgroup += '
' + colgroup + cpdata + '
';\r\n\r\n return cpdata;\r\n}\r\n\r\n\r\n/**\r\n * 复制指定工作表指定单元格区域的数据,返回一维、二维或者自定义行列数的二维数组的数据。只有在dimensional设置为custom的时候,才需要设置setting中的row和column\r\n * @param {String} dimensional 数组维度。可选值为:oneDimensional-一维数组;twoDimensional-二维数组; custom-自定义行列数的二维数组\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.row dimensional为custom的时候设置,多维数组的行数\r\n * @param {Number} options.column dimensional为custom的时候设置,多维数组的列数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n */\r\nexport function getRangeArray(dimensional, options = {}) {\r\n let dimensionalValues = ['oneDimensional', 'twoDimensional'];\r\n\r\n if(!dimensionalValues.includes(dimensional)){\r\n return tooltip.info(\"The dimensional parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n range = formula.getcellrange(range);\r\n }\r\n\r\n if(getObjType(range) != 'object' || range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let r1 = range.row[0],\r\n r2 = range.row[1];\r\n let c1 = range.column[0],\r\n c2 = range.column[1];\r\n\r\n //复制范围内包含部分合并单元格,提示\r\n let cfg = $.extend(true, {}, file.config);\r\n if(cfg[\"merge\"] != null){\r\n let has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n return tooltip.info(\"Cannot perform this operation on partially merged cells\", \"\");\r\n }\r\n }\r\n\r\n let data = file.data;\r\n if(data == null || data.length == 0){\r\n data = sheetmanage.buildGridData(file);\r\n }\r\n\r\n let dataArr = [];\r\n\r\n if(dimensional == 'oneDimensional'){//一维数组\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = data[r][c];\r\n\r\n if(cell == null || cell.v == null){\r\n dataArr.push(null);\r\n }\r\n else{\r\n dataArr.push(cell.v);\r\n }\r\n }\r\n }\r\n }\r\n else if(dimensional == 'twoDimensional'){\r\n for(let r = r1; r <= r2; r++){\r\n let row = [];\r\n\r\n for(let c = c1; c <= c2; c++){\r\n let cell = data[r][c];\r\n\r\n if(cell == null || cell.v == null){\r\n row.push(null);\r\n }\r\n else{\r\n row.push(cell.v);\r\n }\r\n }\r\n\r\n dataArr.push(row);\r\n }\r\n }\r\n\r\n return dataArr;\r\n}\r\n\r\n/**\r\n * 复制指定工作表指定单元格区域的数据,返回json格式的数据\r\n * @param {Boolean} isFirstRowTitle 是否首行为标题\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n */\r\nexport function getRangeJson(isFirstRowTitle, options = {}) {\r\n let curRange = Store.luckysheet_select_save[0];\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n range = curRange,\r\n order = curSheetOrder\r\n } = {...options}\r\n let file = Store.luckysheetfile[order];\r\n let config = file.config;\r\n\r\n if (range && typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n if (!range || range.length > 1) {\r\n if(isEditMode()){\r\n alert(locale_drag.noMulti);\r\n } else{\r\n tooltip.info(locale_drag.noMulti, \"\");\r\n }\r\n return;\r\n }\r\n\r\n //复制范围内包含部分合并单元格,提示\r\n if(config[\"merge\"] != null) {\r\n let has_PartMC = false;\r\n let r1 = range.row[0],\r\n r2 = range.row[1],\r\n c1 = range.column[0],\r\n c2 = range.column[1];\r\n has_PartMC = hasPartMC(config, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(locale().drag.noPartMerge);\r\n } else{\r\n tooltip.info(locale().drag.noPartMerge, \"\");\r\n }\r\n return;\r\n }\r\n }\r\n let getdata = getdatabyselection(range, file.index);\r\n let arr = [];\r\n if (getdata.length === 0) {\r\n return;\r\n }\r\n if (isFirstRowTitle) {\r\n if (getdata.length === 1) {\r\n let obj = {};\r\n for (let i = 0; i < getdata[0].length; i++) {\r\n obj[getcellvalue(0, i, getdata)] = \"\";\r\n }\r\n arr.push(obj);\r\n } else {\r\n for (let r = 1; r < getdata.length; r++) {\r\n let obj = {};\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n if(getcellvalue(0, c, getdata) == undefined){\r\n obj[\"\"] = getcellvalue(r, c, getdata);\r\n }else{\r\n obj[getcellvalue(0, c, getdata)] = getcellvalue(r, c, getdata);\r\n }\r\n }\r\n arr.push(obj);\r\n }\r\n }\r\n } else {\r\n let st = range[\"column\"][0];\r\n for (let r = 0; r < getdata.length; r++) {\r\n let obj = {};\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n obj[chatatABC(c + st)] = getcellvalue(r, c, getdata);\r\n }\r\n arr.push(obj);\r\n }\r\n }\r\n // selection.copybyformat(new Event('click'), JSON.stringify(arr));\r\n return arr;\r\n}\r\n\r\n/**\r\n *\r\n * @param {String} type 对角线还是对角线偏移 \"normal\"-对角线 \"anti\"-反对角线\r\n\"offset\"-对角线偏移\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.column type为offset的时候设置,对角偏移的列数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n */\r\nexport function getRangeDiagonal(type, options = {}) {\r\n let typeValues = ['normal', 'anti', 'offset'];\r\n if (typeValues.indexOf(type) < 0) {\r\n return tooltip.info('The type parameter must be included in [\\'normal\\', \\'anti\\', \\'offset\\']', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let curRange = Store.luckysheet_select_save;\r\n let {\r\n column = 1,\r\n range = curRange,\r\n order = curSheetOrder\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n let config = file.config;\r\n\r\n if (range && typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n if (!range || range.length > 1) {\r\n if(isEditMode()){\r\n alert(locale().drag.noMulti);\r\n } else{\r\n tooltip.info(locale().drag.noMulti, \"\");\r\n }\r\n return;\r\n }\r\n\r\n //复制范围内包含部分合并单元格,提示\r\n if(config[\"merge\"] != null) {\r\n let has_PartMC = false;\r\n let r1 = range[0].row[0],\r\n r2 = range[0].row[1],\r\n c1 = range[0].column[0],\r\n c2 = range[0].column[1];\r\n has_PartMC = hasPartMC(config, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(locale().drag.noPartMerge);\r\n } else{\r\n tooltip.info(locale().drag.noPartMerge, \"\");\r\n }\r\n return;\r\n }\r\n }\r\n let getdata = getdatabyselection(range, order);\r\n let arr = [];\r\n if (getdata.length === 0) {\r\n return;\r\n }\r\n\r\n let clen = getdata[0].length;\r\n switch (type) {\r\n case 'normal':\r\n for (let r = 0; r < getdata.length; r++) {\r\n if (r >= clen) {\r\n break;\r\n }\r\n arr.push(getdata[r][r]);\r\n }\r\n break;\r\n case 'anti':\r\n for (let r = 0; r < getdata.length; r++) {\r\n if (r >= clen) {\r\n break;\r\n }\r\n arr.push(getdata[r][clen - r - 1]);\r\n }\r\n break;\r\n case 'offset':\r\n if(column.toString() == \"NaN\"){\r\n if(isEditMode()){\r\n alert(locale().drag.inputCorrect);\r\n } else{\r\n tooltip.info(locale().drag.inputCorrect, \"\");\r\n }\r\n return;\r\n }\r\n\r\n if(column < 0){\r\n if(isEditMode()){\r\n alert(locale().drag.offsetColumnLessZero);\r\n } else{\r\n tooltip.info(locale().drag.offsetColumnLessZero, \"\");\r\n }\r\n return;\r\n }\r\n\r\n for (let r = 0; r < getdata.length; r++) {\r\n if (r + column >= clen) {\r\n break;\r\n }\r\n arr.push(getdata[r][r + column]);\r\n }\r\n break;\r\n }\r\n selection.copybyformat(new Event(), JSON.stringify(arr));\r\n}\r\n\r\n/**\r\n * 复制指定工作表指定单元格区域的数据,返回布尔值的数据\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n */\r\nexport function getRangeBoolean(options = {}) {\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let curRange = Store.luckysheet_select_save;\r\n let {\r\n range = curRange,\r\n order = curSheetOrder\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n let config = file.config;\r\n\r\n if (range && typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n if (!range || range.length > 1) {\r\n if(isEditMode()){\r\n alert(locale().drag.noMulti);\r\n } else{\r\n tooltip.info(locale().drag.noMulti, \"\");\r\n }\r\n return;\r\n }\r\n\r\n //复制范围内包含部分合并单元格,提示\r\n if(config[\"merge\"] != null) {\r\n let has_PartMC = false;\r\n let r1 = range[0].row[0],\r\n r2 = range[0].row[1],\r\n c1 = range[0].column[0],\r\n c2 = range[0].column[1];\r\n has_PartMC = hasPartMC(config, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(locale().drag.noPartMerge);\r\n } else{\r\n tooltip.info(locale().drag.noPartMerge, \"\");\r\n }\r\n return;\r\n }\r\n }\r\n let getdata = getdatabyselection(range, order);\r\n let arr = [];\r\n if (getdata.length === 0) {\r\n return;\r\n }\r\n for (let r = 0; r < getdata.length; r++) {\r\n let a = [];\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n let bool = false;\r\n\r\n let v;\r\n if(getObjType(getdata[r][c]) == \"object\"){\r\n v = getdata[r][c].v;\r\n } else{\r\n v = getdata[r][c];\r\n }\r\n\r\n if (v == null || v == \"\") {\r\n bool = false;\r\n } else {\r\n v = parseInt(v);\r\n if (v == null || v > 0) {\r\n bool = true;\r\n } else {\r\n bool = false;\r\n }\r\n }\r\n a.push(bool);\r\n }\r\n arr.push(a);\r\n }\r\n\r\n selection.copybyformat(event, JSON.stringify(arr));\r\n}\r\n\r\n\r\n/**\r\n * 指定工作表选中一个或多个选区为选中状态并选择是否高亮,支持多种格式设置。\r\n * @param {Array | Object | String} range 选区范围\r\n * @param {Object} options 可选参数\r\n * @param {Boolean} options.show 是否显示高亮选中效果;默认值为 `true`\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeShow(range, options = {}) {\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = [{\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n }]\r\n }\r\n else if(getObjType(range) == 'object'){\r\n if(range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n range = [{\r\n \"row\": range.row,\r\n \"column\": range.column\r\n }];\r\n }\r\n\r\n if(getObjType(range) == 'array'){\r\n for(let i = 0; i < range.length; i++){\r\n if(getObjType(range[i]) === 'string'){\r\n if(!formula.iscelldata(range[i])){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n let cellrange = formula.getcellrange(range[i]);\r\n range[i] = {\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n }\r\n }\r\n else if(getObjType(range) == 'object'){\r\n if(range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n range = {\r\n \"row\": range.row,\r\n \"column\": range.column\r\n };\r\n }\r\n }\r\n }\r\n\r\n if(getObjType(range) != 'array'){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n show = true,\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n for(let i = 0; i < range.length; i++){\r\n let changeparam = menuButton.mergeMoveMain(range[i].column, range[i].row, range[i]);\r\n if(changeparam) {\r\n range[i] = {\r\n \"row\": changeparam[1],\r\n \"column\": changeparam[0]\r\n }\r\n }\r\n }\r\n\r\n file.luckysheet_select_save = range;\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n Store.luckysheet_select_save = range;\r\n selectHightlightShow();\r\n\r\n if(!show){\r\n $(\"#luckysheet-cell-selected-boxs\").hide();\r\n $(\"#luckysheet-cell-selected-focus\").hide();\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n $(\"#luckysheet-rows-h-selected\").empty();\r\n $(\"#luckysheet-cols-h-selected\").empty();\r\n }\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 将一个单元格数组数据赋值到指定的区域,数据格式同getRangeValue方法取到的数据。\r\n * @param {Array[Array]} data 要赋值的单元格二维数组数据,每个单元格的值,可以为字符串或数字,或为符合Luckysheet格式的对象\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Boolean} options.isRefresh 是否刷新界面;默认为true\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeValue(data, options = {}) {\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let curRange = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let {\r\n range = curRange,\r\n isRefresh = true,\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n if (data == null) {\r\n return tooltip.info('The data which will be set to range cannot be null.', '')\r\n }\r\n\r\n if (range instanceof Array) {\r\n return tooltip.info('setRangeValue only supports a single selection.', '')\r\n }\r\n\r\n if (typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n let rowCount = range.row[1] - range.row[0] + 1,\r\n columnCount = range.column[1] - range.column[0] + 1;\r\n\r\n if (data.length !== rowCount || data[0].length !== columnCount) {\r\n return tooltip.info('The data to be set does not match the selection.', '')\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n let sheetData = $.extend(true, [], file.data);\r\n\r\n for (let i = 0; i < rowCount; i++) {\r\n for (let j = 0; j < columnCount; j++) {\r\n let row = range.row[0] + i,\r\n column = range.column[0] + j;\r\n setCellValue(row, column, data[i][j], {order: order, isRefresh: false})\r\n }\r\n }\r\n\r\n let fileData = $.extend(true, [], file.data);\r\n file.data.length = 0;\r\n file.data.push(...sheetData);\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n jfrefreshgrid(fileData, [{\r\n row: range.row,\r\n column: range.column,\r\n }], undefined, true, false);\r\n }\r\n\r\n if(isRefresh) {\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 设置指定范围的单元格格式,一般用作处理格式,赋值操作推荐使用setRangeValue方法\r\n * @param {String} attr 要赋值的单元格二维数组数据,每个单元格的值,可以为字符串或数字,或为符合Luckysheet格式的对象\r\n * @param {Number | String | Object} value 具体的设置值\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 设置参数的目标选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n */\r\nexport function setSingleRangeFormat(attr, value, options = {}) {\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let curRange = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let {\r\n range = curRange,\r\n order = curSheetOrder,\r\n } = {...options}\r\n\r\n if (!attr) {\r\n tooltip.info('Arguments attr cannot be null or undefined.', '')\r\n return 'error';\r\n }\r\n\r\n if (range instanceof Array) {\r\n tooltip.info('setRangeValue only supports a single selection.', '')\r\n return 'error';\r\n }\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n tooltip.info(\"The range parameter is invalid.\", \"\");\r\n return 'error';\r\n }\r\n\r\n range = formula.getcellrange(range);\r\n }\r\n\r\n if(getObjType(range) != 'object' || range.row == null || range.column == null){\r\n tooltip.info(\"The range parameter is invalid.\", \"\");\r\n return 'error';\r\n }\r\n\r\n for (let r = range.row[0]; r <= range.row[1]; r++) {\r\n for (let c = range.column[0]; c <= range.column[1]; c++) {\r\n console.log('r',r);\r\n console.log('c',c);\r\n setCellValue(r, c, {[attr]: value}, {\r\n order: order,\r\n isRefresh: false,\r\n })\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 设置指定范围的单元格格式,一般用作处理格式。支持多选区设置\r\n * @param {String} attr 要赋值的单元格二维数组数据,每个单元格的值,可以为字符串或数字,或为符合Luckysheet格式的对象\r\n * @param {Number | String | Object} value 具体的设置值\r\n * @param {Object} options 可选参数\r\n * @param {Array | Object | String} options.range 设置参数的目标选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeFormat(attr, value, options = {}) {\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let curRange = Store.luckysheet_select_save;\r\n let {\r\n range = curRange,\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = [{\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n }]\r\n }\r\n else if(getObjType(range) == 'object'){\r\n if(range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n range = [{\r\n \"row\": range.row,\r\n \"column\": range.column\r\n }];\r\n }\r\n\r\n if(getObjType(range) != 'array'){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n let sheetData = $.extend(true, [], file.data);\r\n let result = []\r\n\r\n for (let i = 0; i < range.length; i++) {\r\n result.push(setSingleRangeFormat(attr, value, { range: range[i], order: order }));\r\n }\r\n\r\n if(result.some(i => i === 'error')) {\r\n file.data.length = 0;\r\n file.data.push(...sheetData);\r\n return false;\r\n }\r\n\r\n let fileData = $.extend(true, [], file.data);\r\n file.data.length = 0;\r\n file.data.push(...sheetData);\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n jfrefreshgrid(fileData, undefined, undefined, true, false);\r\n }\r\n\r\n luckysheetrefreshgrid();\r\n\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n}\r\n\r\n/**\r\n * 为指定索引的工作表,选定的范围开启或关闭筛选功能\r\n * @param {String} type 打开还是关闭筛选功能 open-打开筛选功能,返回当前筛选的范围对象;close-关闭筛选功能,返回关闭前筛选的范围对象\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Object} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeFilter(type, options = {}) {\r\n let typeValues = ['open', 'close'];\r\n\r\n if(!typeValues.includes(type)){\r\n return tooltip.info(\"The type parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n range = formula.getcellrange(range);\r\n }\r\n\r\n if(getObjType(range) != 'object' || range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n if(type == 'open'){\r\n file.filter_select = range;\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n createFilterOptions(range, file.filter);\r\n }\r\n\r\n return {\r\n \"row\": range.row,\r\n \"column\": range.column\r\n };\r\n }\r\n else if(type == 'close'){\r\n let luckysheet_filter_save = $.extend(true, {}, file.filter_select);\r\n\r\n file.filter_select = null;\r\n\r\n $(\"#luckysheet-filter-selected-sheet\" + file.index).remove();\r\n $(\"#luckysheet-filter-options-sheet\" + file.index).remove();\r\n\r\n return {\r\n \"row\": luckysheet_filter_save.row,\r\n \"column\": luckysheet_filter_save.column\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * 为指定索引的工作表,选定的范围设定合并单元格\r\n * @param {String} type 合并类型 all-全部合并 horizontal-水平合并 vertical-垂直合并\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Object} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeMerge(type, options = {}) {\r\n let typeValues = ['all', 'horizontal', 'vertical'];\r\n if (typeValues.indexOf(type) < 0) {\r\n return tooltip.info('The type parameter must be included in [\\'all\\', \\'horizontal\\', \\'vertical\\']', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex),\r\n curRange = Store.luckysheet_select_save;\r\n let {\r\n range = curRange,\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order],\r\n cfg = $.extend(true, {}, file.config),\r\n data = $.extend(true, [], file.data);\r\n\r\n if(data.length == 0){\r\n data = $.extend(true, [], sheetmanage.buildGridData(file));\r\n }\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info('Incorrect selection format', '');\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = [{\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n }]\r\n }\r\n else if(getObjType(range) == 'object'){\r\n if(!range.hasOwnProperty(\"row\") || !range.hasOwnProperty(\"column\")){\r\n return tooltip.info('Incorrect selection format', '');\r\n }\r\n\r\n range = [{\r\n \"row\": range.row,\r\n \"column\": range.column\r\n }]\r\n }\r\n\r\n //不能合并重叠区域\r\n if(selectIsOverlap(range)){\r\n return tooltip.info('Cannot merge overlapping range', '');\r\n }\r\n\r\n //选区是否含有 部分合并单元格\r\n if(cfg[\"merge\"] != null){\r\n let has_PartMC = false;\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0],\r\n r2 = range[s].row[1];\r\n let c1 = range[s].column[0],\r\n c2 = range[s].column[1];\r\n\r\n has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n break;\r\n }\r\n }\r\n\r\n if(has_PartMC){\r\n return tooltip.info('Cannot perform this operation on partially merged cells', '');\r\n }\r\n }\r\n\r\n //选区是否含有 合并的单元格\r\n let isHasMc = false;\r\n\r\n for(let i = 0; i < range.length; i++){\r\n let r1 = range[i].row[0],\r\n r2 = range[i].row[1];\r\n let c1 = range[i].column[0],\r\n c2 = range[i].column[1];\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = data[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n isHasMc = true;\r\n break;\r\n }\r\n }\r\n\r\n if(isHasMc){\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(isHasMc){//选区有合并单元格(选区都执行 取消合并)\r\n cancelRangeMerge({\r\n range: range,\r\n order: order\r\n })\r\n }\r\n else{\r\n for(let i = 0; i < range.length; i++){\r\n let r1 = range[i].row[0],\r\n r2 = range[i].row[1];\r\n let c1 = range[i].column[0],\r\n c2 = range[i].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n continue;\r\n }\r\n\r\n if(type == \"all\"){\r\n let fv = {}, isfirst = false;\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = data[r][c];\r\n\r\n if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){\r\n fv = $.extend(true, {}, cell);\r\n isfirst = true;\r\n }\r\n\r\n data[r][c] = { \"mc\": { \"r\": r1, \"c\": c1 } };\r\n }\r\n }\r\n\r\n data[r1][c1] = fv;\r\n data[r1][c1].mc = { \"r\": r1, \"c\": c1, \"rs\": r2 - r1 + 1, \"cs\": c2 - c1 + 1 };\r\n\r\n cfg[\"merge\"][r1 + \"_\" + c1] = { \"r\": r1, \"c\": c1, \"rs\": r2 - r1 + 1, \"cs\": c2 - c1 + 1 };\r\n }\r\n else if(type == \"vertical\"){\r\n for(let c = c1; c <= c2; c++){\r\n let fv = {}, isfirst = false;\r\n\r\n for(let r = r1; r <= r2; r++){\r\n let cell = data[r][c];\r\n\r\n if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){\r\n fv = $.extend(true, {}, cell);\r\n isfirst = true;\r\n }\r\n\r\n data[r][c] = { \"mc\": { \"r\": r1, \"c\": c } };\r\n }\r\n\r\n data[r1][c] = fv;\r\n data[r1][c].mc = { \"r\": r1, \"c\": c, \"rs\": r2 - r1 + 1, \"cs\": 1 };\r\n\r\n cfg[\"merge\"][r1 + \"_\" + c] = { \"r\": r1, \"c\": c, \"rs\": r2 - r1 + 1, \"cs\": 1 };\r\n }\r\n }\r\n else if(type == \"horizontal\"){\r\n for(let r = r1; r <= r2; r++){\r\n let fv = {}, isfirst = false;\r\n\r\n for(let c = c1; c <= c2; c++){\r\n let cell = data[r][c];\r\n\r\n if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){\r\n fv = $.extend(true, {}, cell);\r\n isfirst = true;\r\n }\r\n\r\n data[r][c] = { \"mc\": { \"r\": r, \"c\": c1 } };\r\n }\r\n\r\n data[r][c1] = fv;\r\n data[r][c1].mc = { \"r\": r, \"c\": c1, \"rs\": 1, \"cs\": c2 - c1 + 1 };\r\n\r\n cfg[\"merge\"][r + \"_\" + c1] = { \"r\": r, \"c\": c1, \"rs\": 1, \"cs\": c2 - c1 + 1 };\r\n }\r\n }\r\n }\r\n\r\n if(order == curSheetOrder){\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push({\r\n \"type\": \"mergeChange\",\r\n \"sheetIndex\": file.index,\r\n \"data\": $.extend(true, [], file.data),\r\n \"curData\": data,\r\n \"range\": range,\r\n \"config\": $.extend(true, {}, file.config),\r\n \"curConfig\": cfg\r\n });\r\n }\r\n\r\n Store.clearjfundo = false;\r\n jfrefreshgrid(data, range, {\"cfg\": cfg});\r\n Store.clearjfundo = true;\r\n }\r\n else{\r\n file.data = data;\r\n file.config = cfg;\r\n }\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 为指定索引的工作表,选定的范围取消合并单元格\r\n * @param {Object} options 可选参数\r\n * @param {Array | Object | String} options.range 选区范围\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Object} options.success 操作结束的回调函数\r\n */\r\nexport function cancelRangeMerge(options = {}) {\r\n let curRange = Store.luckysheet_select_save,\r\n curSheetOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n range = curRange,\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order],\r\n cfg = $.extend(true, {}, file.config),\r\n data = $.extend(true, [], file.data);\r\n\r\n if(data.length == 0){\r\n data = $.extend(true, [], sheetmanage.buildGridData(file));\r\n }\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info('Incorrect selection format', '');\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = [{\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n }]\r\n }\r\n else if(getObjType(range) == 'object'){\r\n if(!range.hasOwnProperty(\"row\") || !range.hasOwnProperty(\"column\")){\r\n return tooltip.info('Incorrect selection format', '');\r\n }\r\n\r\n range = [{\r\n \"row\": range.row,\r\n \"column\": range.column\r\n }]\r\n }\r\n\r\n //不能合并重叠区域\r\n if(selectIsOverlap(range)){\r\n return tooltip.info('Cannot merge overlapping range', '');\r\n }\r\n\r\n //选区是否含有 部分合并单元格\r\n if(cfg[\"merge\"] != null){\r\n let has_PartMC = false;\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0],\r\n r2 = range[s].row[1];\r\n let c1 = range[s].column[0],\r\n c2 = range[s].column[1];\r\n\r\n has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n break;\r\n }\r\n }\r\n\r\n if(has_PartMC){\r\n return tooltip.info('Cannot perform this operation on partially merged cells', '');\r\n }\r\n }\r\n\r\n for(let i = 0; i < range.length; i++){\r\n let r1 = range[i].row[0],\r\n r2 = range[i].row[1];\r\n let c1 = range[i].column[0],\r\n c2 = range[i].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n continue;\r\n }\r\n\r\n let fv = {};\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = data[r][c];\r\n\r\n if(cell != null && cell.mc != null){\r\n let mc_r = cell.mc.r, mc_c = cell.mc.c;\r\n\r\n if(\"rs\" in cell.mc){\r\n delete cell.mc;\r\n delete cfg[\"merge\"][mc_r + \"_\" + mc_c];\r\n\r\n fv[mc_r + \"_\" + mc_c] = $.extend(true, {}, cell);\r\n }\r\n else{\r\n // let cell_clone = fv[mc_r + \"_\" + mc_c];\r\n let cell_clone = JSON.parse(JSON.stringify(fv[mc_r + \"_\" + mc_c]));\r\n\r\n delete cell_clone.v;\r\n delete cell_clone.m;\r\n delete cell_clone.ct;\r\n delete cell_clone.f;\r\n delete cell_clone.spl;\r\n\r\n data[r][c] = cell_clone;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(order == curSheetOrder){\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push({\r\n \"type\": \"mergeChange\",\r\n \"sheetIndex\": file.index,\r\n \"data\": $.extend(true, [], file.data),\r\n \"curData\": data,\r\n \"range\": range,\r\n \"config\": $.extend(true, {}, file.config),\r\n \"curConfig\": cfg\r\n });\r\n }\r\n\r\n Store.clearjfundo = false;\r\n jfrefreshgrid(data, range, {\"cfg\": cfg});\r\n Store.clearjfundo = true;\r\n }\r\n else{\r\n file.data = data;\r\n file.config = cfg;\r\n }\r\n}\r\n\r\n/**\r\n * 为指定索引的工作表,选定的范围开启排序功能,返回选定范围排序后的数据。\r\n * @param {String} type 排序类型 asc-升序 desc-降序\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeSort(type, options = {}) {\r\n let typeValues = ['asc', 'desc']\r\n if (typeValues.indexOf(type) < 0) {\r\n return tooltip.info('The type parameter must be included in [\\'asc\\', \\'desc\\'', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex),\r\n curRange = Store.luckysheet_select_save[0];\r\n let {\r\n range = curRange,\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order],\r\n cfg = $.extend(true, {}, file.config),\r\n fileData = $.extend(true, [], file.data);\r\n\r\n if(fileData.length == 0){\r\n fileData = $.extend(true, [], sheetmanage.buildGridData(file));\r\n }\r\n\r\n if(range instanceof Array && range.length > 1){\r\n tooltip.info(locale().sort.noRangeError, \"\");\r\n return;\r\n }\r\n\r\n if (range && typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n let r1 = range.row[0],\r\n r2 = range.row[1],\r\n c1 = range.column[0],\r\n c2 = range.column[1];\r\n\r\n let hasMc = false; //Whether the sort selection has merged cells\r\n let data = [];\r\n for(let r = r1; r <= r2; r++){\r\n let data_row = [];\r\n for(let c = c1; c <= c2; c++){\r\n if(fileData[r][c] != null && fileData[r][c].mc != null){\r\n hasMc = true;\r\n break;\r\n }\r\n data_row.push(fileData[r][c]);\r\n }\r\n data.push(data_row);\r\n }\r\n\r\n if(hasMc){\r\n tooltip.info(locale().sort.mergeError, \"\");\r\n return;\r\n }\r\n\r\n data = orderbydata([].concat(data), 0, type === 'asc');\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n fileData[r][c] = data[r - r1][c - c1];\r\n }\r\n }\r\n\r\n let allParam = {};\r\n if(cfg[\"rowlen\"] != null){\r\n cfg = rowlenByRange(fileData, r1, r2, cfg);\r\n\r\n allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true\r\n }\r\n }\r\n\r\n if (file.index == Store.currentSheetIndex) {\r\n jfrefreshgrid(fileData, [{ \"row\": [r1, r2], \"column\": [c1, c2] }], allParam);\r\n }\r\n else{\r\n file.data = fileData;\r\n file.config = cfg;\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 为指定索引的工作表,选定的范围开启多列自定义排序功能,返回选定范围排序后的数据。\r\n * @param {Boolean} hasTitle 数据是否具有标题行\r\n * @param {Array} sort 列设置,设置需要排序的列索引和排序方式,格式如:[{ i:0,sort:'asc' },{ i:1,sort:'des' }]\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeSortMulti(hasTitle, sort, options = {}) {\r\n if (!sort || !(sort instanceof Array)) {\r\n return tooltip.info('The sort parameter is invalid.', '')\r\n }\r\n\r\n let curSheetOrder = getSheetIndex(Store.currentSheetIndex),\r\n curRange = Store.luckysheet_select_save[0];\r\n let {\r\n range = curRange,\r\n order = curSheetOrder,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order],\r\n cfg = $.extend(true, {}, file.config),\r\n fileData = $.extend(true, [], file.data);\r\n\r\n if(fileData.length == 0){\r\n fileData = $.extend(true, [], sheetmanage.buildGridData(file));\r\n }\r\n\r\n if(range instanceof Array && range.length > 1){\r\n tooltip.info(locale().sort.noRangeError, \"\");\r\n return;\r\n }\r\n\r\n if (range && typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n let r1 = range.row[0],\r\n r2 = range.row[1],\r\n c1 = range.column[0],\r\n c2 = range.column[1];\r\n\r\n let str;\r\n if(hasTitle){\r\n str = r1 + 1;\r\n } else{\r\n str = r1;\r\n }\r\n\r\n let hasMc = false; //Whether the sort selection has merged cells\r\n let data = [];\r\n for(let r = str; r <= r2; r++){\r\n let data_row = [];\r\n for(let c = c1; c <= c2; c++){\r\n if(fileData[r][c] != null && fileData[r][c].mc != null){\r\n hasMc = true;\r\n break;\r\n }\r\n data_row.push(fileData[r][c]);\r\n }\r\n data.push(data_row);\r\n }\r\n\r\n if(hasMc){\r\n tooltip.info(locale().sort.mergeError, \"\");\r\n return;\r\n }\r\n\r\n sort.forEach(sortItem => {\r\n let i = sortItem.i;\r\n i -= c1;\r\n data = orderbydata([].concat(data), i, sortItem.sort === 'asc');\r\n })\r\n\r\n for(let r = str; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n fileData[r][c] = data[r - str][c - c1];\r\n }\r\n }\r\n\r\n let allParam = {};\r\n if(cfg[\"rowlen\"] != null){\r\n cfg = rowlenByRange(fileData, str, r2, cfg);\r\n\r\n allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true\r\n }\r\n }\r\n\r\n if (file.index === Store.currentSheetIndex) {\r\n jfrefreshgrid(fileData, [{ \"row\": [str, r2], \"column\": [c1, c2] }], allParam);\r\n }\r\n else{\r\n file.data = fileData;\r\n file.config = cfg;\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 为指定索引的工作表,选定的范围开启条件格式,根据设置的条件格式规则突出显示部分单元格,返回开启条件格式后的数据。\r\n * @param {String} conditionName 条件格式规则类型\r\n * @param {Object} conditionValue 可以设置条件单元格或者条件值\r\n * @param {Object} options 可选参数\r\n * @param {Object} options.format 颜色设置\r\n * @param {Array | Object | String} options.cellrange 选区范围\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeConditionalFormatDefault(conditionName, conditionValue, options = {}) {\r\n let conditionNameValues = [\r\n 'greaterThan',\r\n 'lessThan',\r\n 'betweenness',\r\n 'equal',\r\n 'textContains',\r\n 'occurrenceDate',\r\n 'duplicateValue',\r\n 'top10',\r\n 'top10%',\r\n 'last10',\r\n 'last10%',\r\n 'AboveAverage',\r\n 'SubAverage'\r\n ];\r\n\r\n if(!conditionName || !conditionNameValues.includes(conditionName)){\r\n return tooltip.info('The conditionName parameter is invalid.', '');\r\n }\r\n\r\n if(getObjType(conditionValue) != 'array' || conditionValue.length == 0){\r\n return tooltip.info('The conditionValue parameter is invalid.', '');\r\n }\r\n\r\n let {\r\n format = {\r\n \"textColor\": \"#000000\",\r\n \"cellColor\": \"#ff0000\"\r\n },\r\n cellrange = Store.luckysheet_select_save,\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n let data = file.data;\r\n\r\n if(data == null || data.length == 0){\r\n data = sheetmanage.buildGridData(file);\r\n }\r\n\r\n if(file == null){\r\n return tooltip.info('Incorrect worksheet index', '');\r\n }\r\n\r\n const conditionformat_Text = locale().conditionformat;\r\n\r\n let conditionRange = [], conditionValue2 = [];\r\n\r\n if(conditionName == 'betweenness'){\r\n let v1 = conditionValue[0];\r\n let v2 = conditionValue[1];\r\n\r\n //条件值是否是选区\r\n let rangeArr1 = conditionformat.getRangeByTxt(v1);\r\n if(rangeArr1.length > 1){\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr1.length == 1){\r\n let r1 = rangeArr1[0].row[0], r2 = rangeArr1[0].row[1];\r\n let c1 = rangeArr1[0].column[0], c2 = rangeArr1[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v1 = getcellvalue(r1, c1, data);\r\n\r\n conditionRange.push({ \"row\": rangeArr1[0].row, \"column\": rangeArr1[0].column });\r\n conditionValue2.push(v1);\r\n }\r\n else{\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr1.length == 0){\r\n if(isNaN(v1) || v1 == \"\"){\r\n conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue2.push(v1);\r\n }\r\n }\r\n\r\n let rangeArr2 = conditionformat.getRangeByTxt(v2);\r\n if(rangeArr2.length > 1){\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr2.length == 1){\r\n let r1 = rangeArr2[0].row[0], r2 = rangeArr2[0].row[1];\r\n let c1 = rangeArr2[0].column[0], c2 = rangeArr2[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v2 = getcellvalue(r1, c1, data);\r\n\r\n conditionRange.push({ \"row\": rangeArr2[0].row, \"column\": rangeArr2[0].column });\r\n conditionValue2.push(v2);\r\n }\r\n else{\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr2.length == 0){\r\n if(isNaN(v2) || v2 == \"\"){\r\n conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue2.push(v2);\r\n }\r\n }\r\n }\r\n else if(conditionName == 'greaterThan' || conditionName == 'lessThan' || conditionName == 'equal'){\r\n let v = conditionValue[0];\r\n\r\n //条件值是否是选区\r\n let rangeArr = conditionformat.getRangeByTxt(v);\r\n if(rangeArr.length > 1){\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr.length == 1){\r\n let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];\r\n let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v = getcellvalue(r1, c1, data);\r\n\r\n conditionRange.push({ \"row\": rangeArr[0].row, \"column\": rangeArr[0].column });\r\n conditionValue2.push(v);\r\n }\r\n else{\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr.length == 0){\r\n if(isNaN(v) || v == \"\"){\r\n conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue2.push(v);\r\n }\r\n }\r\n }\r\n else if(conditionName == 'textContains'){\r\n let v = conditionValue[0];\r\n\r\n //条件值是否是选区\r\n let rangeArr = conditionformat.getRangeByTxt(v);\r\n if(rangeArr.length > 1){\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n else if(rangeArr.length == 1){\r\n let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];\r\n let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n v = getcellvalue(r1, c1, data);\r\n\r\n conditionRange.push({ \"row\": rangeArr[0].row, \"column\": rangeArr[0].column });\r\n conditionValue2.push(v);\r\n }\r\n else{\r\n conditionformat.infoDialog(conditionformat_Text.onlySingleCell, \"\");\r\n return;\r\n }\r\n }\r\n else if(rangeArr.length == 0){\r\n if(v == \"\"){\r\n conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, \"\");\r\n return;\r\n }\r\n else{\r\n conditionValue2.push(v);\r\n }\r\n }\r\n }\r\n else if(conditionName == 'occurrenceDate'){\r\n let v1 = conditionValue[0];\r\n let v2 = conditionValue[1];\r\n\r\n if(!isdatetime(v1) || !isdatetime(v2)){\r\n return tooltip.info('The conditionValue parameter is invalid.', '');\r\n }\r\n\r\n let v;\r\n if(diff(v1, v2) > 0){\r\n v = dayjs(v2).format(\"YYYY/MM/DD\") + \"-\" + dayjs(v1).format(\"YYYY/MM/DD\");\r\n }\r\n else{\r\n v = dayjs(v1).format(\"YYYY/MM/DD\") + \"-\" + dayjs(v2).format(\"YYYY/MM/DD\");\r\n }\r\n\r\n conditionValue2.push(v);\r\n }\r\n else if(conditionName == 'duplicateValue'){\r\n let v = conditionValue[0];\r\n\r\n if(v != '0' || v != '1'){\r\n return tooltip.info('The conditionValue parameter is invalid.', '');\r\n }\r\n\r\n conditionValue2.push(v);\r\n }\r\n else if(conditionName == 'top10' || conditionName == 'top10%' || conditionName == 'last10' || conditionName == 'last10%'){\r\n let v = conditionValue[0];\r\n\r\n if(parseInt(v) != v || parseInt(v) < 1 || parseInt(v) > 1000){\r\n conditionformat.infoDialog(conditionformat_Text.pleaseEnterInteger, \"\");\r\n return;\r\n }\r\n\r\n conditionValue2.push(parseInt(v));\r\n }\r\n else if(conditionName == 'AboveAverage' || conditionName == 'SubAverage'){\r\n conditionValue2.push(conditionName);\r\n }\r\n\r\n if(!format.hasOwnProperty(\"textColor\") || !format.hasOwnProperty(\"cellColor\")){\r\n return tooltip.info('The format parameter is invalid.', '');\r\n }\r\n\r\n if(getObjType(cellrange) == 'string'){\r\n cellrange = conditionformat.getRangeByTxt(cellrange);\r\n }\r\n else if(getObjType(cellrange) == 'object'){\r\n cellrange = [cellrange];\r\n }\r\n\r\n if(getObjType(cellrange) != 'array'){\r\n return tooltip.info('The cellrange parameter is invalid.', '');\r\n }\r\n\r\n let rule = {\r\n \"type\": \"default\",\r\n \"cellrange\": cellrange,\r\n \"format\": format,\r\n \"conditionName\": conditionName,\r\n \"conditionRange\": conditionRange,\r\n \"conditionValue\": conditionValue2\r\n };\r\n\r\n //保存之前的规则\r\n let fileH = $.extend(true, [], Store.luckysheetfile);\r\n let historyRules = conditionformat.getHistoryRules(fileH);\r\n\r\n //保存当前的规则\r\n let ruleArr = file[\"luckysheet_conditionformat_save\"] || [];\r\n ruleArr.push(rule);\r\n file[\"luckysheet_conditionformat_save\"] = ruleArr;\r\n\r\n let fileC = $.extend(true, [], Store.luckysheetfile);\r\n let currentRules = conditionformat.getCurrentRules(fileC);\r\n\r\n //刷新一次表格\r\n conditionformat.ref(historyRules, currentRules);\r\n\r\n //发送给后台\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", file.index, ruleArr, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 为指定索引的工作表,选定的范围开启条件格式,返回开启条件格式后的数据。\r\n * @param {String} type 条件格式规则类型\r\n * @param {Object} options 可选参数\r\n * @param {Array | String} options.format 颜色设置\r\n * @param {Array | Object | String} options.cellrange 选区范围\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setRangeConditionalFormat(type, options = {}) {\r\n let typeValues = [\r\n 'dataBar',\r\n 'colorGradation',\r\n 'icons'\r\n ];\r\n\r\n if(!type || !typeValues.includes(type)){\r\n return tooltip.info('The type parameter is invalid.', '');\r\n }\r\n\r\n let {\r\n format,\r\n cellrange = Store.luckysheet_select_save,\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info('Incorrect worksheet index', '');\r\n }\r\n\r\n if(type == 'dataBar'){\r\n if(format == null){\r\n format = [\"#638ec6\", \"#ffffff\"];\r\n }\r\n\r\n if(getObjType(format) != 'array' || format.length < 1 || format.length > 2){\r\n return tooltip.info('The format parameter is invalid.', '');\r\n }\r\n }\r\n else if(type == 'colorGradation'){\r\n if(format == null){\r\n format = [\"rgb(99, 190, 123)\", \"rgb(255, 235, 132)\", \"rgb(248, 105, 107)\"];\r\n }\r\n\r\n if(getObjType(format) != 'array' || format.length < 2 || format.length > 3){\r\n return tooltip.info('The format parameter is invalid.', '');\r\n }\r\n }\r\n else if(type == 'icons'){\r\n if(format == null){\r\n format = \"threeWayArrowMultiColor\";\r\n }\r\n\r\n let formatValues = [\r\n 'threeWayArrowMultiColor',\r\n 'threeTriangles',\r\n 'fourWayArrowMultiColor',\r\n 'fiveWayArrowMultiColor',\r\n 'threeWayArrowGrayColor',\r\n 'fourWayArrowGrayColor',\r\n 'fiveWayArrowGrayColor',\r\n 'threeColorTrafficLightRimless',\r\n 'threeSigns',\r\n 'greenRedBlackGradient',\r\n 'threeColorTrafficLightBordered',\r\n 'fourColorTrafficLight',\r\n 'threeSymbolsCircled',\r\n 'tricolorFlag',\r\n 'threeSymbolsnoCircle',\r\n 'threeStars',\r\n 'fiveQuadrantDiagram',\r\n 'fiveBoxes',\r\n 'grade4',\r\n 'grade5'\r\n ];\r\n\r\n if(getObjType(format) != 'string' || !formatValues.includes(format)){\r\n return tooltip.info('The format parameter is invalid.', '');\r\n }\r\n\r\n switch (format) {\r\n case 'threeWayArrowMultiColor':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 0,\r\n \"top\": 0\r\n };\r\n break;\r\n case 'threeTriangles':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 0,\r\n \"top\": 1\r\n };\r\n break;\r\n case 'fourWayArrowMultiColor':\r\n format = {\r\n \"len\": 4,\r\n \"leftMin\": 0,\r\n \"top\": 2\r\n };\r\n break;\r\n case 'fiveWayArrowMultiColor':\r\n format = {\r\n \"len\": 5,\r\n \"leftMin\": 0,\r\n \"top\": 3\r\n };\r\n break;\r\n case 'threeWayArrowGrayColor':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 5,\r\n \"top\": 0\r\n };\r\n break;\r\n case 'fourWayArrowGrayColor':\r\n format = {\r\n \"len\": 4,\r\n \"leftMin\": 5,\r\n \"top\": 1\r\n };\r\n break;\r\n case 'fiveWayArrowGrayColor':\r\n format = {\r\n \"len\": 5,\r\n \"leftMin\": 5,\r\n \"top\": 2\r\n };\r\n break;\r\n case 'threeColorTrafficLightRimless':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 0,\r\n \"top\": 4\r\n };\r\n break;\r\n case 'threeSigns':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 0,\r\n \"top\": 5\r\n };\r\n break;\r\n case 'greenRedBlackGradient':\r\n format = {\r\n \"len\": 4,\r\n \"leftMin\": 0,\r\n \"top\": 6\r\n };\r\n break;\r\n case 'threeColorTrafficLightBordered':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 5,\r\n \"top\": 4\r\n };\r\n break;\r\n case 'fourColorTrafficLight':\r\n format = {\r\n \"len\": 4,\r\n \"leftMin\": 5,\r\n \"top\": 5\r\n };\r\n break;\r\n case 'threeSymbolsCircled':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 0,\r\n \"top\": 7\r\n };\r\n break;\r\n case 'tricolorFlag':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 0,\r\n \"top\": 8\r\n };\r\n break;\r\n case 'threeSymbolsnoCircle':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 5,\r\n \"top\": 7\r\n };\r\n break;\r\n case 'threeStars':\r\n format = {\r\n \"len\": 3,\r\n \"leftMin\": 0,\r\n \"top\": 9\r\n };\r\n break;\r\n case 'fiveQuadrantDiagram':\r\n format = {\r\n \"len\": 5,\r\n \"leftMin\": 0,\r\n \"top\": 10\r\n };\r\n break;\r\n case 'fiveBoxes':\r\n format = {\r\n \"len\": 5,\r\n \"leftMin\": 0,\r\n \"top\": 11\r\n };\r\n break;\r\n case 'grade4':\r\n format = {\r\n \"len\": 4,\r\n \"leftMin\": 5,\r\n \"top\": 9\r\n };\r\n break;\r\n case 'grade5':\r\n format = {\r\n \"len\": 5,\r\n \"leftMin\": 5,\r\n \"top\": 10\r\n };\r\n break;\r\n }\r\n }\r\n\r\n if(getObjType(cellrange) == 'string'){\r\n cellrange = conditionformat.getRangeByTxt(cellrange);\r\n }\r\n else if(getObjType(cellrange) == 'object'){\r\n cellrange = [cellrange];\r\n }\r\n\r\n if(getObjType(cellrange) != 'array'){\r\n return tooltip.info('The cellrange parameter is invalid.', '');\r\n }\r\n\r\n let rule = {\r\n \"type\": type,\r\n \"cellrange\": cellrange,\r\n \"format\": format\r\n };\r\n\r\n //保存之前的规则\r\n let fileH = $.extend(true, [], Store.luckysheetfile);\r\n let historyRules = conditionformat.getHistoryRules(fileH);\r\n\r\n //保存当前的规则\r\n let ruleArr = file[\"luckysheet_conditionformat_save\"] || [];\r\n ruleArr.push(rule);\r\n file[\"luckysheet_conditionformat_save\"] = ruleArr;\r\n\r\n let fileC = $.extend(true, [], Store.luckysheetfile);\r\n let currentRules = conditionformat.getCurrentRules(fileC);\r\n\r\n //刷新一次表格\r\n conditionformat.ref(historyRules, currentRules);\r\n\r\n //发送给后台\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", file.index, ruleArr, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 为指定下标的工作表,删除条件格式规则,返回被删除的条件格式规则\r\n * @param {Number} itemIndex 条件格式规则索引\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteRangeConditionalFormat(itemIndex, options = {}) {\r\n if(!isRealNum(itemIndex)){\r\n return tooltip.info('The itemIndex parameter is invalid.', '');\r\n }\r\n\r\n itemIndex = Number(itemIndex);\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info('The order parameter is invalid.', '');\r\n }\r\n\r\n let cdformat = $.extend(true, [], file.luckysheet_conditionformat_save);\r\n\r\n if(cdformat.length == 0){\r\n return tooltip.info('This worksheet has no conditional format to delete', '');\r\n }\r\n else if(cdformat[itemIndex] == null){\r\n return tooltip.info('The conditional format of the index cannot be found', '');\r\n }\r\n\r\n let cdformatItem = cdformat.splice(itemIndex, 1);\r\n\r\n //保存之前的规则\r\n let fileH = $.extend(true, [], Store.luckysheetfile);\r\n let historyRules = conditionformat.getHistoryRules(fileH);\r\n\r\n //保存当前的规则\r\n file[\"luckysheet_conditionformat_save\"] = cdformat;\r\n\r\n let fileC = $.extend(true, [], Store.luckysheetfile);\r\n let currentRules = conditionformat.getCurrentRules(fileC);\r\n\r\n //刷新一次表格\r\n conditionformat.ref(historyRules, currentRules);\r\n\r\n //发送给后台\r\n if(server.allowUpdate){\r\n server.saveParam(\"all\", file.index, ruleArr, { \"k\": \"luckysheet_conditionformat_save\" });\r\n }\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return cdformatItem;\r\n}\r\n\r\n\r\n/**\r\n * 清除指定工作表指定单元格区域的内容,不同于删除选区的功能,不需要设定单元格移动情况\r\n * @param {Object} options 可选参数\r\n * @param {Array | Object | String} options.range 要清除的选区范围\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function clearRange(options = {}) {\r\n let {\r\n range = Store.luckysheet_select_save,\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = [{\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n }]\r\n }\r\n else if(getObjType(range) == 'object'){\r\n if(range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n range = [{\r\n \"row\": range.row,\r\n \"column\": range.column\r\n }];\r\n }\r\n\r\n if(getObjType(range) != 'array'){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let cfg = $.extend(true, {}, file.config);\r\n let has_PartMC = false;\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0],\r\n r2 = range[s].row[1];\r\n let c1 = range[s].column[0],\r\n c2 = range[s].column[1];\r\n\r\n has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n break;\r\n }\r\n }\r\n\r\n if(has_PartMC){\r\n return tooltip.info('Cannot perform this operation on partially merged cells', '');\r\n }\r\n\r\n let d = $.extend(true, [], file.data);\r\n\r\n if(d.length == 0){\r\n d = $.extend(true, [], sheetmanage.buildGridData(file));\r\n }\r\n\r\n for(let s = 0; s < range.length; s++){\r\n let r1 = range[s].row[0],\r\n r2 = range[s].row[1];\r\n let c1 = range[s].column[0],\r\n c2 = range[s].column[1];\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\"){\r\n delete cell[\"m\"];\r\n delete cell[\"v\"];\r\n\r\n if(cell[\"f\"] != null){\r\n delete cell[\"f\"];\r\n formula.delFunctionGroup(r, c, file.index);\r\n\r\n delete cell[\"spl\"];\r\n }\r\n\r\n if(cell[\"ct\"] != null && cell[\"ct\"].t == 'inlineStr'){\r\n delete cell[\"ct\"];\r\n }\r\n }\r\n else{\r\n d[r][c] = null;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n jfrefreshgrid(d, range);\r\n }\r\n else{\r\n file.data = d;\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 删除指定工作表指定单元格区域,返回删除掉的数据,同时,指定是右侧单元格左移还是下方单元格上移\r\n * @param {String} move 删除后,单元格左移/上移\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 要删除的选区范围\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteRange(move, options = {}) {\r\n let moveList = ['left', 'up'];\r\n\r\n if(!moveList.includes(move)){\r\n return tooltip.info(\"The move parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = {\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n };\r\n }\r\n\r\n if(getObjType(range) != 'object' || range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let str = range.row[0],\r\n edr = range.row[1],\r\n stc = range.column[0],\r\n edc = range.column[1];\r\n\r\n if(move == 'left'){\r\n luckysheetDeleteCell('moveLeft', str, edr, stc, edc, order);\r\n }\r\n else if(move == 'up'){\r\n luckysheetDeleteCell('moveUp', str, edr, stc, edc, order);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 指定工作表指定单元格区域的数据进行矩阵操作,返回操作成功后的结果数据\r\n * @param {String} type 矩阵操作的类型\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function matrixOperation(type, options = {}) {\r\n let typeValues = [\r\n 'flipUpDown', // 上下翻转\r\n 'flipLeftRight', // 左右翻转\r\n 'flipClockwise', // 顺时针旋转\r\n 'flipCounterClockwise', // 逆时针旋转\r\n 'transpose', // 转置\r\n 'deleteZeroByRow', // 按行删除两端0值\r\n 'deleteZeroByColumn', // 按列删除两端0值\r\n 'removeDuplicateByRow', // 按行删除重复值\r\n 'removeDuplicateByColumn', // 按列删除重复值\r\n 'newMatrix' // 生产新矩阵\r\n ]\r\n\r\n if (!type || typeValues.indexOf(type) < 0) {\r\n return tooltip.info('The type parameter is invalid.', '')\r\n }\r\n\r\n let curRange = Store.luckysheet_select_save[0];\r\n let {\r\n range = curRange,\r\n success\r\n } = {...options}\r\n\r\n if(range instanceof Array && range.length > 1){\r\n tooltip.info(locale().drag.noMulti, \"\");\r\n return;\r\n }\r\n\r\n if (range && typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n let getdata = getdatabyselection(range);\r\n let arr = [];\r\n if (getdata.length === 0) {\r\n return;\r\n }\r\n\r\n let getdatalen, collen, arr1;\r\n switch (type) {\r\n case 'flipUpDown':\r\n for (let r = getdata.length - 1; r >= 0; r--) {\r\n let a = [];\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n }\r\n a.push(value);\r\n }\r\n arr.push(a);\r\n }\r\n break;\r\n case 'flipLeftRight':\r\n for (let r = 0; r < getdata.length; r++) {\r\n let a = [];\r\n for (let c = getdata[0].length - 1; c >= 0; c--) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n }\r\n a.push(value);\r\n }\r\n arr.push(a);\r\n }\r\n break;\r\n case 'flipClockwise':\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n let a = [];\r\n for (let r = getdata.length - 1; r >= 0; r--) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n }\r\n a.push(value);\r\n }\r\n arr.push(a);\r\n }\r\n break;\r\n case 'flipCounterClockwise':\r\n for (let c = getdata[0].length - 1; c >= 0; c--) {\r\n let a = [];\r\n for (let r = 0; r < getdata.length; r++) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n }\r\n a.push(value);\r\n }\r\n arr.push(a);\r\n }\r\n break;\r\n case 'transpose':\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n let a = [];\r\n for (let r = 0; r < getdata.length; r++) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n }\r\n a.push(value);\r\n }\r\n arr.push(a);\r\n }\r\n break;\r\n case 'deleteZeroByRow':\r\n getdatalen = getdata[0].length;\r\n for (let r = 0; r < getdata.length; r++) {\r\n let a = [], stdel = true, eddel = true;\r\n for (let c = 0; c < getdatalen; c++) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n if ((value.v == \"0\" || value.v == 0) && stdel) {\r\n continue;\r\n }\r\n else {\r\n stdel = false;\r\n }\r\n }\r\n a.push(value);\r\n }\r\n\r\n let a1 = [];\r\n if (a.length == getdatalen) {\r\n a1 = a;\r\n } else {\r\n for (let c = a.length - 1; c >= 0; c--) {\r\n let value = \"\";\r\n if (a[c] != null) {\r\n value = a[c];\r\n if ((value.v == \"0\" || value.v == 0) && eddel) {\r\n continue;\r\n }\r\n else {\r\n eddel = false;\r\n }\r\n }\r\n a1.unshift(value);\r\n }\r\n\r\n let l = getdatalen - a1.length;\r\n for (let c1 = 0; c1 < l; c1++) {\r\n a1.push(\"\");\r\n }\r\n }\r\n arr.push(a1);\r\n }\r\n break;\r\n case 'deleteZeroByColumn':\r\n getdatalen = getdata.length;\r\n collen = getdata[0].length;\r\n for (let c = 0; c < collen; c++) {\r\n let a = [], stdel = true, eddel = true;\r\n for (let r = 0; r < getdatalen; r++) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n if ((value.v == \"0\" || value.v == 0) && stdel) {\r\n continue;\r\n }\r\n else {\r\n stdel = false;\r\n }\r\n }\r\n a.push(value);\r\n }\r\n\r\n let a1 = [];\r\n if (a.length == getdatalen) {\r\n a1 = a;\r\n }\r\n else {\r\n for (let r = a.length - 1; r >= 0; r--) {\r\n let value = \"\";\r\n if (a[r] != null) {\r\n value = a[r];\r\n if ((value.v == \"0\" || value.v == 0) && eddel) {\r\n continue;\r\n }\r\n else {\r\n eddel = false;\r\n }\r\n }\r\n a1.unshift(value);\r\n }\r\n\r\n let l = getdatalen - a1.length;\r\n for (let r1 = 0; r1 < l; r1++) {\r\n a1.push(\"\");\r\n }\r\n }\r\n arr.push(a1);\r\n }\r\n\r\n arr1 = [];\r\n for (let c = 0; c < arr[0].length; c++) {\r\n let a = [];\r\n for (let r = 0; r < arr.length; r++) {\r\n let value = \"\";\r\n if (arr[r] != null && arr[r][c] != null) {\r\n value = arr[r][c];\r\n }\r\n a.push(value);\r\n }\r\n arr1.push(a);\r\n }\r\n break;\r\n case 'removeDuplicateByRow':\r\n getdatalen = getdata[0].length;\r\n for (let r = 0; r < getdata.length; r++) {\r\n let a = [], repeat = {};\r\n\r\n for (let c = 0; c < getdatalen; c++) {\r\n let value = null;\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n\r\n if(value.v in repeat){\r\n repeat[value.v].push(value);\r\n }\r\n else{\r\n repeat[value.v] = [];\r\n repeat[value.v].push(value);\r\n }\r\n }\r\n }\r\n\r\n for (let c = 0; c < getdatalen; c++) {\r\n let value = null;\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n\r\n if(repeat[value.v].length == 1){\r\n a.push(value);\r\n }\r\n }\r\n }\r\n\r\n let l = getdatalen - a.length;\r\n for (let c1 = 0; c1 < l; c1++) {\r\n a.push(null);\r\n }\r\n arr.push(a);\r\n }\r\n break;\r\n case 'removeDuplicateByColumn':\r\n collen = getdata[0].length;\r\n getdatalen = getdata.length;\r\n for (let c = 0; c < collen; c++) {\r\n let a = [], repeat = {};\r\n\r\n for (let r = 0; r < getdatalen; r++) {\r\n let value = null;\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n\r\n if(value.v in repeat){\r\n repeat[value.v].push(value);\r\n }\r\n else{\r\n repeat[value.v] = [];\r\n repeat[value.v].push(value);\r\n }\r\n }\r\n }\r\n\r\n for (let r = 0; r < getdatalen; r++) {\r\n let value = null;\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n\r\n if(repeat[value.v].length == 1){\r\n a.push(value);\r\n }\r\n }\r\n }\r\n\r\n a1 = a;\r\n let l = getdatalen - a1.length;\r\n for (let r1 = 0; r1 < l; r1++) {\r\n a1.push(null);\r\n }\r\n arr.push(a1);\r\n }\r\n\r\n arr1 = [];\r\n for (let c = 0; c < arr[0].length; c++) {\r\n let a = [];\r\n for (let r = 0; r < arr.length; r++) {\r\n let value = null;\r\n if (arr[r] != null && arr[r][c] != null) {\r\n value = arr[r][c];\r\n }\r\n a.push(value);\r\n }\r\n arr1.push(a);\r\n }\r\n break;\r\n case 'newMatrix':\r\n // TODO\r\n console.log(\"TODO\")\r\n break;\r\n }\r\n editor.controlHandler(arr, range)\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 指定工作表指定单元格区域的数据进行矩阵计算,返回计算成功后的结果数据\r\n * @param {String} type 计算方式\r\n * @param {Number} number 计算数值\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,支持选区的格式为\"A1:B2\"、\"sheetName!A1:B2\"或者{row:[0,1],column:[0,1]},只能为单个选区;默认为当前选区\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function matrixCalculation(type, number, options = {}) {\r\n let typeValues = [\r\n 'plus', // 加\r\n 'minus', // 减\r\n 'multiply', // 乘\r\n 'divided', // 除\r\n 'power', // 幂\r\n 'root', // 次方根\r\n 'log' // 对数log\r\n ]\r\n\r\n if (!type || typeValues.indexOf(type) < 0) {\r\n return tooltip.info('The type parameter is invalid.', '')\r\n }\r\n\r\n if(!isRealNum(number)){\r\n return tooltip.info('The number parameter is invalid.', '')\r\n }\r\n\r\n let curRange = Store.luckysheet_select_save[0];\r\n let {\r\n range = curRange,\r\n success\r\n } = {...options}\r\n\r\n if(range instanceof Array && range.length > 1){\r\n tooltip.info(locale().drag.noMulti, \"\");\r\n return;\r\n }\r\n\r\n if (range && typeof range === 'string' && formula.iscelldata(range)) {\r\n range = formula.getcellrange(range)\r\n }\r\n\r\n let getdata = getdatabyselection(range);\r\n if (getdata.length == 0) {\r\n return;\r\n }\r\n\r\n let arr = [];\r\n for (let r = 0; r < getdata.length; r++) {\r\n let a = [];\r\n for (let c = 0; c < getdata[0].length; c++) {\r\n let value = \"\";\r\n if (getdata[r] != null && getdata[r][c] != null) {\r\n value = getdata[r][c];\r\n if (parseInt(value) != null && getdata[r][c].ct != undefined && getdata[r][c].ct.t == \"n\") {\r\n if (type == \"minus\") {\r\n value.v = value.v - number;\r\n }\r\n else if (type == \"multiply\") {\r\n value.v = value.v * number;\r\n }\r\n else if (type == \"divided\") {\r\n value.v = numFormat(value.v / number, 4);\r\n }\r\n else if (type == \"power\") {\r\n value.v = Math.pow(value.v, number);\r\n }\r\n else if (type == \"root\") {\r\n if (number == 2) {\r\n value.v = numFormat(Math.sqrt(value.v), 4);\r\n }\r\n else if (number == 3 && Math.cbrt) {\r\n value.v = numFormat(Math.cbrt(value.v), 4);\r\n }\r\n else {\r\n value.v = numFormat(jfnqrt(value.v, number), 4);\r\n }\r\n }\r\n else if (type == \"log\") {\r\n value.v = numFormat(Math.log(value.v) * 10000 / Math.log(Math.abs(number)), 4);\r\n }\r\n else {\r\n value.v = value.v + number;\r\n }\r\n\r\n if(value.v == null){\r\n value.m = \"\";\r\n }\r\n else{\r\n value.m = value.v.toString();\r\n }\r\n }\r\n }\r\n a.push(value);\r\n }\r\n arr.push(a);\r\n }\r\n\r\n editor.controlHandler(arr, range);\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 新增一个sheet,返回新增的工作表对象\r\n * @param {Object} options 可选参数\r\n * @param {Object} options.sheetObject 新增的工作表的数据;默认值为空对象\r\n * @param {Number} options.order 新增的工作表索引;默认值为最后一个索引位置\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetAdd(options = {}) {\r\n let lastOrder = Store.luckysheetfile.length - 1;\r\n let {\r\n sheetObject = {},\r\n order = lastOrder,\r\n success\r\n } = {...options}\r\n\r\n if(!isRealNum(order)){\r\n return tooltip.info(\"Parameter is not a table index\", \"\");\r\n }\r\n\r\n order = Number(order);\r\n\r\n let index = sheetmanage.generateRandomSheetIndex();\r\n // calcChain公式链里的index也要跟着变化\r\n if (sheetObject.calcChain && sheetObject.calcChain.length > 0) {\r\n sheetObject.calcChain.forEach((item) => {\r\n item.index = index\r\n })\r\n }\r\n let sheetname = sheetmanage.generateRandomSheetName(Store.luckysheetfile, false);\r\n if(!!sheetObject.name){\r\n let sameName = false;\r\n\r\n for(let i = 0; i < Store.luckysheetfile.length; i++){\r\n if(Store.luckysheetfile[i].name == sheetObject.name){\r\n sameName = true;\r\n break;\r\n }\r\n }\r\n\r\n if(!sameName){\r\n sheetname = sheetObject.name;\r\n }\r\n }\r\n\r\n $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, {\r\n \"index\": index,\r\n \"active\": \"\",\r\n \"name\": sheetname,\r\n \"style\": \"\",\r\n \"colorset\": \"\"\r\n }));\r\n\r\n let sheetconfig = {\r\n \"name\": \"\",\r\n \"color\": \"\",\r\n \"status\": \"0\",\r\n \"order\": \"\",\r\n \"index\": \"\",\r\n \"celldata\": [],\r\n \"row\": Store.defaultrowNum,\r\n \"column\": Store.defaultcolumnNum,\r\n \"config\": {},\r\n \"pivotTable\": null,\r\n \"isPivotTable\": false\r\n };\r\n sheetconfig = $.extend(true, sheetconfig, sheetObject);\r\n\r\n sheetconfig.index = index;\r\n sheetconfig.name = sheetname;\r\n sheetconfig.order = order;\r\n\r\n if(order <= 0){\r\n let beforeIndex = Store.luckysheetfile[0].index;\r\n let beforeObj = $(\"#luckysheet-sheets-item\" + beforeIndex);\r\n $(\"#luckysheet-sheets-item\" + index).insertBefore(beforeObj);\r\n\r\n Store.luckysheetfile.splice(0, 0, sheetconfig);\r\n }\r\n else{\r\n if(order > Store.luckysheetfile.length){\r\n order = Store.luckysheetfile.length;\r\n }\r\n\r\n let afterIndex = Store.luckysheetfile[order - 1].index;\r\n let afterObj = $(\"#luckysheet-sheets-item\" + afterIndex);\r\n $(\"#luckysheet-sheets-item\" + index).insertAfter(afterObj);\r\n\r\n Store.luckysheetfile.splice(order, 0, sheetconfig);\r\n }\r\n\r\n let orders = {};\r\n\r\n Store.luckysheetfile.forEach((item, i, arr) => {\r\n arr[i].order = i;\r\n orders[item.index.toString()] = i;\r\n })\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-sheets-item\" + index).addClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-cell-main\").append('
');\r\n cleargridelement(true);\r\n\r\n server.saveParam(\"sha\", null, $.extend(true, {}, sheetconfig));\r\n server.saveParam(\"shr\", null, orders);\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n let redo = {};\r\n redo[\"type\"] = \"addSheet\";\r\n redo[\"sheetconfig\"] = $.extend(true, {}, sheetconfig);\r\n redo[\"index\"] = index;\r\n redo[\"currentSheetIndex\"] = Store.currentSheetIndex;\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n sheetmanage.changeSheetExec(index, false, true);\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 删除指定下标的工作表,返回已删除的工作表对象\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetDelete(options = {}) {\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n if(Store.luckysheetfile.length === 1){\r\n return tooltip.info(locale().sheetconfig.noMoreSheet, \"\");\r\n }\r\n\r\n sheetmanage.deleteSheet(file.index);\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return file;\r\n}\r\n\r\n\r\n/**\r\n * 复制指定下标的工作表到指定下标位置\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.targetOrder 新复制的工作表目标下标位置;默认值为当前工作表下标的下一个下标位置(递增)\r\n * @param {Number} options.order 被复制的工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetCopy(options = {}) {\r\n let {\r\n targetOrder,\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n if(targetOrder == null){\r\n targetOrder = order + 1;\r\n }\r\n\r\n if(!isRealNum(targetOrder)){\r\n return tooltip.info(\"The targetOrder parameter is invalid.\", \"\");\r\n }\r\n\r\n let copyindex = file.index;\r\n let index = sheetmanage.generateRandomSheetIndex();\r\n\r\n let copyjson = $.extend(true, {}, file);\r\n copyjson.order = Store.luckysheetfile.length;\r\n copyjson.index = index;\r\n copyjson.name = sheetmanage.generateCopySheetName(Store.luckysheetfile, copyjson.name);\r\n\r\n let colorset = '';\r\n if(copyjson.color != null){\r\n colorset = '
';\r\n }\r\n\r\n let afterObj = $(\"#luckysheet-sheets-item\" + copyindex);\r\n if(isRealNum(targetOrder)){\r\n afterObj = $(\"#luckysheet-sheets-item\" + Store.luckysheetfile[targetOrder - 1].index);\r\n }\r\n\r\n $(\"#luckysheet-sheet-container-c\").append(replaceHtml(sheetHTML, {\r\n \"index\": copyjson.index,\r\n \"active\": \"\",\r\n \"name\": copyjson.name,\r\n \"order\": copyjson.order,\r\n \"style\": \"\",\r\n \"colorset\": colorset\r\n }));\r\n $(\"#luckysheet-sheets-item\" + copyjson.index).insertAfter(afterObj);\r\n Store.luckysheetfile.splice(targetOrder, 0, copyjson);\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-sheets-item\" + index).addClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-cell-main\").append('
');\r\n cleargridelement(true);\r\n\r\n server.saveParam(\"shc\", index, { \"copyindex\": copyindex, \"name\": copyjson.name });\r\n\r\n sheetmanage.changeSheetExec(index);\r\n sheetmanage.reOrderAllSheet();\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfredo.push({\r\n \"type\": \"copySheet\",\r\n \"copyindex\": copyindex,\r\n \"index\": copyjson.index,\r\n \"sheetIndex\": copyjson.index\r\n });\r\n }\r\n else if (Store.jfredo.length > 0) {\r\n let jfredostr = Store.jfredo[Store.jfredo.length - 1];\r\n\r\n if (jfredostr.type == \"copySheet\") {\r\n jfredostr.index = copyjson.index;\r\n jfredostr.sheetIndex = copyjson.index;\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return copyjson;\r\n}\r\n\r\n\r\n/**\r\n * 隐藏指定下标的工作表,返回被隐藏的工作表对象\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetHide(options = {}) {\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n sheetmanage.setSheetHide(file.index);\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return file;\r\n}\r\n\r\n\r\n/**\r\n * 取消隐藏指定下标的工作表,返回被取消隐藏的工作表对象\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetShow(options = {}) {\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n sheetmanage.setSheetShow(file.index);\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return file;\r\n}\r\n\r\n\r\n/**\r\n * 设置指定下标的工作表为当前工作表(激活态),即切换到指定的工作表,返回被激活的工作表对象\r\n * @param {Number} order 要激活的工作表下标\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetActive(order, options = {}) {\r\n if(order == null || !isRealNum(order) || Store.luckysheetfile[order] == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n $(\"#luckysheet-sheet-area div.luckysheet-sheets-item\").removeClass(\"luckysheet-sheets-item-active\");\r\n $(\"#luckysheet-sheets-item\" + file.index).addClass(\"luckysheet-sheets-item-active\");\r\n\r\n sheetmanage.changeSheet(file.index);\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n server.multipleRangeShow()\r\n return file;\r\n}\r\n\r\n\r\n/**\r\n * 修改工作表名称\r\n * @param {String} name 工作表名称\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetName(name, options = {}) {\r\n if(getObjType(name) != 'string' || name.toString().length == 0){\r\n return tooltip.info(\"The name parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let oldtxt = file.name;\r\n file.name = name;\r\n\r\n $(\"#luckysheet-sheets-item\" + file.index + \" .luckysheet-sheets-item-name\").text(name);\r\n\r\n server.saveParam(\"all\", file.index, name, { \"k\": \"name\" });\r\n\r\n if (Store.clearjfundo) {\r\n let redo = {};\r\n redo[\"type\"] = \"sheetName\";\r\n redo[\"sheetIndex\"] = file.index;\r\n\r\n redo[\"oldtxt\"] = oldtxt;\r\n redo[\"txt\"] = name;\r\n\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 设置工作表名称处的颜色\r\n * @param {String} color 工作表颜色\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetColor(color, options = {}) {\r\n if(getObjType(color) != 'string' || color.toString().length == 0){\r\n return tooltip.info(\"The color parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let oldcolor = file.color;\r\n file.color = color;\r\n\r\n $(\"#luckysheet-sheets-item\" + file.index).find(\".luckysheet-sheets-item-color\").remove();\r\n $(\"#luckysheet-sheets-item\" + file.index).append('
');\r\n\r\n server.saveParam(\"all\", file.index, color, { \"k\": \"color\" });\r\n\r\n if (Store.clearjfundo) {\r\n let redo = {};\r\n redo[\"type\"] = \"sheetColor\";\r\n redo[\"sheetIndex\"] = file.index;\r\n\r\n redo[\"oldcolor\"] = oldcolor;\r\n redo[\"color\"] = color;\r\n\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 指定工作表向左边或右边移动一个位置,或者指定索引,返回指定的工作表对象\r\n * @param {String | Number} type 工作表移动方向或者移动的目标索引\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表索引;默认值为当前工作表索引\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetMove(type, options = {}) {\r\n if(type != 'left' && type != 'right' && !isRealNum(type)){\r\n return tooltip.info(\"Type parameter not available\", \"\");\r\n }\r\n\r\n if(isRealNum(type)){\r\n type = parseInt(type);\r\n }\r\n\r\n let curOrder = getSheetIndex(Store.currentSheetIndex);\r\n let {\r\n order = curOrder,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"ncorrect worksheet index\", \"\");\r\n }\r\n\r\n let sheetIndex = file.index;\r\n\r\n if(type == 'left'){\r\n if(order == 0){\r\n return;\r\n }\r\n\r\n let prevIndex = Store.luckysheetfile[order - 1].index;\r\n $(\"#luckysheet-sheets-item\" + sheetIndex).insertBefore($(\"#luckysheet-sheets-item\" + prevIndex));\r\n\r\n Store.luckysheetfile.splice(order, 1);\r\n Store.luckysheetfile.splice(order - 1, 0, file);\r\n }\r\n else if(type == 'right'){\r\n if(order == Store.luckysheetfile.length - 1){\r\n return;\r\n }\r\n\r\n let nextIndex = Store.luckysheetfile[order + 1].index;\r\n $(\"#luckysheet-sheets-item\" + sheetIndex).insertAfter($(\"#luckysheet-sheets-item\" + nextIndex));\r\n\r\n Store.luckysheetfile.splice(order, 1);\r\n Store.luckysheetfile.splice(order + 1, 0, file);\r\n }\r\n else{\r\n if(type < 0){\r\n type = 0;\r\n }\r\n\r\n if(type > Store.luckysheetfile.length - 1){\r\n type = Store.luckysheetfile.length - 1;\r\n }\r\n\r\n if(type == order){\r\n return;\r\n }\r\n\r\n if(type < order){\r\n let prevIndex = Store.luckysheetfile[type].index;\r\n $(\"#luckysheet-sheets-item\" + sheetIndex).insertBefore($(\"#luckysheet-sheets-item\" + prevIndex));\r\n }\r\n else{\r\n let nextIndex = Store.luckysheetfile[type].index;\r\n $(\"#luckysheet-sheets-item\" + sheetIndex).insertAfter($(\"#luckysheet-sheets-item\" + nextIndex));\r\n }\r\n\r\n Store.luckysheetfile.splice(order, 1);\r\n Store.luckysheetfile.splice(type, 0, file);\r\n }\r\n\r\n let orders = {};\r\n\r\n Store.luckysheetfile.forEach((item, i, arr) => {\r\n arr[i].order = i;\r\n orders[item.index.toString()] = i;\r\n })\r\n\r\n server.saveParam(\"shr\", null, orders);\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 重新排序所有工作表的位置,指定工作表顺序的数组。\r\n * @param {Array} orderList 工作表顺序,设置工作表的index和order来指定位置\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetOrder(orderList, options = {}) {\r\n if(orderList == null || orderList.length == 0){\r\n return tooltip.info(\"Type orderList not available\", \"\");\r\n }\r\n\r\n let orderListMap = {};\r\n orderList.forEach((item) => {\r\n orderListMap[item.index.toString()] = item.order;\r\n })\r\n\r\n Store.luckysheetfile.sort((x, y) => {\r\n let order_x = orderListMap[x.index.toString()];\r\n let order_y = orderListMap[y.index.toString()];\r\n\r\n if(order_x != null && order_y != null){\r\n return order_x - order_y;\r\n }\r\n else if(order_x != null){\r\n return -1;\r\n }\r\n else if(order_y != null){\r\n return 1;\r\n }\r\n else{\r\n return 1;\r\n }\r\n })\r\n\r\n let orders = {};\r\n\r\n Store.luckysheetfile.forEach((item, i, arr) => {\r\n arr[i].order = i;\r\n orders[item.index.toString()] = i;\r\n\r\n if(i > 0){\r\n let preIndex = arr[i - 1].index;\r\n $(\"#luckysheet-sheets-item\" + item.index).insertAfter($(\"#luckysheet-sheets-item\" + preIndex));\r\n }\r\n })\r\n\r\n server.saveParam(\"shr\", null, orders);\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 设置工作表缩放比例\r\n * @param {Number} zoom 工作表缩放比例,值范围为0.1 ~ 4;\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setSheetZoom(zoom, options = {}) {\r\n if(!isRealNum(zoom) || zoom < 0.1 || zoom > 4){\r\n return tooltip.info(\"The zoom parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n file[\"zoomRatio\"] = zoom;\r\n\r\n server.saveParam(\"all\", file.index, zoom, { \"k\": \"zoomRatio\" });\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n Store.zoomRatio = zoom;\r\n\r\n zoomNumberDomBind();\r\n zoomRefreshView();\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 显示指定下标工作表的网格线,返回操作的工作表对象\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 需要显示网格线的工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function showGridLines(options = {}){\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n file.showGridLines = true;\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n Store.showGridLines = true;\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return file;\r\n}\r\n\r\n\r\n/**\r\n * 隐藏指定下标工作表的网格线,返回操作的工作表对象\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 需要显示网格线的工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function hideGridLines(options = {}){\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n file.showGridLines = false;\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n Store.showGridLines = false;\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return file;\r\n}\r\n\r\n\r\n/**\r\n * 刷新canvas\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function refresh(options = {}) {\r\n // luckysheetrefreshgrid();\r\n jfrefreshgrid();\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 滚动当前工作表位置\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.scrollLeft 横向滚动值\r\n * @param {Number} options.scrollTop 纵向滚动值\r\n * @param {Number} options.targetRow 纵向滚动到指定的行号\r\n * @param {Number} options.targetColumn 横向滚动到指定的列号\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function scroll(options = {}){\r\n let {\r\n scrollLeft,\r\n scrollTop,\r\n targetRow,\r\n targetColumn,\r\n success\r\n } = {...options}\r\n\r\n if(scrollLeft != null){\r\n if(!isRealNum(scrollLeft)){\r\n return tooltip.info(\"The scrollLeft parameter is invalid.\", \"\");\r\n }\r\n\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(scrollLeft);\r\n }\r\n else if(targetColumn != null){\r\n if(!isRealNum(targetColumn)){\r\n return tooltip.info(\"The targetColumn parameter is invalid.\", \"\");\r\n }\r\n\r\n let col = Store.visibledatacolumn[targetColumn],\r\n col_pre = targetColumn <= 0 ? 0 : Store.visibledatacolumn[targetColumn - 1];\r\n\r\n $(\"#luckysheet-scrollbar-x\").scrollLeft(col_pre);\r\n }\r\n\r\n\r\n if(scrollTop != null){\r\n if(!isRealNum(scrollTop)){\r\n return tooltip.info(\"The scrollTop parameter is invalid.\", \"\");\r\n }\r\n\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(scrollTop);\r\n }\r\n else if(targetRow != null){\r\n if(!isRealNum(targetRow)){\r\n return tooltip.info(\"The targetRow parameter is invalid.\", \"\");\r\n }\r\n\r\n let row = Store.visibledatarow[targetRow],\r\n row_pre = targetRow <= 0 ? 0 : Store.visibledatarow[targetRow - 1];\r\n\r\n $(\"#luckysheet-scrollbar-y\").scrollTop(row_pre);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 根据窗口大小自动resize画布\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function resize(options = {}){\r\n luckysheetsizeauto();\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 返回指定选区截图后生成的base64格式的图片\r\n * @param {Object} options 可选参数\r\n * @param {Object | String} options.range 选区范围,只能为单个选区;默认为当前选区\r\n */\r\nexport function getScreenshot(options = {}) {\r\n let {\r\n range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],\r\n } = {...options}\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = {\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n };\r\n }\r\n\r\n if(getObjType(range) != 'object' || range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let str = range.row[0],\r\n edr = range.row[1],\r\n stc = range.column[0],\r\n edc = range.column[1];\r\n\r\n let has_PartMC = hasPartMC(Store.config, str, edr, stc, edc);\r\n\r\n if(has_PartMC){\r\n return tooltip.info('Cannot perform this operation on partially merged cells', '');\r\n }\r\n\r\n let visibledatarow = Store.visibledatarow;\r\n let visibledatacolumn = Store.visibledatacolumn;\r\n\r\n let scrollHeight, rh_height;\r\n if (str - 1 < 0) {\r\n scrollHeight = 0;\r\n rh_height = visibledatarow[edr];\r\n }\r\n else {\r\n scrollHeight = visibledatarow[str - 1];\r\n rh_height = visibledatarow[edr] - visibledatarow[str - 1];\r\n }\r\n\r\n let scrollWidth, ch_width;\r\n if (stc - 1 < 0) {\r\n scrollWidth = 0;\r\n ch_width = visibledatacolumn[edc];\r\n }\r\n else {\r\n scrollWidth = visibledatacolumn[stc - 1];\r\n ch_width = visibledatacolumn[edc] - visibledatacolumn[stc - 1];\r\n }\r\n\r\n let newCanvas = $(\"\").attr({\r\n width: Math.ceil(ch_width * Store.devicePixelRatio),\r\n height: Math.ceil(rh_height * Store.devicePixelRatio)\r\n }).css({ width: ch_width, height: rh_height });\r\n\r\n luckysheetDrawMain(scrollWidth, scrollHeight, ch_width, rh_height, 1, 1, null, null, newCanvas);\r\n let ctx_newCanvas = newCanvas.get(0).getContext(\"2d\");\r\n\r\n //补上 左边框和上边框\r\n ctx_newCanvas.beginPath();\r\n ctx_newCanvas.moveTo(\r\n 0,\r\n 0\r\n );\r\n ctx_newCanvas.lineTo(\r\n 0,\r\n Store.devicePixelRatio * rh_height\r\n );\r\n ctx_newCanvas.lineWidth = Store.devicePixelRatio * 2;\r\n ctx_newCanvas.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n ctx_newCanvas.stroke();\r\n ctx_newCanvas.closePath();\r\n\r\n ctx_newCanvas.beginPath();\r\n ctx_newCanvas.moveTo(\r\n 0,\r\n 0\r\n );\r\n ctx_newCanvas.lineTo(\r\n Store.devicePixelRatio * ch_width,\r\n 0\r\n );\r\n ctx_newCanvas.lineWidth = Store.devicePixelRatio * 2;\r\n ctx_newCanvas.strokeStyle = luckysheetdefaultstyle.strokeStyle;\r\n ctx_newCanvas.stroke();\r\n ctx_newCanvas.closePath();\r\n\r\n let url = newCanvas.get(0).toDataURL(\"image/png\");\r\n\r\n return url;\r\n}\r\n\r\n\r\n/**\r\n * 设置工作簿名称\r\n * @param {String} name 工作簿名称\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setWorkbookName(name, options = {}) {\r\n if(name == null || name.toString().length == 0){\r\n return tooltip.info(\"The name parameter is invalid.\", \"\");\r\n }\r\n\r\n $(\"#luckysheet_info_detail_input\").val(name);\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 获取工作簿名称\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n * @returns {String} 返回工作簿名称,如果读取失败则返回空字符串并弹窗提示\r\n */\r\nexport function getWorkbookName(options = {}) {\r\n\r\n let name = \"\";\r\n let element = $(\"#luckysheet_info_detail_input\");\r\n\r\n if(element.length == 0){\r\n\r\n tooltip.info('Failed to get workbook name, label loading failed!');\r\n return name;\r\n\r\n }\r\n\r\n name = $.trim(element.val());\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success()\r\n }\r\n }, 1)\r\n\r\n return name;\r\n}\r\n\r\n\r\n/**\r\n * 撤销当前操作,返回刚刚撤销的操作对象\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function undo(options = {}) {\r\n let ctr = $.extend(true, {}, Store.jfredo[Store.jfredo.length - 1]);\r\n\r\n controlHistory.redo(new Event('custom'));\r\n luckysheetactiveCell();\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return ctr;\r\n}\r\n\r\n\r\n/**\r\n * 重做当前操作,返回刚刚重做的操作对象\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function redo(options = {}) {\r\n let ctr = $.extend(true, {}, Store.jfundo[Store.jfundo.length - 1]);\r\n\r\n controlHistory.undo(new Event('custom'));\r\n luckysheetactiveCell();\r\n\r\n let {\r\n success\r\n } = {...options}\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1);\r\n\r\n return ctr;\r\n}\r\n\r\n\r\n/**\r\n * 返回所有工作表配置\r\n */\r\nexport function getAllSheets() {\r\n let data = $.extend(true, [], Store.luckysheetfile);\r\n\r\n data.forEach((item, index, arr) => {\r\n if(item.data != null && item.data.length > 0){\r\n item.celldata = sheetmanage.getGridData(item.data);\r\n }\r\n\r\n delete item.load;\r\n delete item.freezen;\r\n\r\n })\r\n\r\n return data;\r\n}\r\n\r\n\r\n/**\r\n * 根据index获取sheet页配置\r\n *\r\n * @param {Object} options 可选参数\r\n * @param {String} options.index 工作表index\r\n * @param {Number} options.order 工作表order\r\n * @param {String} options.name 工作表name\r\n */\r\nexport function getSheet(options = {}){\r\n\r\n let {\r\n index,\r\n order,\r\n name\r\n } = {...options};\r\n\r\n if(index != null){\r\n return sheetmanage.getSheetByIndex(index);\r\n }else if(order != null){\r\n return Store.luckysheetfile[order];\r\n }else if(name != null){\r\n return sheetmanage.getSheetByName(name);\r\n }\r\n\r\n return sheetmanage.getSheetByIndex();\r\n\r\n}\r\n\r\n/**\r\n * 快捷返回指定工作表的数据\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n */\r\nexport function getSheetData(options = {}) {\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex)\r\n } = {...options};\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let data = $.extend(true, [], file.data);\r\n\r\n if(data == null || data.length == 0){\r\n data = $.extend(true, [], sheetmanage.buildGridData(file));\r\n }\r\n\r\n return data;\r\n}\r\n\r\n/**\r\n * 快捷返回指定工作表的config配置\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n */\r\nexport function getConfig(options = {}) {\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex)\r\n } = {...options};\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let config = $.extend(true, {}, file.config);\r\n\r\n return config;\r\n}\r\n\r\n/**\r\n * 快捷设置指定工作表config配置\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setConfig(cfg, options = {}) {\r\n if(getObjType(cfg) != 'object'){\r\n return tooltip.info(\"The cfg parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options};\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n file.config = cfg;\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n Store.config = cfg;\r\n\r\n if(\"rowhidden\" in cfg || \"colhidden\" in cfg || \"rowlen\" in cfg || \"columnlen\" in cfg){\r\n jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);\r\n }\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n/**\r\n * 返回所有表格数据结构的一维数组luckysheetfile\r\n */\r\nexport function getLuckysheetfile(){\r\n return getluckysheetfile();\r\n}\r\n\r\n\r\n/**\r\n * 指定工作表范围设置数据验证功能,并设置参数\r\n * @param {Object} optionItem 数据验证的配置信息\r\n * @param {String} optionItem.type 类型\r\n * @param {String | Null} optionItem.type2 条件类型\r\n * @param {String | Number} optionItem.value1 条件值1\r\n * @param {String | Number} optionItem.value2 条件值2\r\n * @param {Boolean} optionItem.checked 选中状态\r\n * @param {Boolean} optionItem.remote 自动远程获取选项\r\n * @param {Boolean} optionItem.prohibitInput 输入数据无效时禁止输入\r\n * @param {Boolean} optionItem.hintShow 选中单元格时显示提示语\r\n * @param {String} optionItem.hintText 提示语文本\r\n * @param {Object} options 可选参数\r\n * @param {Array | Object | String} options.range 选区范围;默认为当前选区\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function setDataVerification(optionItem, options = {}) {\r\n if(getObjType(optionItem) != 'object'){\r\n return tooltip.info(\"The optionItem parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n type,\r\n type2 = null,\r\n value1 = '',\r\n value2 = '',\r\n remote = false,\r\n prohibitInput = false,\r\n hintShow = false,\r\n hintText = '',\r\n checked = false\r\n } = {...optionItem}\r\n\r\n let typeValues = [\"dropdown\", \"checkbox\", \"number\", \"number_integer\", \"number_decimal\", \"text_content\", \"text_length\", \"date\", \"validity\"];\r\n let type2Values_1 = [\"bw\", \"nb\", \"eq\", \"ne\", \"gt\", \"lt\", \"gte\", \"lte\"];\r\n let type2Values_2 = [\"include\", \"exclude\", \"equal\"];\r\n let type2Values_3 = [\"bw\", \"nb\", \"eq\", \"ne\", \"bf\", \"nbf\", \"af\", \"naf\"];\r\n let type2Values_4 = [\"card\", \"phone\"];\r\n\r\n if(!typeValues.includes(type)){\r\n return tooltip.info(\"The optionItem.type parameter is invalid.\", \"\");\r\n }\r\n\r\n let dvText = locale().dataVerification;\r\n\r\n if(type == 'dropdown'){\r\n if(value1.length == 0){\r\n tooltip.info('', dvText.tooltipInfo1);\r\n return;\r\n }\r\n }\r\n else if(type == 'checkbox'){\r\n if(value1.length == 0 || value2.length == 0){\r\n tooltip.info('', dvText.tooltipInfo2);\r\n return;\r\n }\r\n }\r\n else if(type == 'number' || type == 'number_integer' || type == 'number_decimal'){\r\n if(!type2Values_1.includes(type2)){\r\n return tooltip.info(\"The optionItem.type2 parameter is invalid.\", \"\");\r\n }\r\n\r\n if(!isRealNum(value1)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(type2 == 'bw' || type2 == 'nb'){\r\n if(!isRealNum(value2)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(Number(value2) < Number(value1)){\r\n tooltip.info('', dvText.tooltipInfo4);\r\n return;\r\n }\r\n }\r\n }\r\n else if(type == 'text_content'){\r\n if(!type2Values_2.includes(type2)){\r\n return tooltip.info(\"The optionItem.type2 parameter is invalid.\", \"\");\r\n }\r\n\r\n if(value1.length == 0){\r\n tooltip.info('', dvText.tooltipInfo5);\r\n return;\r\n }\r\n }\r\n else if(type == 'text_length'){\r\n if(!type2Values_1.includes(type2)){\r\n return tooltip.info(\"The optionItem.type2 parameter is invalid.\", \"\");\r\n }\r\n\r\n if(!isRealNum(value1)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(type2 == 'bw' || type2 == 'nb'){\r\n if(!isRealNum(value2)){\r\n tooltip.info('', dvText.tooltipInfo3);\r\n return;\r\n }\r\n\r\n if(Number(value2) < Number(value1)){\r\n tooltip.info('', dvText.tooltipInfo4);\r\n return;\r\n }\r\n }\r\n }\r\n else if(type == 'date'){\r\n if(!type2Values_3.includes(type2)){\r\n return tooltip.info(\"The optionItem.type2 parameter is invalid.\", \"\");\r\n }\r\n\r\n if(!isdatetime(value1)){\r\n tooltip.info('', dvText.tooltipInfo6);\r\n return;\r\n }\r\n\r\n if(type2 == 'bw' || type2 == 'nb'){\r\n if(!isdatetime(value2)){\r\n tooltip.info('', dvText.tooltipInfo6);\r\n return;\r\n }\r\n\r\n if(diff(value1, value2) > 0){\r\n tooltip.info('', dvText.tooltipInfo7);\r\n return;\r\n }\r\n }\r\n }\r\n else if(type == 'validity'){\r\n if(!type2Values_4.includes(type2)){\r\n return tooltip.info(\"The optionItem.type2 parameter is invalid.\", \"\");\r\n }\r\n }\r\n\r\n if(getObjType(remote) != 'boolean'){\r\n return tooltip.info(\"The optionItem.remote parameter is invalid.\", \"\");\r\n }\r\n\r\n if(getObjType(prohibitInput) != 'boolean'){\r\n return tooltip.info(\"The optionItem.prohibitInput parameter is invalid.\", \"\");\r\n }\r\n\r\n if(getObjType(hintShow) != 'boolean'){\r\n return tooltip.info(\"The optionItem.hintShow parameter is invalid.\", \"\");\r\n }\r\n\r\n let {\r\n range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = {\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n };\r\n }\r\n\r\n if(getObjType(range) != 'object' || range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let item = {\r\n type: type,\r\n type2: type2,\r\n value1: value1,\r\n value2: value2,\r\n checked: checked,\r\n remote: remote,\r\n prohibitInput: prohibitInput,\r\n hintShow: hintShow,\r\n hintText: hintText,\r\n }\r\n\r\n let currentDataVerification = $.extend(true, {}, file.dataVerification);\r\n\r\n let data = $.extend(true, [], file.data);\r\n if(data.length == 0){\r\n data = sheetmanage.buildGridData(file);\r\n }\r\n\r\n let str = range.row[0],\r\n edr = range.row[1],\r\n stc = range.column[0],\r\n edc = range.column[1];\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = stc; c <= edc; c++){\r\n currentDataVerification[r + '_' + c] = item;\r\n\r\n if(type == 'checkbox'){\r\n item.checked ? setcellvalue(r, c, data, item.value1) : setcellvalue(r, c, data, item.value2);\r\n }\r\n }\r\n }\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n let historyDataVerification = $.extend(true, {}, file.dataVerification);\r\n\r\n if(type == 'checkbox'){\r\n dataVerificationCtrl.refOfCheckbox(historyDataVerification, currentDataVerification, Store.currentSheetIndex, data, range);\r\n }\r\n else{\r\n dataVerificationCtrl.ref(historyDataVerification, currentDataVerification, Store.currentSheetIndex);\r\n }\r\n }\r\n else{\r\n file.dataVerification = currentDataVerification;\r\n file.data = data;\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 指定工作表范围删除数据验证功能\r\n * @param {Object} options 可选参数\r\n * @param {Array | Object | String} options.range 选区范围;默认为当前选区\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteDataVerification(options = {}) {\r\n let {\r\n range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n if(getObjType(range) == 'string'){\r\n if(!formula.iscelldata(range)){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let cellrange = formula.getcellrange(range);\r\n range = {\r\n \"row\": cellrange.row,\r\n \"column\": cellrange.column\r\n };\r\n }\r\n\r\n if(getObjType(range) != 'object' || range.row == null || range.column == null){\r\n return tooltip.info(\"The range parameter is invalid.\", \"\");\r\n }\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let currentDataVerification = $.extend(true, {}, file.dataVerification);\r\n\r\n let str = range.row[0],\r\n edr = range.row[1],\r\n stc = range.column[0],\r\n edc = range.column[1];\r\n\r\n for(let r = str; r <= edr; r++){\r\n for(let c = stc; c <= edc; c++){\r\n delete currentDataVerification[r + '_' + c];\r\n }\r\n }\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n let historyDataVerification = $.extend(true, {}, file.dataVerification);\r\n dataVerificationCtrl.ref(historyDataVerification, currentDataVerification, Store.currentSheetIndex);\r\n }\r\n else{\r\n file.dataVerification = currentDataVerification;\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 在指定的工作表中指定单元格位置插入图片\r\n * @param {String} src 图片src\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Number} options.rowIndex 要插入图片的单元格行下标;默认为0\r\n * @param {Number} options.colIndex 要插入图片的单元格列下标;默认为0\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function insertImage(src, options = {}){\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n rowIndex,\r\n colIndex,\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n\r\n if(rowIndex == null){\r\n rowIndex = last.row_focus || 0;\r\n }\r\n\r\n if(rowIndex < 0){\r\n rowIndex = 0;\r\n }\r\n\r\n if(rowIndex > Store.visibledatarow.length){\r\n rowIndex = Store.visibledatarow.length;\r\n }\r\n\r\n if(colIndex == null){\r\n colIndex = last.column_focus || 0;\r\n }\r\n\r\n if(colIndex < 0){\r\n colIndex = 0;\r\n }\r\n\r\n if(colIndex > Store.visibledatacolumn.length){\r\n colIndex = Store.visibledatacolumn.length;\r\n }\r\n\r\n let left = colIndex == 0 ? 0 : Store.visibledatacolumn[colIndex - 1];\r\n let top = rowIndex == 0 ? 0 : Store.visibledatarow[rowIndex - 1];\r\n\r\n let image = new Image();\r\n image.onload = function(){\r\n let width = image.width,\r\n height = image.height;\r\n\r\n let img = {\r\n src: src,\r\n left: left,\r\n top: top,\r\n originWidth: width,\r\n originHeight: height\r\n }\r\n\r\n imageCtrl.addImgItem(img);\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }\r\n image.src = src;\r\n }\r\n else {\r\n let images = file.images || {};\r\n let config = file.config;\r\n let zoomRatio = file.zoomRatio || 1;\r\n\r\n let rowheight = file.row;\r\n let visibledatarow = file.visibledatarow || [];\r\n if(visibledatarow.length === 0){\r\n let rh_height = 0;\r\n\r\n for (let r = 0; r < rowheight; r++) {\r\n let rowlen = Store.defaultrowlen;\r\n\r\n if (config[\"rowlen\"] != null && config[\"rowlen\"][r] != null) {\r\n rowlen = config[\"rowlen\"][r];\r\n }\r\n\r\n if (config[\"rowhidden\"] != null && config[\"rowhidden\"][r] != null) {\r\n visibledatarow.push(rh_height);\r\n continue;\r\n }\r\n\r\n rh_height += Math.round((rowlen + 1) * zoomRatio);\r\n\r\n visibledatarow.push(rh_height); //行的临时长度分布\r\n }\r\n }\r\n\r\n let colwidth = file.column;\r\n let visibledatacolumn = file.visibledatacolumn || [];\r\n if(visibledatacolumn.length === 0){\r\n let ch_width = 0;\r\n\r\n for (let c = 0; c < colwidth; c++) {\r\n let firstcolumnlen = Store.defaultcollen;\r\n\r\n if (config[\"columnlen\"] != null && config[\"columnlen\"][c] != null) {\r\n firstcolumnlen = config[\"columnlen\"][c];\r\n }\r\n\r\n if(config[\"colhidden\"] != null && config[\"colhidden\"][c] != null){\r\n visibledatacolumn.push(ch_width);\r\n continue;\r\n }\r\n\r\n ch_width += Math.round((firstcolumnlen + 1)*zoomRatio);\r\n\r\n visibledatacolumn.push(ch_width);//列的临时长度分布\r\n }\r\n }\r\n\r\n if(rowIndex == null){\r\n rowIndex = 0;\r\n }\r\n\r\n if(rowIndex < 0){\r\n rowIndex = 0;\r\n }\r\n\r\n if(rowIndex > visibledatarow.length){\r\n rowIndex = visibledatarow.length;\r\n }\r\n\r\n if(colIndex == null){\r\n colIndex = 0;\r\n }\r\n\r\n if(colIndex < 0){\r\n colIndex = 0;\r\n }\r\n\r\n if(colIndex > visibledatacolumn.length){\r\n colIndex = visibledatacolumn.length;\r\n }\r\n\r\n let left = colIndex == 0 ? 0 : visibledatacolumn[colIndex - 1];\r\n let top = rowIndex == 0 ? 0 : visibledatarow[rowIndex - 1];\r\n\r\n let image = new Image();\r\n image.onload = function(){\r\n let img = {\r\n src: src,\r\n left: left,\r\n top: top,\r\n originWidth: image.width,\r\n originHeight: image.height\r\n }\r\n\r\n let width, height;\r\n let max = 400;\r\n\r\n if(img.originHeight < img.originWidth){\r\n height = Math.round(img.originHeight * (max / img.originWidth));\r\n width = max;\r\n }\r\n else{\r\n width = Math.round(img.originWidth * (max / img.originHeight));\r\n height = max;\r\n }\r\n\r\n let imgItem = $.extend(true, {}, imageCtrl.imgItem);\r\n imgItem.src = img.src;\r\n imgItem.originWidth = img.originWidth;\r\n imgItem.originHeight = img.originHeight;\r\n imgItem.default.width = width;\r\n imgItem.default.height = height;\r\n imgItem.default.left = img.left;\r\n imgItem.default.top = img.top;\r\n imgItem.crop.width = width;\r\n imgItem.crop.height = height;\r\n\r\n let id = imageCtrl.generateRandomId();\r\n images[id] = imgItem;\r\n\r\n file.images = images;\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }\r\n image.src = src;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 删除指定工作表中的图片\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {String | Array} options.idList 要删除图片的id集合,也可为字符串`\"all\"`,all为所有的字符串;默认为`\"all\"`\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function deleteImage(options = {}){\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n idList = 'all',\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n let images = file.images;\r\n\r\n if(images == null){\r\n return tooltip.info(\"The worksheet has no pictures to delete.\", \"\");\r\n }\r\n\r\n if(idList != 'all' && getObjType(idList) != 'array'){\r\n return tooltip.info(\"The idList parameter is invalid.\", \"\");\r\n }\r\n\r\n if(getObjType(idList) == 'array'){\r\n idList.forEach(item => {\r\n delete images[item];\r\n })\r\n }\r\n else {\r\n images = null;\r\n }\r\n\r\n file.images = images;\r\n\r\n if(file.index == Store.currentSheetIndex){\r\n if(imageCtrl.currentImgId != null && (idList == 'all' || idList.includes(imageCtrl.currentImgId))){\r\n $(\"#luckysheet-modal-dialog-activeImage\").hide();\r\n $(\"#luckysheet-modal-dialog-cropping\").hide();\r\n $(\"#luckysheet-modal-dialog-slider-imageCtrl\").hide();\r\n }\r\n\r\n imageCtrl.images = images;\r\n imageCtrl.allImagesShow();\r\n imageCtrl.init();\r\n }\r\n\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 获取指定工作表的图片配置\r\n * @param {Object} options 可选参数\r\n * @param {Number} options.order 工作表下标;默认值为当前工作表下标\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function getImageOption(options = {}){\r\n let {\r\n order = getSheetIndex(Store.currentSheetIndex),\r\n success\r\n } = {...options}\r\n\r\n let file = Store.luckysheetfile[order];\r\n\r\n if(file == null){\r\n return tooltip.info(\"The order parameter is invalid.\", \"\");\r\n }\r\n\r\n setTimeout(function(){\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n }, 1)\r\n\r\n return file.images;\r\n}\r\n\r\n\r\n/**\r\n * data => celldata ,data二维数组数据转化成 {r, c, v}格式一维数组\r\n *\r\n * @param {Array} data 二维数组数据\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function transToCellData(data, options = {}){\r\n let {\r\n success\r\n } = {...options}\r\n\r\n setTimeout(()=>{\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n },0)\r\n\r\n return sheetmanage.getGridData(data)\r\n}\r\n\r\n\r\n/**\r\n * celldata => data ,celldata一维数组数据转化成表格所需二维数组\r\n *\r\n * @param {Array} celldata 二维数组数据\r\n * @param {Object} options 可选参数\r\n * @param {Function} options.success 操作结束的回调函数\r\n */\r\nexport function transToData(celldata, options = {}){\r\n let {\r\n success\r\n } = {...options}\r\n\r\n setTimeout(()=>{\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n },0)\r\n\r\n return sheetmanage.buildGridData({\r\n celldata: celldata\r\n })\r\n}\r\n\r\n/**\r\n * 导出的json字符串可以直接当作`luckysheet.create(options)`初始化工作簿时的参数`options`使用\r\n *\r\n */\r\nexport function toJson(){\r\n\r\n const toJsonOptions = Store.toJsonOptions;\r\n\r\n // Workbook name\r\n toJsonOptions.title = $(\"#luckysheet_info_detail_input\").val();\r\n\r\n toJsonOptions.data = getAllSheets();\r\n\r\n // row and column\r\n getluckysheetfile().forEach((file,index)=>{\r\n\r\n if(file.data == undefined){\r\n return;\r\n }\r\n toJsonOptions.data[index].row = getObjType(file.data) === 'array' ? file.data.length : 0;\r\n toJsonOptions.data[index].column = getObjType(file.data[0]) === 'array' ? file.data[0].length : 0;\r\n\r\n })\r\n\r\n return toJsonOptions;\r\n}\r\n\r\n\r\n/**\r\n * 传入目标语言,切换到对应的语言界面\r\n * @param {String} lang 可选参数;暂支持`\"zh\"`、`\"en\"`、`\"es\"`;默认为`\"zh\"`;\r\n */\r\nexport function changLang(lang = 'zh'){\r\n if(!['zh', 'en', 'es'].includes(lang)){\r\n return tooltip.info(\"The lang parameter is invalid.\", \"\");\r\n }\r\n\r\n let options = toJson();\r\n options.lang = lang;\r\n luckysheet.create(options);\r\n}\r\n\r\n\r\n/**\r\n * 关闭websocket连接\r\n */\r\nexport function closeWebsocket(){\r\n if(server.websocket == null){\r\n return;\r\n }\r\n server.websocket.close(1000);\r\n}\r\n\r\n\r\n/**\r\n * 根据范围字符串转换为range数组\r\n * @param {String} txt 范围字符串\r\n */\r\nexport function getRangeByTxt(txt){\r\n\r\n // 默认取当前第一个范围\r\n if(txt == null){\r\n return {\r\n column:Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1].column,\r\n row:Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1].row\r\n }\r\n }\r\n\r\n const range = conditionformat.getRangeByTxt(txt);\r\n\r\n return {\r\n column:range[0].column,\r\n row:range[0].row\r\n };\r\n}\r\n\r\n\r\n/**\r\n * 根据范围数组转换为范围字符串\r\n * @param {Object | Array} range 范围数组\r\n */\r\nexport function getTxtByRange(range=Store.luckysheet_select_save){\r\n\r\n // 单个范围\r\n if(getObjType(range) === 'object'){\r\n range = [range];\r\n }\r\n return conditionformat.getTxtByRange(range);\r\n}\r\n\r\n/**\r\n * 初始化分页器\r\n * @param {Object} config 分页器配置\r\n * @param {Number} config.pageIndex 当前的页码\r\n * @param {Number} config.pageSize 每页显示多少条数据\r\n * @param {Array} config.selectOption 选择每页的条数\r\n * @param {Number} config.total 总条数\r\n */\r\nexport function pagerInit (config) {\r\n $('#luckysheet-bottom-pager').remove()\r\n $('#luckysheet-sheet-area').append('
')\r\n $(\"#luckysheet-bottom-pager\").sPage({\r\n page: config.pageIndex, //当前页码,必填\r\n total: config.total, //数据总条数,必填\r\n selectOption: config.selectOption, // 选择每页的行数,\r\n pageSize: config.pageSize, //每页显示多少条数据,默认10条\r\n showTotal: true, // 是否显示总数\r\n showSkip: config.showSkip || true, //是否显示跳页,默认关闭:false\r\n showPN: config.showPN || true, //是否显示上下翻页,默认开启:true\r\n backFun: function (page) {\r\n page.pageIndex = page.page\r\n if(!method.createHookFunction(\"onTogglePager\", page)){ return; }\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * 刷新公式\r\n * @param {Function} success 回调函数\r\n */\r\nexport function refreshFormula (success) {\r\n formula.execFunctionGroupForce(true);\r\n luckysheetrefreshgrid()\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 刷新状态栏的状态\r\n * @param {Array} data 操作数据\r\n * @param {Number} r 指定的行\r\n * @param {Number} c 指定的列\r\n * @param {Function} success 回调函数\r\n */\r\nexport function refreshMenuButtonFocus(data ,r,c , success){\r\n data = data || Store.flowdata;\r\n if(r == null && c == null){\r\n /* 获取选取范围 */\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length -1];\r\n\r\n r = last.row_focus || last.row[0];\r\n c = last.column_focus || last.column[0];\r\n }\r\n\r\n menuButton.menuButtonFocus(data, r, c);\r\n\r\n setTimeout(() => {\r\n if (success && typeof success === 'function') {\r\n success();\r\n }\r\n })\r\n}","import menuButton from './menuButton';\r\nimport formula from '../global/formula';\r\nimport Store from '../store';\r\nimport flatpickr from 'flatpickr'\r\nimport dayjs from \"dayjs\";\r\nimport { update, datenum_local } from '../global/format';\r\nimport { setCellValue, setCellFormat } from '../global/api';\r\n\r\nconst fitFormat = (formatStr) => {\r\n let dateFormat = formatStr.replace(/y/g, 'Y');\r\n dateFormat = dateFormat.replace(/d/g, 'D');\r\n dateFormat = dateFormat.replace(/h/g, 'H');\r\n\r\n dateFormat = dateFormat.replace(/上午\\/下午/g, 'A');\r\n dateFormat = dateFormat.replace(/上午/g, 'A');\r\n dateFormat = dateFormat.replace(/下午/g, 'A');\r\n\r\n dateFormat = dateFormat.replace(/AM\\/PM/g, 'A');\r\n dateFormat = dateFormat.replace(/AM/g, 'A');\r\n dateFormat = dateFormat.replace(/PM/g, 'A');\r\n dateFormat = dateFormat.replace(/\\\"/g, '');\r\n\r\n if (dateFormat.includes('A')) {\r\n dateFormat = dateFormat.replace(/H/g, 'h');\r\n }\r\n return dateFormat\r\n}\r\n\r\nconst cellDatePickerCtrl = {\r\n cellFocus: function (r, c, cell) {\r\n let row = Store.visibledatarow[r],\r\n row_pre = r == 0 ? 0 : Store.visibledatarow[r - 1];\r\n let col = Store.visibledatacolumn[c],\r\n col_pre = c == 0 ? 0 : Store.visibledatacolumn[c - 1];\r\n\r\n let margeset = menuButton.mergeborer(Store.flowdata, r, c);\r\n let type = cell.ct.fa || 'YYYY-MM-DD';\r\n let defaultDate = update('yyyy-MM-dd hh:mm:ss', cell.v);\r\n let dateFormat = fitFormat(type);\r\n let enableTime = false;\r\n let noCalendar = false;\r\n let enableSeconds = false;\r\n let time_24hr = true;\r\n let hasChineseTime = false;\r\n\r\n\r\n if (!!margeset) {\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n\r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n }\r\n\r\n $(\".cell-date-picker\").show().css({\r\n width: col - col_pre + 1,\r\n height: row - row_pre + 1,\r\n left: col_pre,\r\n top: row_pre\r\n })\r\n\r\n if (/[上午下午]/.test(type)) {\r\n hasChineseTime = true\r\n }\r\n if (/[Hhms]/.test(dateFormat)) {\r\n enableTime = true;\r\n }\r\n if (!/[YMD]/.test(dateFormat)) {\r\n noCalendar = true;\r\n }\r\n if (/s/.test(dateFormat)) {\r\n enableSeconds = true;\r\n }\r\n if (/A/.test(dateFormat)) {\r\n time_24hr = false;\r\n }\r\n\r\n const fp = flatpickr('#luckysheet-input-box', {\r\n allowInput: false,\r\n noCalendar,\r\n enableSeconds,\r\n enableTime,\r\n dateFormat,\r\n time_24hr,\r\n defaultDate,\r\n onClose() {\r\n setTimeout(() => {\r\n fp.destroy()\r\n }, 0);\r\n },\r\n parseDate: (datestr, format) => {\r\n return dayjs(datestr).toDate();\r\n },\r\n formatDate: (date, format, locale) => {\r\n if (hasChineseTime) {\r\n return dayjs(date).format(format).replace('AM', '上午').replace('PM', '下午')\r\n }\r\n return dayjs(date).format(format);\r\n },\r\n onChange: function (selectedDates, dateStr) {\r\n let currentVal = datenum_local(new Date(selectedDates))\r\n $(\"#luckysheet-rich-text-editor\").html(dateStr);\r\n setCellValue(r, c, currentVal, { isRefresh: false })\r\n setCellFormat(r, c, 'ct', cell.ct)\r\n if (!enableTime) {\r\n formula.updatecell(Store.luckysheetCellUpdate[0], Store.luckysheetCellUpdate[1]);\r\n }\r\n }\r\n });\r\n\r\n $(\"#luckysheet-input-box\").click();\r\n },\r\n}\r\n\r\nexport default cellDatePickerCtrl;\r\n","import pivotTable from './pivotTable';\r\nimport luckysheetFreezen from './freezen';\r\nimport menuButton from './menuButton';\r\nimport conditionformat from './conditionformat';\r\nimport alternateformat from './alternateformat';\r\nimport cellDatePickerCtrl from './cellDatePickerCtrl';\r\nimport dataVerificationCtrl from './dataVerificationCtrl';\r\nimport {checkProtectionLocked,checkProtectionCellHidden} from './protection';\r\nimport { chatatABC } from '../utils/util';\r\nimport { isEditMode } from '../global/validate';\r\nimport { getcellvalue,getInlineStringStyle } from '../global/getdata';\r\nimport { valueShowEs } from '../global/format';\r\nimport formula from '../global/formula';\r\nimport { luckysheetRangeLast } from '../global/cursorPos';\r\nimport cleargridelement from '../global/cleargridelement';\r\nimport {isInlineStringCell} from './inlineString';\r\nimport Store from '../store';\r\nimport server from './server';\r\nimport method from '../global/method';\r\n\r\nexport function luckysheetupdateCell(row_index1, col_index1, d, cover, isnotfocus) {\r\n if(!checkProtectionLocked(row_index1, col_index1, Store.currentSheetIndex)){\r\n $(\"#luckysheet-functionbox-cell\").blur();\r\n return;\r\n }\r\n\r\n if(isEditMode() || Store.allowEdit===false){//此模式下禁用单元格编辑\r\n return;\r\n }\r\n\r\n // 钩子函数\r\n method.createHookFunction('cellEditBefore',Store.luckysheet_select_save)\r\n\r\n // 编辑单元格时发送指令到后台,通知其他单元格更新为“正在输入”状态\r\n server.saveParam(\"mv\", Store.currentSheetIndex, {op:\"enterEdit\",range:Store.luckysheet_select_save});\r\n\r\n //数据验证\r\n if(dataVerificationCtrl.dataVerification != null && dataVerificationCtrl.dataVerification[row_index1 + '_' + col_index1] != null){\r\n let dataVerificationItem = dataVerificationCtrl.dataVerification[row_index1 + '_' + col_index1];\r\n if(dataVerificationItem.type == 'dropdown'){\r\n dataVerificationCtrl.dropdownListShow();\r\n }\r\n else if(dataVerificationItem.type == 'checkbox'){\r\n return;\r\n }\r\n }\r\n\r\n let size = getColumnAndRowSize(row_index1, col_index1, d);\r\n let row = size.row, \r\n row_pre = size.row_pre, \r\n col = size.col, \r\n col_pre = size.col_pre, \r\n row_index = size.row_index, \r\n col_index = size.col_index;\r\n\r\n if($(\"#luckysheet-dropCell-icon\").is(\":visible\")){\r\n $(\"#luckysheet-dropCell-icon\").remove();\r\n }\r\n\r\n let winH = $(window).height(), winW = $(window).width();\r\n let container_offset = $(\"#\" + Store.container).offset();\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n if (pivotTable.isPivotRange(row_index, col_index)) {\r\n return;\r\n }\r\n\r\n let left = col_pre + container_offset.left + Store.rowHeaderWidth - scrollLeft - 2;\r\n if(luckysheetFreezen.freezenverticaldata != null && col_index1 <= luckysheetFreezen.freezenverticaldata[1]){\r\n left = col_pre + container_offset.left + Store.rowHeaderWidth - 2;\r\n }\r\n\r\n let top = row_pre + container_offset.top + Store.infobarHeight + Store.toolbarHeight + Store.calculatebarHeight + Store.columnHeaderHeight - scrollTop - 2;\r\n if(luckysheetFreezen.freezenhorizontaldata != null && row_index1 <= luckysheetFreezen.freezenhorizontaldata[1]){\r\n top = row_pre + container_offset.top + Store.infobarHeight + Store.toolbarHeight + Store.calculatebarHeight + Store.columnHeaderHeight - 2;\r\n }\r\n\r\n let input_postition = {\r\n \"min-width\": col - col_pre+ 1- 8, \r\n \"min-height\": row - row_pre + 1- 4, \r\n \r\n \"max-width\": winW + scrollLeft - col_pre - 20 - Store.rowHeaderWidth, \r\n \"max-height\": winH + scrollTop - row_pre - 20 - 15 - Store.toolbarHeight - Store.infobarHeight - Store.calculatebarHeight - Store.sheetBarHeight - Store.statisticBarHeight, \r\n \"left\": left, \r\n \"top\": top, \r\n }\r\n\r\n let inputContentScale = {\r\n \"transform\":\"scale(\"+ Store.zoomRatio +\")\",\r\n \"transform-origin\":\"left top\",\r\n \"width\":(100 / Store.zoomRatio) + \"%\",\r\n \"height\":(100 / Store.zoomRatio) + \"%\",\r\n }\r\n\r\n Store.luckysheetCellUpdate = [row_index, col_index];\r\n if (!isnotfocus) {\r\n $(\"#luckysheet-rich-text-editor\").focus().select();\r\n }\r\n\r\n $(\"#luckysheet-input-box\").removeAttr(\"style\").css({ \r\n \"background-color\": \"rgb(255, 255, 255)\", \r\n \"padding\": \"0px 2px\", \r\n \"font-size\": \"13px\", \r\n \"right\": \"auto\", \r\n \"overflow-y\": \"auto\",\r\n \"box-sizing\": \"initial\",\r\n \"display\":\"flex\",\r\n });\r\n\r\n if(luckysheetFreezen.freezenverticaldata != null || luckysheetFreezen.freezenhorizontaldata != null){\r\n $(\"#luckysheet-input-box\").css(\"z-index\", 10002);\r\n }\r\n \r\n $(\"#luckysheet-input-box-index\").html(chatatABC(col_index) + (row_index + 1)).hide();\r\n $(\"#luckysheet-wa-functionbox-cancel, #luckysheet-wa-functionbox-confirm\").addClass(\"luckysheet-wa-calculate-active\");\r\n \r\n let value = \"\", isCenter=false;\r\n \r\n if (d[row_index] != null && d[row_index][col_index] != null) {\r\n let cell = d[row_index][col_index];\r\n let htValue = cell[\"ht\"];\r\n let leftOrigin = \"left\", topOrigin = \"top\";\r\n if(htValue == \"0\"){//0 center, 1 left, 2 right\r\n input_postition = { \r\n \"min-width\": col - col_pre + 1- 8, \r\n \"min-height\": row - row_pre + 1- 4, \r\n // \"transform\":\"scale(\"+ Store.zoomRatio +\")\",\r\n // \"transform-origin\":\"center top\",\r\n \"max-width\": winW*2/3, \r\n \"max-height\": winH + scrollTop - row_pre - 20 - 15 - Store.toolbarHeight - Store.infobarHeight - Store.calculatebarHeight - Store.sheetBarHeight - Store.statisticBarHeight, \r\n \"left\": col_pre + container_offset.left + Store.rowHeaderWidth - scrollLeft - 2, \r\n \"top\": row_pre + container_offset.top + Store.infobarHeight + Store.toolbarHeight + Store.calculatebarHeight + Store.columnHeaderHeight - scrollTop - 2, \r\n }\r\n\r\n if(Store.zoomRatio<1){\r\n leftOrigin = \"center\";\r\n }\r\n\r\n isCenter = true;\r\n }\r\n else if(htValue == \"2\"){\r\n input_postition = { \r\n \"min-width\": col - col_pre+ 1- 8, \r\n \"min-height\": row - row_pre + 1- 4, \r\n // \"transform\":\"scale(\"+ Store.zoomRatio +\")\",\r\n // \"transform-origin\":\"right top\",\r\n \"max-width\": col + container_offset.left - scrollLeft - 8, \r\n \"max-height\": winH + scrollTop - row_pre - 20 - 15 - Store.toolbarHeight - Store.infobarHeight - Store.calculatebarHeight - Store.sheetBarHeight - Store.statisticBarHeight, \r\n \"right\": winW - (container_offset.left + (Store.rowHeaderWidth-1) - scrollLeft) - col, \r\n \"top\": row_pre + container_offset.top + Store.infobarHeight + Store.toolbarHeight + Store.calculatebarHeight + Store.columnHeaderHeight - scrollTop - 2, \r\n }\r\n\r\n if(Store.zoomRatio<1){\r\n leftOrigin = \"right\";\r\n }\r\n }\r\n\r\n if(cell[\"vt\"]==\"0\"){\r\n topOrigin = \"center\";\r\n }\r\n else if(cell[\"vt\"]==\"2\"){\r\n topOrigin = \"bottom\";\r\n }\r\n\r\n inputContentScale[\"transform-origin\"] = leftOrigin +\" \" + topOrigin;\r\n\r\n \r\n if (!cover) {\r\n if(isInlineStringCell(cell)){\r\n value = getInlineStringStyle(row_index, col_index, d);\r\n }\r\n else if(cell.f!=null){\r\n value = getcellvalue(row_index, col_index, d, \"f\");\r\n }\r\n else{\r\n value = valueShowEs(row_index, col_index, d);\r\n if(cell.qp==\"1\"){\r\n value = \"'\" + value;\r\n }\r\n }\r\n }\r\n \r\n let style = menuButton.getStyleByCell(d, row_index, col_index);\r\n style = $(\"#luckysheet-input-box\").get(0).style.cssText + style;\r\n\r\n $(\"#luckysheet-input-box\").get(0).style.cssText = style;\r\n if($(\"#luckysheet-input-box\").get(0).style.backgroundColor == \"rgba(0, 0, 0, 0)\"){\r\n $(\"#luckysheet-input-box\").get(0).style.background = \"rgb(255,255,255)\";\r\n }\r\n }\r\n else{\r\n //交替颜色\r\n let af_compute = alternateformat.getComputeMap();\r\n var checksAF = alternateformat.checksAF(row_index, col_index, af_compute);\r\n\r\n //条件格式\r\n var cf_compute = conditionformat.getComputeMap();\r\n var checksCF = conditionformat.checksCF(row_index, col_index, cf_compute);\r\n\r\n if(checksCF != null && checksCF[\"cellColor\"] != null){\r\n $(\"#luckysheet-input-box\").get(0).style.background = checksCF[\"cellColor\"];\r\n }\r\n else if(checksAF != null){\r\n $(\"#luckysheet-input-box\").get(0).style.background = checksAF[1];\r\n }\r\n }\r\n\r\n if(input_postition[\"min-height\"] > input_postition[\"max-height\"]){\r\n input_postition[\"min-height\"] = input_postition[\"max-height\"];\r\n }\r\n\r\n if(input_postition[\"min-width\"] > input_postition[\"max-width\"]){\r\n input_postition[\"min-width\"] = input_postition[\"max-width\"];\r\n }\r\n \r\n if((value == null || value.toString() == \"\") && !cover){\r\n value = \"
\";\r\n }\r\n \r\n if(!checkProtectionCellHidden(row_index, col_index, Store.currentSheetIndex) && value.length>0 && value.substr(0, 63)=='='){\r\n $(\"#luckysheet-rich-text-editor\").html(\"\");\r\n }\r\n else{\r\n $(\"#luckysheet-rich-text-editor\").html(value);\r\n if (!isnotfocus) {\r\n luckysheetRangeLast($(\"#luckysheet-rich-text-editor\")[0]);\r\n }\r\n }\r\n\r\n if(isCenter){\r\n let width = $(\"#luckysheet-input-box\").width();\r\n if(width> input_postition[\"max-width\"]){\r\n width = input_postition[\"max-width\"];\r\n }\r\n\r\n if(width< input_postition[\"min-width\"]){\r\n width = input_postition[\"min-width\"];\r\n }\r\n\r\n let newLeft = input_postition[\"left\"] - width/2 + (col - col_pre)/2;\r\n if(newLeft<2){\r\n newLeft = 2;\r\n }\r\n\r\n input_postition[\"left\"] = newLeft-2;\r\n }\r\n\r\n $(\"#luckysheet-input-box\").css(input_postition);\r\n $(\"#luckysheet-rich-text-editor\").css(inputContentScale);\r\n\r\n //日期\r\n if(d[row_index1][col_index1] && d[row_index1][col_index1].ct && d[row_index1][col_index1].ct.t == 'd'){\r\n cellDatePickerCtrl.cellFocus(row_index1, col_index1, d[row_index1][col_index1]);\r\n }\r\n\r\n formula.rangetosheet = Store.currentSheetIndex;\r\n formula.createRangeHightlight();\r\n formula.rangeResizeTo = $(\"#luckysheet-rich-text-editor\");\r\n cleargridelement();\r\n}\r\n\r\nexport function setCenterInputPosition(row_index, col_index, d){\r\n if(row_index==null ||col_index==null){\r\n return;\r\n }\r\n let cell = d[row_index][col_index];\r\n if(cell==null){\r\n return;\r\n }\r\n let htValue = cell[\"ht\"];\r\n if(cell!=null && htValue != \"0\"){//0 center, 1 left, 2 right\r\n return;\r\n }\r\n\r\n let size = getColumnAndRowSize(row_index, col_index, d);\r\n let row = size.row, row_pre = size.row_pre, col = size.col, col_pre = size.col_pre;\r\n\r\n let winH = $(window).height(), winW = $(window).width();\r\n let container_offset = $(\"#\" + Store.container).offset();\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n\r\n let input_postition = { \r\n \"min-width\": col - col_pre + 1 - 8, \r\n \"max-width\": winW*2/3, \r\n \"left\": col_pre + container_offset.left + Store.rowHeaderWidth - scrollLeft - 2, \r\n }\r\n\r\n let width = $(\"#luckysheet-input-box\").width();\r\n if(width> input_postition[\"max-width\"]){\r\n width = input_postition[\"max-width\"];\r\n }\r\n\r\n if(width< input_postition[\"min-width\"]){\r\n width = input_postition[\"min-width\"];\r\n }\r\n\r\n let newLeft = input_postition[\"left\"] - width/2 + (col - col_pre)/2;\r\n if(newLeft<2){\r\n newLeft = 2;\r\n }\r\n\r\n input_postition[\"left\"] = newLeft-2;\r\n\r\n $(\"#luckysheet-input-box\").css(input_postition);\r\n}\r\n\r\nexport function getColumnAndRowSize(row_index, col_index, d){\r\n let row = Store.visibledatarow[row_index], \r\n row_pre = row_index - 1 == -1 ? 0 : Store.visibledatarow[row_index - 1];\r\n let col = Store.visibledatacolumn[col_index], \r\n col_pre = col_index - 1 == -1 ? 0 : Store.visibledatacolumn[col_index - 1];\r\n\r\n if(d == null){\r\n d = Store.flowdata;\r\n }\r\n\r\n let margeset = menuButton.mergeborer(d, row_index, col_index);\r\n if(!!margeset){\r\n row = margeset.row[1];\r\n row_pre = margeset.row[0];\r\n row_index = margeset.row[2];\r\n col = margeset.column[1];\r\n col_pre = margeset.column[0];\r\n col_index = margeset.column[2];\r\n } \r\n\r\n return {\r\n row: row,\r\n row_pre: row_pre,\r\n row_index: row_index,\r\n col: col,\r\n col_pre: col_pre,\r\n col_index: col_index\r\n }\r\n}\r\n","import formula from '../global/formula';\r\nimport editor from '../global/editor';\r\nimport {luckysheetupdateCell} from './updateCell';\r\nimport { modelHTML } from './constant';\r\nimport { replaceHtml } from '../utils/util';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\n//if公式生成器\r\nconst ifFormulaGenerator = {\r\n singleRangeFocus: false,\r\n init: function(){\r\n let _this = this;\r\n const _locale = locale();\r\n const locale_formula = _locale.formula;\r\n const locale_button = _locale.button;\r\n //点击选择单元格\r\n $(document).off(\"focus.IFcompareValue\").on(\"focus.IFcompareValue\", \"#luckysheet-ifFormulaGenerator-dialog #compareValue\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n _this.singleRangeFocus = true;\r\n });\r\n $(document).off(\"click.IFsingRange\").on(\"click.IFsingRange\", \"#luckysheet-ifFormulaGenerator-dialog .singRange\", function(){\r\n let value = $(\"#luckysheet-ifFormulaGenerator-dialog #compareValue\").val().trim();\r\n\r\n if(formula.iscelldata(value)){\r\n _this.singleRangeDialog(value);\r\n }\r\n else{\r\n _this.singleRangeDialog();\r\n }\r\n });\r\n $(document).off(\"click.IFsingRangeConfirm\").on(\"click.IFsingRangeConfirm\", \"#luckysheet-ifFormulaGenerator-singleRange-confirm\", function(){\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n\r\n $(\"#luckysheet-ifFormulaGenerator-singleRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").show();\r\n\r\n let value = $(this).parents(\"#luckysheet-ifFormulaGenerator-singleRange-dialog\").find(\"input\").val().trim();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog #compareValue\").val(value);\r\n\r\n _this.singleRangeFocus = false; \r\n });\r\n $(document).off(\"click.IFsingRangeCancel\").on(\"click.IFsingRangeCancel\", \"#luckysheet-ifFormulaGenerator-singleRange-cancel\", function(){\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n\r\n $(\"#luckysheet-ifFormulaGenerator-singleRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").show();\r\n\r\n _this.singleRangeFocus = false; \r\n });\r\n $(document).off(\"click.IFsingRangeClose\").on(\"click.IFsingRangeClose\", \"#luckysheet-ifFormulaGenerator-singleRange-dialog .luckysheet-modal-dialog-title-close\", function(){\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").show();\r\n\r\n _this.singleRangeFocus = false;\r\n });\r\n\r\n //点击选择范围\r\n $(document).off(\"click.IFmultiRange\").on(\"click.IFmultiRange\", \"#luckysheet-ifFormulaGenerator-dialog .multiRange\", function(){\r\n _this.multiRangeDialog();\r\n\r\n _this.singleRangeFocus = false;\r\n });\r\n $(document).off(\"click.IFmultiRangeConfirm\").on(\"click.IFmultiRangeConfirm\", \"#luckysheet-ifFormulaGenerator-multiRange-confirm\", function(){\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n\r\n $(\"#luckysheet-ifFormulaGenerator-multiRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").show();\r\n\r\n let value = $(this).parents(\"#luckysheet-ifFormulaGenerator-multiRange-dialog\").find(\"input\").val().trim();\r\n let cellrange = formula.getcellrange(value);\r\n let str_r = cellrange[\"row\"][0], \r\n end_r = cellrange[\"row\"][1], \r\n str_c = cellrange[\"column\"][0], \r\n end_c = cellrange[\"column\"][1];\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n let arr = [];\r\n \r\n //获取范围内所有数值\r\n for(let r = str_r; r <= end_r; r++){\r\n for(let c = str_c; c <= end_c; c++){\r\n if(d[r] != null && d[r][c] != null && d[r][c][\"ct\"] != null && d[r][c][\"ct\"][\"t\"] == \"n\"){\r\n arr.push(d[r][c][\"v\"]);\r\n }\r\n }\r\n }\r\n\r\n //从大到小排序\r\n for(let j = 0; j < arr.length; j++){\r\n for(let k = 0; k < arr.length - 1 - j; k++){\r\n if(arr[k] < arr[k + 1]){\r\n let temp = arr[k];\r\n arr[k] = arr[k + 1];\r\n arr[k + 1] = temp;\r\n }\r\n }\r\n }\r\n\r\n let largeNum = arr[0];\r\n let smallNum = arr[arr.length - 1];\r\n \r\n //赋值\r\n $(\"#luckysheet-ifFormulaGenerator-dialog #smallRange\").val(smallNum);\r\n $(\"#luckysheet-ifFormulaGenerator-dialog #largeRange\").val(largeNum);\r\n });\r\n $(document).off(\"click.IFmultiRangeCancel\").on(\"click.IFmultiRangeCancel\", \"#luckysheet-ifFormulaGenerator-multiRange-cancel\", function(){\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n\r\n $(\"#luckysheet-ifFormulaGenerator-multiRange-dialog\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").show();\r\n });\r\n $(document).off(\"click.IFmultiRangeClose\").on(\"click.IFmultiRangeClose\", \"#luckysheet-ifFormulaGenerator-multiRange-dialog .luckysheet-modal-dialog-title-close\", function(){\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n $(\"#luckysheet-row-count-show\").hide();\r\n $(\"#luckysheet-column-count-show\").hide();\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").show();\r\n });\r\n\r\n //选择 划分方式\r\n $(document).on(\"change\", \"#DivisionMethod\", function(){\r\n let value = $(this).find(\"option:selected\").val();\r\n\r\n if(value == \"2\"){\r\n $(\"#DivisionMethodVal\").hide();\r\n }\r\n else{\r\n $(\"#DivisionMethodVal\").show(); \r\n }\r\n\r\n $(\"#luckysheet-ifFormulaGenerator-dialog .ifList\").empty();\r\n });\r\n\r\n //点击 生成 按钮\r\n $(document).off(\"click.IFcreateBtn\").on(\"click.IFcreateBtn\", \"#luckysheet-ifFormulaGenerator-dialog #createBtn\", function(){\r\n let compareValue = $(this).parents(\"#luckysheet-ifFormulaGenerator-dialog\").find(\"#compareValue\").val().trim();\r\n if(compareValue == \"\"){\r\n _this.info(locale_formula.ifGenTipNotNullValue);\r\n return;\r\n }\r\n\r\n let method = $(this).parents(\"#luckysheet-ifFormulaGenerator-dialog\").find(\"#DivisionMethod option:selected\").val();\r\n if(method == \"2\"){\r\n let itemHtml = '
'+\r\n ''+\r\n ''+\r\n ''+ compareValue +''+\r\n ''+\r\n ''+\r\n ''+locale_formula.ifGenTipLableTitile+':'+\r\n ''+\r\n ''+\r\n '
';\r\n $(\"#luckysheet-ifFormulaGenerator-dialog .ifList\").append(itemHtml); \r\n }\r\n else{\r\n let smallRange = $(this).parents(\"#luckysheet-ifFormulaGenerator-dialog\").find(\"#smallRange\").val().trim();\r\n let largeRange = $(this).parents(\"#luckysheet-ifFormulaGenerator-dialog\").find(\"#largeRange\").val().trim();\r\n let DivisionMethodVal = $(this).parents(\"#luckysheet-ifFormulaGenerator-dialog\").find(\"#DivisionMethodVal\").val().trim();\r\n \r\n if(smallRange == \"\" || largeRange == \"\"){\r\n _this.info(locale_formula.ifGenTipRangeNotforNull);\r\n return;\r\n }\r\n else if(DivisionMethodVal == \"\"){\r\n _this.info(locale_formula.ifGenTipCutValueNotforNull);\r\n return;\r\n }\r\n\r\n _this.getIfList(compareValue, smallRange, largeRange, method, DivisionMethodVal);\r\n }\r\n });\r\n\r\n //点击 删除条件\r\n $(document).on(\"click\", \"#luckysheet-ifFormulaGenerator-dialog .item .fa-remove\", function(){\r\n $(this).parents(\".item\").remove();\r\n });\r\n\r\n //点击 确认 按钮\r\n $(document).off(\"click.IFconfirmBtn\").on(\"click.IFconfirmBtn\", \"#luckysheet-ifFormulaGenerator-dialog-confirm\", function(){\r\n let $item = $(this).parents(\"#luckysheet-ifFormulaGenerator-dialog\").find(\".ifList .item\");\r\n let str = '';\r\n\r\n $($item.toArray().reverse()).each(function(i, e){\r\n let smallNum = $(e).find(\".smallNum\").val().trim();\r\n let largeNum = $(e).find(\".largeNum\").val().trim();\r\n let operator = $(e).find(\".operator option:selected\").val();\r\n let operator2 = $(e).find(\".operator2 option:selected\").val();\r\n let compareValue = $(e).find(\".compareValue\").text();\r\n\r\n let markText = $(e).find(\".markText\").val().trim();\r\n if(markText == \"\"){\r\n markText = locale_formula.ifGenTipLableTitile + (i + 1);\r\n }\r\n\r\n if(smallNum == \"\" && largeNum == \"\"){\r\n return true;\r\n }\r\n\r\n let s;\r\n if(operator == \"0\"){\r\n s = compareValue + \">=\" + smallNum;\r\n }\r\n else{\r\n s = compareValue + \">\" + smallNum;\r\n }\r\n\r\n let l;\r\n if(operator2 == \"0\"){\r\n l = compareValue + \"<=\" + largeNum;\r\n }\r\n else{\r\n l = compareValue + \"<\" + largeNum;\r\n }\r\n\r\n let a;\r\n if(i == 0 && largeNum == \"\"){\r\n a = s;\r\n }\r\n else if(i == ($item.length - 1) && smallNum == \"\"){\r\n a = l;\r\n }\r\n else{\r\n a = \"and(\"+s+\",\"+l+\")\";\r\n }\r\n\r\n if(i == 0){\r\n str = 'if('+ a +',\"'+ markText +'\")';\r\n }\r\n else{\r\n str = 'if('+ a +',\"'+ markText +'\",'+ str +')';\r\n }\r\n })\r\n \r\n if(str.length == 0){\r\n _this.info(locale_formula.ifGenTipNotGenCondition);\r\n return;\r\n }\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").hide();\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let row_index = last[\"row_focus\"], \r\n col_index = last[\"column_focus\"];\r\n \r\n luckysheetupdateCell(row_index, col_index, Store.flowdata);\r\n\r\n $(\"#luckysheet-rich-text-editor\").html(\"=\" + str);\r\n $(\"#luckysheet-functionbox-cell\").html($(\"#luckysheet-rich-text-editor\").html());\r\n\r\n $(\"#luckysheet-wa-functionbox-confirm\").click();\r\n });\r\n\r\n //info\r\n $(document).on(\"click\", \"#luckysheet-ifFormulaGenerator-info .luckysheet-model-close-btn\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n });\r\n $(document).on(\"click\", \"#luckysheet-ifFormulaGenerator-info .luckysheet-modal-dialog-title-close\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n });\r\n },\r\n ifFormulaDialog: function(fp){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_formula = _locale.formula;\r\n const locale_button = _locale.button;\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").remove();\r\n\r\n let compareValue = \"\";\r\n let ifListHtml = '';\r\n\r\n if(!!fp){\r\n let arr = fp.split(\"if(\");\r\n\r\n for(let i = 1; i < arr.length; i++){\r\n let txt = arr[i].replace(\"and(\",\"\").replace(/\\)/g,\"\").replace(/\\\"/g,\"\");\r\n let arr2 = txt.split(\",\");\r\n arr2 = _this.clearArr(arr2);\r\n \r\n compareValue = _this.splitTxt(arr2[0])[0];\r\n\r\n let smallNum, largeNum, markText;\r\n if(arr2.length == 3){\r\n smallNum = _this.splitTxt(arr2[0])[1];\r\n largeNum = _this.splitTxt(arr2[1])[2];\r\n markText = arr2[2];\r\n }\r\n else{\r\n smallNum = _this.splitTxt(arr2[0])[1];\r\n largeNum = _this.splitTxt(arr2[0])[2];\r\n markText = arr2[1];\r\n }\r\n\r\n let itemHtml = '
'+\r\n ''+\r\n ''+\r\n ''+ compareValue +''+\r\n ''+\r\n ''+\r\n ''+locale_formula.ifGenTipLableTitile+':'+\r\n ''+\r\n ''+\r\n '
'; \r\n ifListHtml += itemHtml; \r\n }\r\n }\r\n\r\n let content = '
'+\r\n '
'+\r\n ''+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n ' '+ locale_formula.ifGenRangeTo +' '+\r\n ''+\r\n '
'+\r\n ' '+ locale_formula.ifGenRangeEvaluate +' '+\r\n ''+\r\n '
'+\r\n '
'+\r\n '
'+\r\n ''+\r\n ''+\r\n ''+\r\n '
'+ locale_formula.ifGenCutSame +'
'+\r\n '
'+\r\n '
'+\r\n '
'+ifListHtml+'
';\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-ifFormulaGenerator-dialog\", \r\n \"addclass\": \"luckysheet-ifFormulaGenerator-dialog\", \r\n \"title\": locale_formula.ifGenerate, \r\n \"content\": content, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-ifFormulaGenerator-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 590).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n },\r\n clearArr: function(arr){\r\n for(let i = 0; i < arr.length; i++){\r\n if(arr[i] == \"\" || arr[i] == null || arr[i] == undefined){\r\n arr.splice(i, 1);\r\n }\r\n }\r\n\r\n return arr;\r\n },\r\n splitTxt: function(txt){\r\n let compareValue, smallNum, largeNum;\r\n \r\n if(txt.indexOf(\">=\") != -1){\r\n compareValue = txt.split(\">=\")[0];\r\n smallNum = txt.split(\">=\")[1];\r\n\r\n return [compareValue, smallNum, largeNum];\r\n }\r\n else if(txt.indexOf(\">\") != -1){\r\n compareValue = txt.split(\">\")[0];\r\n smallNum = txt.split(\">\")[1];\r\n\r\n return [compareValue, smallNum, largeNum];\r\n }\r\n else if(txt.indexOf(\"<=\") != -1){\r\n compareValue = txt.split(\"<=\")[0];\r\n largeNum = txt.split(\"<=\")[1];\r\n\r\n return [compareValue, smallNum, largeNum];\r\n }\r\n else if(txt.indexOf(\"<\") != -1){\r\n compareValue = txt.split(\"<\")[0];\r\n largeNum = txt.split(\"<\")[1];\r\n\r\n return [compareValue, smallNum, largeNum];\r\n }\r\n },\r\n singleRangeDialog: function(value){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").hide();\r\n $(\"#luckysheet-ifFormulaGenerator-singleRange-dialog\").remove();\r\n\r\n const _locale = locale();\r\n const locale_formula = _locale.formula;\r\n const locale_button = _locale.button;\r\n\r\n if(value == null){\r\n value = \"\";\r\n }\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-ifFormulaGenerator-singleRange-dialog\", \r\n \"addclass\": \"luckysheet-ifFormulaGenerator-singleRange-dialog\", \r\n \"title\": locale_formula.ifGenTipSelectCell, \r\n \"content\": '', \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-ifFormulaGenerator-singleRange-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 400).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-ifFormulaGenerator-singleRange-dialog\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n },\r\n multiRangeDialog: function(){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-ifFormulaGenerator-dialog\").hide();\r\n $(\"#luckysheet-ifFormulaGenerator-multiRange-dialog\").remove();\r\n\r\n const _locale = locale();\r\n const locale_formula = _locale.formula;\r\n const locale_button = _locale.button;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-ifFormulaGenerator-multiRange-dialog\", \r\n \"addclass\": \"luckysheet-ifFormulaGenerator-multiRange-dialog\", \r\n \"title\": locale_formula.ifGenTipSelectRange, \r\n \"content\": '', \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-ifFormulaGenerator-multiRange-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 400).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-ifFormulaGenerator-multiRange-dialog\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n },\r\n getIfList: function(compareValue, smallRange, largeRange, method, methodVal){\r\n const locale_formula = locale().formula;\r\n\r\n $(\"#luckysheet-ifFormulaGenerator-dialog .ifList\").empty();\r\n\r\n smallRange = parseInt(smallRange);\r\n largeRange = parseInt(largeRange);\r\n methodVal = parseInt(methodVal);\r\n\r\n let arr = [];\r\n\r\n if(method == \"0\"){\r\n let len = Math.ceil((largeRange - smallRange) / methodVal); \r\n for(let i = 0; i <= len; i++){\r\n let num = smallRange + methodVal * i;\r\n if(i == 0 || num >= largeRange){\r\n arr.push(\"\");\r\n }\r\n else{\r\n arr.push(num);\r\n }\r\n }\r\n \r\n }\r\n else if(method == \"1\"){\r\n let addnum = Math.ceil((largeRange - smallRange) / methodVal);\r\n for(let i = 0; i <= methodVal; i++){\r\n let num = smallRange + addnum * i;\r\n if(i == 0 || num >= largeRange){\r\n arr.push(\"\");\r\n }\r\n else{\r\n arr.push(num);\r\n }\r\n }\r\n }\r\n for(let j = 0; j < arr.length - 1; j++){\r\n let markText;\r\n if(j == 0){\r\n markText = \"小于\" + arr[j + 1];\r\n }\r\n else if(j == arr.length - 2){\r\n markText = \"大于等于\" + arr[j];\r\n }\r\n else{\r\n markText = arr[j] + \"到\" + arr[j + 1];\r\n }\r\n\r\n let itemHtml = '
'+\r\n ''+\r\n ''+\r\n ''+ compareValue +''+\r\n ''+\r\n ''+\r\n ''+locale_formula.ifGenTipLableTitile+':'+\r\n ''+\r\n ''+\r\n '
';\r\n $(\"#luckysheet-ifFormulaGenerator-dialog .ifList\").append(itemHtml);\r\n }\r\n },\r\n info: function(title){\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-ifFormulaGenerator-info\").remove();\r\n\r\n const _locale = locale();\r\n const locale_button = _locale.button;\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-ifFormulaGenerator-info\", \r\n \"addclass\": \"\", \r\n \"title\": title, \r\n \"content\": \"\", \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-ifFormulaGenerator-info\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 300).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-ifFormulaGenerator-info\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n }\r\n}\r\n\r\nexport default ifFormulaGenerator;","import { luckysheet_getcelldata } from '../function/func';\r\n// import functionlist from '../function/functionlist';\r\n// import Store.luckysheet_function from '../function/Store.luckysheet_function';\r\nimport formula from '../global/formula';\r\nimport { isRealNum, isRealNull } from '../global/validate';\r\nimport { modelHTML } from './constant';\r\nimport { luckysheet_count_show } from './select';\r\nimport { replaceHtml, getObjType } from '../utils/util';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\n//插入函数\r\nconst insertFormula = {\r\n init: function(){\r\n let _this = this;\r\n let _locale = locale();\r\n let locale_formulaMore = _locale.formulaMore;\r\n let locale_button = _locale.button;\r\n\r\n $(document).off(\"keyup.fxSFLI\").on(\"keyup.fxSFLI\", \"#searchFormulaListInput\", function(){\r\n $(\"#formulaTypeList\").empty();\r\n let txt = $(this).val().toUpperCase();\r\n let functionlist = Store.functionlist;\r\n\r\n if(txt == \"\"){\r\n //若没有查找内容则根据类别筛选\r\n _this.formulaListByType($(\"#formulaTypeSelect option:selected\").val());\r\n }\r\n else{\r\n for(let i = 0; i < functionlist.length; i++){\r\n if(/^[a-zA-Z]+$/.test(txt)){\r\n if(functionlist[i].n.indexOf(txt) != \"-1\"){\r\n $('
'+ functionlist[i].n +''+ functionlist[i].a +'
').appendTo($(\"#formulaTypeList\"));\r\n }\r\n }\r\n else if(functionlist[i].a.indexOf(txt) != \"-1\"){\r\n $('
'+ functionlist[i].n +''+ functionlist[i].a +'
').appendTo($(\"#formulaTypeList\"));\r\n }\r\n }\r\n }\r\n \r\n $(\"#formulaTypeList .listBox:first-child\").addClass(\"on\"); //默认公式列表第一个为选中状态\r\n });\r\n\r\n $(document).off(\"change.fxFormulaTS\").on(\"change.fxFormulaTS\", \"#formulaTypeSelect\", function(){\r\n let type = $(\"#formulaTypeSelect option:selected\").val();\r\n _this.formulaListByType(type);\r\n });\r\n\r\n $(document).off(\"click.fxListbox\").on(\"click.fxListbox\", \"#formulaTypeList .listBox\", function(){\r\n $(this).addClass(\"on\").siblings().removeClass(\"on\");\r\n });\r\n\r\n //选择公式后弹出参数栏弹框\r\n $(document).off(\"click.fxFormulaCf\").on(\"click.fxFormulaCf\", \"#luckysheet-search-formula-confirm\", function(){\r\n let formula = $(\"#luckysheet-search-formula .listBox.on\").attr(\"name\");\r\n let formulaTxt = '='+ formula.toUpperCase() +'()';\r\n \r\n $(\"#luckysheet-rich-text-editor\").html(formulaTxt);\r\n $(\"#luckysheet-functionbox-cell\").html($(\"#luckysheet-rich-text-editor\").html());\r\n\r\n _this.formulaParmDialog(formula);\r\n });\r\n\r\n //公式参数框\r\n $(document).off(\"focus.fxParamInput\").on(\"focus.fxParamInput\", \"#luckysheet-search-formula-parm .parmBox input\", function(){\r\n let parmIndex = $(this).parents(\".parmBox\").index();\r\n formula.data_parm_index = parmIndex;\r\n\r\n let formulatxt = $(this).parents(\"#luckysheet-search-formula-parm\").find(\".luckysheet-modal-dialog-title-text\").text();\r\n let parmLen = Store.luckysheet_function[formulatxt].p.length;\r\n\r\n let parmDetail, parmRepeat;\r\n if(parmIndex >= parmLen){\r\n parmDetail = Store.luckysheet_function[formulatxt].p[parmLen - 1].detail;\r\n parmRepeat = Store.luckysheet_function[formulatxt].p[parmLen - 1].repeat;\r\n }\r\n else{\r\n parmDetail = Store.luckysheet_function[formulatxt].p[parmIndex].detail;\r\n parmRepeat = Store.luckysheet_function[formulatxt].p[parmIndex].repeat;\r\n }\r\n\r\n //参数选区显示,参数值显示\r\n _this.parmTxtShow($(this).val());\r\n \r\n //计算结果\r\n _this.functionStrCompute();\r\n \r\n //参数名称和释义切换\r\n $(\"#luckysheet-search-formula-parm .parmDetailsBox\").empty();\r\n\r\n let parmName = $(this).parents(\".parmBox\").find(\".name\").text();\r\n $(''+ parmName +':'+ parmDetail +'').appendTo($(\"#luckysheet-search-formula-parm .parmDetailsBox\"));\r\n \r\n //公式参数可自增(参数自增最多5个)\r\n if(parmRepeat == \"y\"){\r\n let parmCount = $(\"#luckysheet-search-formula-parm .parmBox\").length;\r\n\r\n if(parmCount < 5 && parmIndex == (parmCount - 1)){\r\n $('
'+ locale_formulaMore.valueTitle +''+ (parmCount + 1) +'
=
').appendTo($(\"#luckysheet-search-formula-parm .parmListBox\"));\r\n }\r\n }\r\n });\r\n\r\n $(document).off(\"blur.fxParamInput\").on(\"blur.fxParamInput\", \"#luckysheet-search-formula-parm .parmBox input\", function(){\r\n let txt = $(this).val();\r\n\r\n if(formula.getfunctionParam(txt).fn == null && !formula.iscelldata(txt)){\r\n if(!isRealNum(txt) && txt != \"\" && txt.length <= 2 && txt.indexOf('\"') != 0 && txt.lastIndexOf('\"') != 0){\r\n txt = '\"' + txt + '\"';\r\n $(this).val(txt);\r\n\r\n _this.parmTxtShow(txt);\r\n _this.functionStrCompute();\r\n }\r\n }\r\n });\r\n \r\n $(document).off(\"keyup.fxParamInput\").on(\"keyup.fxParamInput\", \"#luckysheet-search-formula-parm .parmBox input\", function(){\r\n //参数选区显示,参数值显示\r\n _this.parmTxtShow($(this).val());\r\n\r\n //计算结果\r\n _this.functionStrCompute();\r\n });\r\n\r\n //点击图标选取数据范围\r\n $(document).off(\"click.fxParamI\").on(\"click.fxParamI\", \"#luckysheet-search-formula-parm .parmBox i\", function(){\r\n formula.data_parm_index = $(this).parents(\".parmBox\").index();\r\n \r\n //选取范围弹出框\r\n $(\"#luckysheet-search-formula-parm\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n\r\n $(\"#luckysheet-search-formula-parm-select\").remove();\r\n \r\n if($(this).parents(\".parmBox\").find(\".txt input\").val() == \"\"){\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-search-formula-parm-select\", \r\n \"addclass\": \"luckysheet-search-formula-parm-select\", \r\n \"title\": locale_formulaMore.tipSelectDataRange, \r\n \"content\": \"\", \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n }\r\n else{\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-search-formula-parm-select\", \r\n \"addclass\": \"luckysheet-search-formula-parm-select\", \r\n \"title\": locale_formulaMore.tipSelectDataRange, \r\n \"content\": \"\", \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n }\r\n\r\n let $t = $(\"#luckysheet-search-formula-parm-select\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 300).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-search-formula-parm-select\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n \r\n //参数选区虚线框\r\n _this.parmTxtShow($(this).parents(\".parmBox\").find(\".txt input\").val());\r\n });\r\n\r\n //点击确定\r\n $(document).off(\"click.fxParamCf\").on(\"click.fxParamCf\", \"#luckysheet-search-formula-parm-confirm\", function(){\r\n $(\"#luckysheet-wa-functionbox-confirm\").click();\r\n });\r\n\r\n //选取范围后传回参数栏弹框\r\n $(document).off(\"click.fxParamSelectCf\").on(\"click.fxParamSelectCf\", \"#luckysheet-search-formula-parm-select-confirm\", function(){\r\n let parmIndex = $(\"#luckysheet-search-formula-parm-select-input\").attr(\"data_parm_index\");\r\n\r\n $(\"#luckysheet-search-formula-parm-select\").hide();\r\n $(\"#luckysheet-search-formula-parm\").show();\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(parmIndex).find(\".txt input\").focus();\r\n });\r\n },\r\n formulaListDialog: function(){\r\n let _this = this;\r\n\r\n let _locale = locale();\r\n let locale_formulaMore = _locale.formulaMore;\r\n let locale_button = _locale.button\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-search-formula\").remove();\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-search-formula\", \r\n \"addclass\": \"luckysheet-search-formula\", \r\n \"title\": \"\", \r\n \"content\": \"
\", \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-search-formula\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 300).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-search-formula\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3, \"user-select\": \"none\" }).show();\r\n \r\n _this.formulaListByType(\"0\"); //默认公式列表为类型0\r\n $(\"#searchFormulaListInput\").focus();\r\n },\r\n formulaListByType: function(type){\r\n $(\"#formulaTypeList\").empty();\r\n let functionlist = Store.functionlist;\r\n \r\n for(let i = 0; i < functionlist.length; i++){\r\n if((type == \"-1\" && functionlist[i].t > 14) || functionlist[i].t == type){\r\n $('
'+ functionlist[i].n +''+ functionlist[i].a +'
').appendTo($(\"#formulaTypeList\"));\r\n }\r\n }\r\n\r\n $(\"#formulaTypeList .listBox:first-child\").addClass(\"on\"); //默认公式列表第一个为选中状态\r\n },\r\n formulaParmDialog: function(formulaTxt, parm){ //参数弹出框\r\n let parm_title = '',\r\n parm_content = '',\r\n parm_list_content = '';\r\n\r\n let _locale = locale();\r\n let locale_formulaMore = _locale.formulaMore;\r\n let locale_button = _locale.button;\r\n let functionlist = Store.functionlist;\r\n\r\n for(let i = 0; i < functionlist.length; i++){\r\n if(functionlist[i].n == formulaTxt.toUpperCase()){\r\n parm_title = functionlist[i].n;\r\n\r\n for(let j = 0; j < functionlist[i].p.length; j++){\r\n if(parm == null){\r\n //无参数\r\n parm_list_content += '
'+\r\n '
'+ functionlist[i].p[j].name +'
'+\r\n '
'+\r\n '' +\r\n ''+\r\n '
'+\r\n '
=
'+\r\n '
';\r\n }\r\n else{\r\n //有参数\r\n if(parm[j] == null){\r\n parm[j] = \"\";\r\n }\r\n\r\n parm_list_content += '
'+\r\n '
'+ functionlist[i].p[j].name +'
'+\r\n '
'+\r\n ''+\r\n ''+\r\n '
'+\r\n '
=
'+\r\n '
';\r\n }\r\n }\r\n\r\n parm_content = '
'+\r\n '
'+ parm_list_content +'
'+\r\n '
'+ functionlist[i].d +'
'+\r\n '
'+\r\n '
'+locale_formulaMore.calculationResult+' =
'+\r\n '
';\r\n }\r\n }\r\n\r\n $(\"#luckysheet-search-formula\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n \r\n $(\"#luckysheet-search-formula-parm\").remove();\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-search-formula-parm\", \r\n \"addclass\": \"luckysheet-search-formula-parm\", \r\n \"title\": parm_title, \r\n \"content\": parm_content, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-search-formula-parm\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 300).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-search-formula-parm\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n \r\n //参数栏第一个参数聚焦,显示选取虚线框\r\n $(\"#luckysheet-search-formula-parm .parmBox:eq(0) input\").focus();\r\n\r\n //遍历参数,有参数显示值,无显示空\r\n $(\"#luckysheet-search-formula-parm .parmBox\").each(function(index,e){\r\n let parmtxt = $(e).find(\".txt input\").val();\r\n \r\n if(formula.getfunctionParam(parmtxt).fn == null){ //参数不是公式\r\n if(formula.iscelldata(parmtxt)){ //参数是选区\r\n let txtdata = luckysheet_getcelldata(parmtxt).data;\r\n\r\n if(getObjType(txtdata) == \"array\"){ //参数为多个单元格选区\r\n let txtArr = [];\r\n \r\n for(let i = 0; i < txtdata.length; i++){\r\n for(let j = 0; j < txtdata[i].length; j++){\r\n let cell = txtdata[i][j];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n txtArr.push(null);\r\n }\r\n else{\r\n txtArr.push(cell.v);\r\n }\r\n }\r\n }\r\n\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(index).find(\".val\").text(\" = {\"+ txtArr.join(\",\") +\"}\");\r\n }\r\n else{ //参数为单个单元格选区\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(index).find(\".val\").text(\" = {\"+ txtdata.v +\"}\");\r\n }\r\n }\r\n else{ //参数不是选区\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(index).find(\".val\").text(\" = {\"+ parmtxt +\"}\");\r\n }\r\n }\r\n else{ //参数是公式\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(index).find(\".val\").text(\" = {\"+ (new Function(\"return \" + $.trim(formula.functionParserExe(\"=\" + parmtxt)))()) +\"}\");\r\n }\r\n })\r\n\r\n $(\"#luckysheet-formula-functionrange .luckysheet-formula-functionrange-highlight\").remove(); \r\n formula.data_parm_index = 0;\r\n formula.rangestart = true;\r\n },\r\n parmTxtShow: function(parmtxt){\r\n if(formula.getfunctionParam(parmtxt).fn == null){ //参数不是公式\r\n if(formula.iscelldata(parmtxt)){ //参数是选区\r\n let cellrange = formula.getcellrange(parmtxt);\r\n let r1 = cellrange.row[0], \r\n r2 = cellrange.row[1], \r\n c1 = cellrange.column[0], \r\n c2 = cellrange.column[1];\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({ \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1 \r\n }).show();\r\n $(\"#luckysheet-formula-help-c\").hide();\r\n\r\n luckysheet_count_show(col_pre, row_pre, col - col_pre - 1, row - row_pre - 1, cellrange.row, cellrange.column);\r\n\r\n let txtdata = luckysheet_getcelldata(parmtxt).data;\r\n if(getObjType(txtdata) == \"array\"){ //参数为多个单元格选区\r\n let txtArr = [];\r\n \r\n for(let i = 0; i < txtdata.length; i++){\r\n for(let j = 0; j < txtdata[i].length; j++){\r\n let cell = txtdata[i][j];\r\n\r\n if(cell == null || isRealNull(cell.v)){\r\n txtArr.push(null);\r\n }\r\n else{\r\n txtArr.push(cell.v);\r\n }\r\n }\r\n }\r\n\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(formula.data_parm_index).find(\".val\").text(\" = {\"+ txtArr.join(\",\") +\"}\");\r\n }\r\n else{ //参数为单个单元格选区\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(formula.data_parm_index).find(\".val\").text(\" = {\"+ txtdata.v +\"}\");\r\n }\r\n }\r\n else{ //参数不是选区\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(formula.data_parm_index).find(\".val\").text(\" = {\"+ parmtxt +\"}\");\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").hide();\r\n }\r\n }\r\n else{ \r\n //参数是公式\r\n let txt;\r\n for(let k = 0; k < formula.getfunctionParam(parmtxt).param.length; k++){\r\n if(formula.iscelldata(formula.getfunctionParam(parmtxt).param[k])){\r\n txt = formula.getfunctionParam(parmtxt).param[k];\r\n break;\r\n }\r\n }\r\n\r\n let cellrange = formula.getcellrange(txt);\r\n let r1 = cellrange.row[0], \r\n r2 = cellrange.row[1], \r\n c1 = cellrange.column[0], \r\n c2 = cellrange.column[1];\r\n let row = Store.visibledatarow[r2], \r\n row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1];\r\n let col = Store.visibledatacolumn[c2], \r\n col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1];\r\n\r\n $(\"#luckysheet-formula-functionrange-select\").css({ \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1 \r\n }).show();\r\n $(\"#luckysheet-formula-help-c\").hide();\r\n\r\n luckysheet_count_show(col_pre, row_pre, col - col_pre - 1, row - row_pre - 1, cellrange.row, cellrange.column);\r\n\r\n $(\"#luckysheet-search-formula-parm .parmBox\").eq(formula.data_parm_index).find(\".val\").text(\" = {\"+ (new Function(\"return \" + $.trim(formula.functionParserExe(\"=\" + parmtxt)))()) +\"}\");\r\n }\r\n },\r\n functionStrCompute: function(){\r\n let isVal = true; //参数不为空\r\n let parmValArr = []; //参数值集合\r\n let lvi = -1; //最后一个有值的参数索引\r\n\r\n let formulatxt = $(\"#luckysheet-search-formula-parm\").find(\".luckysheet-modal-dialog-title-text\").text();\r\n let p = Store.luckysheet_function[formulatxt].p;\r\n \r\n $(\"#luckysheet-search-formula-parm .parmBox\").each(function(i, e){\r\n let parmtxt = $(e).find(\".txt input\").val();\r\n\r\n let parmRequire;\r\n if(i < p.length){\r\n parmRequire = p[i].require;\r\n }\r\n else{\r\n parmRequire = p[p.length - 1].require;\r\n }\r\n\r\n if(parmtxt == \"\" && parmRequire == \"m\"){\r\n isVal = false;\r\n }\r\n\r\n if(parmtxt != \"\"){\r\n lvi = i;\r\n }\r\n });\r\n\r\n //单元格显示\r\n let functionHtmlTxt;\r\n if(lvi == -1){\r\n functionHtmlTxt = \"=\" + $(\"#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text\").text() + \"()\"; \r\n }\r\n else if(lvi == 0){\r\n functionHtmlTxt = \"=\" + $(\"#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text\").text() + \"(\" + $(\"#luckysheet-search-formula-parm .parmBox\").eq(0).find(\".txt input\").val() + \")\"; \r\n }\r\n else{\r\n for(let j = 0; j <= lvi; j++){\r\n parmValArr.push($(\"#luckysheet-search-formula-parm .parmBox\").eq(j).find(\".txt input\").val());\r\n }\r\n\r\n functionHtmlTxt = \"=\" + $(\"#luckysheet-search-formula-parm .luckysheet-modal-dialog-title-text\").text() + \"(\" + parmValArr.join(\",\") + \")\"; \r\n }\r\n\r\n let function_str = formula.functionHTMLGenerate(functionHtmlTxt);\r\n $(\"#luckysheet-rich-text-editor\").html(function_str);\r\n $(\"#luckysheet-functionbox-cell\").html($(\"#luckysheet-rich-text-editor\").html());\r\n \r\n if(isVal){ //公式计算\r\n let fp = $.trim(formula.functionParserExe($(\"#luckysheet-rich-text-editor\").text()));\r\n \r\n let result = null;\r\n\r\n try {\r\n result = new Function(\"return \" + fp)();\r\n } \r\n catch (e) {\r\n result = formula.error.n;\r\n }\r\n\r\n $(\"#luckysheet-search-formula-parm .result span\").text(result);\r\n }\r\n }\r\n}\r\n\r\nexport default insertFormula;","import { selectionCopyShow, selectIsOverlap } from './select';\r\nimport { luckyColor, iconfontObjects } from './constant';\r\nimport luckysheetConfigsetting from './luckysheetConfigsetting';\r\nimport luckysheetMoreFormat from './moreFormat';\r\nimport alternateformat from './alternateformat';\r\nimport conditionformat from './conditionformat';\r\nimport server from './server';\r\nimport { luckysheet_searcharray } from './sheetSearch';\r\nimport luckysheetFreezen from './freezen';\r\nimport luckysheetsizeauto from './resize';\r\nimport { createFilter } from './filter';\r\nimport luckysheetSearchReplace from './searchReplace';\r\nimport luckysheetLocationCell from './locationCell';\r\nimport ifFormulaGenerator from './ifFormulaGenerator';\r\nimport {luckysheetupdateCell} from './updateCell';\r\nimport insertFormula from './insertFormula';\r\nimport sheetmanage from './sheetmanage';\r\nimport luckysheetPostil from './postil';\r\nimport { isRealNum, isRealNull, isEditMode, hasPartMC } from '../global/validate';\r\nimport tooltip from '../global/tooltip';\r\nimport editor from '../global/editor';\r\nimport { genarate, update, is_date } from '../global/format';\r\nimport { jfrefreshgrid, luckysheetrefreshgrid } from '../global/refresh';\r\nimport { sortSelection } from '../global/sort';\r\nimport luckysheetformula from '../global/formula';\r\nimport { rowLocationByIndex, colLocationByIndex } from '../global/location';\r\nimport { isdatatypemulti } from '../global/datecontroll';\r\nimport { rowlenByRange, getCellTextSplitArr } from '../global/getRowlen';\r\nimport { setcellvalue } from '../global/setdata';\r\nimport { getFontStyleByCell, checkstatusByCell} from '../global/getdata';\r\nimport { countfunc } from '../global/count';\r\nimport { hideMenuByCancel } from '../global/cursorPos';\r\nimport { getSheetIndex, getRangetxt, getluckysheetfile } from '../methods/get';\r\nimport { setluckysheetfile } from '../methods/set';\r\nimport {isInlineStringCell,updateInlineStringFormat,convertCssToStyleList,inlineStyleAffectAttribute,updateInlineStringFormatOutside} from './inlineString';\r\nimport { replaceHtml, getObjType, rgbTohex, mouseclickposition, luckysheetfontformat,luckysheetContainerFocus } from '../utils/util';\r\nimport {openProtectionModal,checkProtectionFormatCells,checkProtectionNotEnable} from './protection';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\nconst menuButton = {\r\n \"menu\": '
${item}
',\r\n // \"item\": '
${name} ${example}
',\r\n \"item\": '
${name} ${example}
',\r\n \"split\": '
',\r\n \"color\": '
${resetColor}
${coloritem}
',\r\n \"coloritem\": '
${name}
',\r\n \"subcolor\": '
',\r\n \"rightclickmenu\": null,\r\n \"submenuhide\": {},\r\n focus: function($obj, value){\r\n if($obj.attr(\"id\")==\"luckysheet-icon-font-family-menuButton\"){\r\n if (isdatatypemulti(value)[\"num\"]) {\r\n let _locale = locale();\r\n const locale_fontarray = _locale.fontarray;\r\n value = locale_fontarray[parseInt(value)];\r\n if(value==null){\r\n value = this.defualtFont[itemvalue];\r\n }\r\n }\r\n }\r\n $obj.find(\".luckysheet-cols-menuitem\").find(\"span.icon\").html(\"\");\r\n if(value == null){\r\n $obj.find(\".luckysheet-cols-menuitem\").eq(0).find(\"span.icon\").html('');\r\n }\r\n else{\r\n $obj.find(\".luckysheet-cols-menuitem[itemvalue='\"+ value +\"']\").find(\"span.icon\").html('');\r\n }\r\n },\r\n createButtonMenu: function(itemdata){\r\n let itemset = \"\";\r\n let _this = this;\r\n\r\n for(let i = 0; i < itemdata.length; i++){\r\n let item = itemdata[i];\r\n\r\n if(item.value==\"split\"){\r\n itemset += _this.split;\r\n }\r\n else{\r\n if(item.example==\"more\"){\r\n // itemset += replaceHtml(_this.item, {\"value\": item.value, \"name\": item.text, \"example\": \"►\", \"sub\": \"luckysheet-cols-submenu\"});\r\n itemset += replaceHtml(_this.item, {\"value\": item.value, \"name\": item.text, \"example\": \"\", \"sub\": \"luckysheet-cols-submenu\", \"iconClass\": \"iconfont luckysheet-iconfont-youjiantou\"});\r\n\r\n }\r\n else{\r\n itemset += replaceHtml(_this.item, {\"value\": item.value, \"name\": item.text, \"example\": item.example, \"sub\": \"\", \"iconClass\": \"\"});\r\n }\r\n }\r\n }\r\n\r\n return itemset;\r\n },\r\n cancelPaintModel: function(){\r\n let _this = this;\r\n\r\n $(\"#luckysheet-sheettable_0\").removeClass(\"luckysheetPaintCursor\");\r\n\r\n if(Store.luckysheet_copy_save[\"dataSheetIndex\"] == Store.currentSheetIndex){\r\n Store.luckysheet_selection_range = [];\r\n selectionCopyShow();\r\n }\r\n else{\r\n Store.luckysheetfile[getSheetIndex(Store.luckysheet_copy_save[\"dataSheetIndex\"])].luckysheet_selection_range = [];\r\n }\r\n \r\n Store.luckysheet_copy_save = {};\r\n\r\n _this.luckysheetPaintModelOn = false;\r\n $(\"#luckysheetpopover\").fadeOut(200,function(){\r\n $(\"#luckysheetpopover\").remove();\r\n });\r\n },\r\n luckysheetPaintModelOn:false,\r\n luckysheetPaintSingle: false,\r\n initialMenuButton: function(){\r\n let _this = this;\r\n\r\n //格式刷\r\n $(\"#luckysheet-icon-paintformat\").click(function(){\r\n\r\n let _locale = locale();\r\n let locale_paint = _locale.paint;\r\n\r\n if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(locale_paint.tipSelectRange);\r\n }\r\n else{\r\n tooltip.info(\"\",locale_paint.tipSelectRange);\r\n }\r\n return;\r\n }\r\n else if(Store.luckysheet_select_save.length > 1){\r\n if(isEditMode()){\r\n alert(locale_paint.tipNotMulti);\r\n }\r\n else{\r\n tooltip.info(\"\",locale_paint.tipNotMulti);\r\n }\r\n return;\r\n }\r\n\r\n tooltip.popover(\" \"+locale_paint.start+\"\", \"topCenter\", true, null, locale_paint.end,function(){\r\n _this.cancelPaintModel();\r\n });\r\n $(\"#luckysheet-sheettable_0\").addClass(\"luckysheetPaintCursor\");\r\n\r\n Store.luckysheet_selection_range = [{ \"row\": Store.luckysheet_select_save[0].row, \"column\": Store.luckysheet_select_save[0].column }];\r\n selectionCopyShow();\r\n\r\n let RowlChange = false, HasMC = false;\r\n for(let r = Store.luckysheet_select_save[0].row[0]; r <= Store.luckysheet_select_save[0].row[1]; r++){\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n if (Store.config[\"rowlen\"] != null && (r in Store.config[\"rowlen\"])){\r\n RowlChange = true;\r\n }\r\n\r\n for(let c = Store.luckysheet_select_save[0].column[0]; c <= Store.luckysheet_select_save[0].column[1]; c++){\r\n let cell = Store.flowdata[r][c];\r\n \r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell) && cell.mc.rs != null){\r\n HasMC = true;\r\n }\r\n }\r\n }\r\n Store.luckysheet_copy_save = { \"dataSheetIndex\": Store.currentSheetIndex, \"copyRange\": [{ \"row\": Store.luckysheet_select_save[0].row, \"column\": Store.luckysheet_select_save[0].column }], \"RowlChange\": RowlChange, \"HasMC\": HasMC };\r\n\r\n _this.luckysheetPaintModelOn = true;\r\n _this.luckysheetPaintSingle = true;\r\n });\r\n $(\"#luckysheet-icon-paintformat\").dblclick(function(){\r\n let _locale = locale();\r\n let locale_paint = _locale.paint;\r\n if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(locale_paint.tipSelectRange);\r\n }\r\n else{\r\n tooltip.info(\"\",locale_paint.tipSelectRange); \r\n }\r\n return;\r\n }\r\n else if(Store.luckysheet_select_save.length > 1){\r\n if(isEditMode()){\r\n alert(locale_paint.tipNotMulti);\r\n }\r\n else{\r\n tooltip.info(\"\",locale_paint.tipNotMulti);\r\n }\r\n return;\r\n }\r\n\r\n tooltip.popover(\" \"+locale_paint.start, \"topCenter\", true, null, locale_paint.end,function(){\r\n _this.cancelPaintModel();\r\n });\r\n $(\"#luckysheet-sheettable_0\").addClass(\"luckysheetPaintCursor\");\r\n\r\n Store.luckysheet_selection_range = [{ \"row\": Store.luckysheet_select_save[0].row, \"column\": Store.luckysheet_select_save[0].column }];\r\n selectionCopyShow();\r\n\r\n let RowlChange = false, HasMC = false;\r\n for(let r = Store.luckysheet_select_save[0].row[0]; r <= Store.luckysheet_select_save[0].row[1]; r++){\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n if (Store.config[\"rowlen\"] != null && (r in Store.config[\"rowlen\"])){\r\n RowlChange = true;\r\n }\r\n\r\n for(let c = Store.luckysheet_select_save[0].column[0]; c <= Store.luckysheet_select_save[0].column[1]; c++){\r\n let cell = Store.flowdata[r][c];\r\n \r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell) && cell.mc.rs != null){\r\n HasMC = true;\r\n }\r\n }\r\n }\r\n Store.luckysheet_copy_save = { \"dataSheetIndex\": Store.currentSheetIndex, \"copyRange\": [{ \"row\": Store.luckysheet_select_save[0].row, \"column\": Store.luckysheet_select_save[0].column }], \"RowlChange\": RowlChange, \"HasMC\": HasMC };\r\n \r\n _this.luckysheetPaintModelOn = true;\r\n _this.luckysheetPaintSingle = false;\r\n });\r\n\r\n //货币格式\r\n $(\"#luckysheet-icon-currency\").click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n\r\n _this.updateFormat(d, \"ct\", \"¥ #.00\");\r\n });\r\n\r\n //百分比\r\n $(\"#luckysheet-icon-percent\").click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n\r\n _this.updateFormat(d, \"ct\", \"0.00%\");\r\n });\r\n\r\n //减少小数位数\r\n $(\"#luckysheet-icon-fmt-decimal-decrease\").click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n let row_index = Store.luckysheet_select_save[0][\"row_focus\"], \r\n col_index = Store.luckysheet_select_save[0][\"column_focus\"];\r\n let foucsStatus = _this.checkstatus(d, row_index, col_index, \"ct\");\r\n let cell = d[row_index][col_index];\r\n\r\n if(foucsStatus == null || foucsStatus.t != \"n\"){\r\n return;\r\n }\r\n\r\n if(foucsStatus.fa == \"General\"){\r\n let mask = genarate(cell.v);\r\n foucsStatus = mask[1];\r\n }\r\n\r\n //万亿格式\r\n let reg = /^(w|W)((0?)|(0\\.0+))$/;\r\n if(reg.test(foucsStatus.fa)){\r\n if(foucsStatus.fa.indexOf(\".\") > -1){\r\n if(foucsStatus.fa.substr(-2) == \".0\"){\r\n _this.updateFormat(d, \"ct\", foucsStatus.fa.split(\".\")[0]);\r\n }\r\n else{\r\n _this.updateFormat(d, \"ct\", foucsStatus.fa.substr(0, foucsStatus.fa.length - 1)); \r\n }\r\n }\r\n else{\r\n _this.updateFormat(d, \"ct\", foucsStatus.fa);\r\n }\r\n\r\n return;\r\n }\r\n\r\n let prefix = \"\", main = \"\";\r\n if(foucsStatus.fa.indexOf(\".\")>-1){\r\n fa = foucsStatus.fa.split(\".\");\r\n prefix = fa[0];\r\n main = fa[1];\r\n }\r\n else{\r\n return;\r\n }\r\n\r\n let fa = main.split(\"\");\r\n let tail = \"\";\r\n for(let i = fa.length-1; i >= 0; i--){\r\n let c = fa[i];\r\n if((c!=\"#\" && c!=\"0\" && c!=\",\" && isNaN(parseInt(c)))) {\r\n tail = c + tail;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n\r\n let fmt = \"\";\r\n if(foucsStatus.fa.indexOf(\".\")>-1){\r\n let suffix = main;\r\n if(tail.length>0){\r\n suffix = main.replace(tail, \"\");\r\n }\r\n\r\n let pos = suffix.replace(/#/g, \"0\");\r\n pos = pos.substr(0, pos.length-1);\r\n if(pos==\"\"){\r\n fmt = prefix + tail;\r\n }\r\n else{\r\n fmt = prefix + \".\" + pos + tail;\r\n }\r\n }\r\n\r\n _this.updateFormat(d, \"ct\", fmt);\r\n });\r\n\r\n //增加小数位数\r\n $(\"#luckysheet-icon-fmt-decimal-increase\").click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n let row_index = Store.luckysheet_select_save[0][\"row_focus\"], \r\n col_index = Store.luckysheet_select_save[0][\"column_focus\"];\r\n let foucsStatus = _this.checkstatus(d, row_index, col_index, \"ct\");\r\n let cell = d[row_index][col_index];\r\n\r\n if(foucsStatus== null || foucsStatus.t != \"n\"){\r\n return;\r\n }\r\n\r\n if(foucsStatus.fa == \"General\"){\r\n let mask = genarate(cell.v);\r\n foucsStatus = mask[1];\r\n }\r\n\r\n if(foucsStatus.fa == \"General\"){\r\n _this.updateFormat(d, \"ct\", \"#.0\");\r\n return;\r\n }\r\n\r\n //万亿格式\r\n let reg = /^(w|W)((0?)|(0\\.0+))$/;\r\n if(reg.test(foucsStatus.fa)){\r\n if(foucsStatus.fa.indexOf(\".\") > -1){\r\n _this.updateFormat(d, \"ct\", foucsStatus.fa + \"0\");\r\n }\r\n else{\r\n if(foucsStatus.fa.substr(-1) == \"0\"){\r\n _this.updateFormat(d, \"ct\", foucsStatus.fa + \".0\");\r\n }\r\n else{\r\n _this.updateFormat(d, \"ct\", foucsStatus.fa + \"0.0\");\r\n }\r\n }\r\n\r\n return;\r\n }\r\n\r\n let prefix = \"\", main = \"\";\r\n if(foucsStatus.fa.indexOf(\".\")>-1){\r\n fa = foucsStatus.fa.split(\".\");\r\n prefix = fa[0];\r\n main = fa[1];\r\n }\r\n else{\r\n main = foucsStatus.fa;\r\n }\r\n\r\n let fa = main.split(\"\");\r\n let tail = \"\";\r\n for(let i = fa.length - 1; i >= 0; i--){\r\n let c = fa[i];\r\n if(( c!=\"#\" && c!=\"0\" && c!=\",\" && isNaN(parseInt(c)))) {\r\n tail = c + tail;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n\r\n let fmt = \"\";\r\n if(foucsStatus.fa.indexOf(\".\")>-1){\r\n let suffix = main;\r\n if(tail.length>0){\r\n suffix = main.replace(tail, \"\");\r\n }\r\n\r\n let pos = suffix.replace(/#/g, \"0\");\r\n pos += \"0\";\r\n fmt = prefix + \".\" + pos + tail;\r\n }\r\n else{\r\n if(tail.length>0){\r\n fmt = main.replace(tail, \"\") + \".0\" + tail;\r\n }\r\n else{\r\n fmt = main + \".0\" + tail;\r\n }\r\n }\r\n\r\n\r\n _this.updateFormat(d, \"ct\", fmt);\r\n });\r\n\r\n //更多格式\r\n $(\"#luckysheet-icon-fmt-other\").click(function(){\r\n const _locale = locale();\r\n const locale_format = _locale.format;\r\n const locale_defaultFmt = _locale.defaultFmt;\r\n\r\n let menuButtonId = $(this).attr(\"id\")+\"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n let itemdata = locale_defaultFmt;\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n // luckysheet-menuButton-sub\r\n let menu = replaceHtml(_this.menu, {\"id\": \"fmt-other\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\"});\r\n\r\n let subitemdata = [\r\n {\"text\":locale_format.moreCurrency+\"...\", \"value\":\"morecurrency\", \"example\":\"\"},\r\n {\"text\":locale_format.moreDateTime+\"...\", \"value\":\"moredatetime\", \"example\":\"\"},\r\n {\"text\":locale_format.moreNumber+\"...\", \"value\":\"moredigit\", \"example\":\"\"}\r\n ];\r\n let subitemset = _this.createButtonMenu(subitemdata);\r\n let submenu = replaceHtml(_this.menu, {\"id\": \"fmtOtherSelf\", \"item\": subitemset, \"subclass\": \"luckysheet-menuButton-sub\"});\r\n \r\n //luckysheet-icon-fmt-other-menuButton_sub\r\n $(\"body\").append(menu+submenu);\r\n $menuButton = $(\"#\" + menuButtonId).width(250);\r\n _this.focus($menuButton);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\"),itemname = $t.attr(\"itemname\");\r\n $(\"#luckysheet-icon-fmt-other\").find(\".luckysheet-toolbar-menu-button-caption\").html(\" \"+ itemname +\" \");\r\n\r\n if(itemvalue == \"fmtOtherSelf\"){\r\n return;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);//取数据\r\n _this.focus($menuButton, itemvalue);\r\n\r\n _this.updateFormat(d, \"ct\", itemvalue);\r\n });\r\n\r\n //更多格式\r\n $(\"#luckysheet-icon-fmtOtherSelf-menuButton\").find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n $(\"#luckysheet-icon-fmtOtherSelf-menuButton\").hide();\r\n luckysheetContainerFocus();\r\n\r\n let itemvalue = $(this).attr(\"itemvalue\");\r\n\r\n luckysheetMoreFormat.createDialog(itemvalue);\r\n luckysheetMoreFormat.init();\r\n })\r\n } else {\r\n const text =$(this).find(\".luckysheet-toolbar-menu-button-caption\").text().trim();\r\n const format = locale_defaultFmt.find(f => f.text === text);\r\n if(format) {\r\n _this.focus($menuButton, format.value);\r\n }\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top+25, \"lefttop\");\r\n });\r\n\r\n //字体设置\r\n $(\"#luckysheet-icon-font-family\").mousedown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(){\r\n let menuButtonId = $(this).attr(\"id\")+\"-menuButton\";\r\n let $menuButton = $(\"#\"+menuButtonId);\r\n if($menuButton.length == 0){\r\n // const locale_fontarray = locale().fontarray;\r\n // let itemdata = [];\r\n\r\n // for(let a=0;a\"+fItem+\"\";\r\n // ret.example = \"\";\r\n // itemdata.push(ret);\r\n // }\r\n\r\n let itemset = _this.createButtonMenu(_this.fontSelectList);\r\n\r\n let menu = replaceHtml(_this.menu, {\"id\": \"font-family\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\"});\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\"+menuButtonId).width(200);\r\n _this.focus($menuButton);\r\n\r\n $menuButton.on(\"click\", \".luckysheet-cols-menuitem\", function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\"), itemname = $t.attr(\"itemname\");\r\n _this.focus($menuButton, itemvalue);\r\n $(\"#luckysheet-icon-font-family\").find(\".luckysheet-toolbar-menu-button-caption\").html(\" \"+ itemname +\" \");\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n _this.updateFormat(d, \"ff\", itemvalue);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top+25, \"lefttop\");\r\n });\r\n\r\n //字体颜色\r\n $(\"#luckysheet-icon-text-color\").mousedown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let color = $(this).attr(\"color\");\r\n if(color == null){\r\n color = \"#000000\";\r\n }\r\n _this.updateFormat(d, \"fc\", color);\r\n });\r\n\r\n\r\n\r\n $(\"#luckysheet-icon-text-color-menu\").mousedown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\"+menuButtonId);\r\n\r\n if($menuButton.length == 0){\r\n const _locale = locale();\r\n const locale_toolbar = _locale.toolbar;\r\n const locale_button = _locale.button;\r\n const locale_alternatingColors = _locale.alternatingColors;\r\n let itemdata = [\r\n {\"name\":locale_toolbar.alternatingColors+\"...\", \"id\":\"luckysheet-color-alternate\", \"example\":\"\"}\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n let subid = \"text-color-self\";\r\n let coloritem = replaceHtml(_this.coloritem, {\"class\": \"luckysheet-icon-alternateformat\", \"name\": locale_toolbar.alternatingColors+\"...\"});\r\n let menu = replaceHtml(_this.color, {\"id\":menuButtonId, \"coloritem\": coloritem, \"colorself\": subid, \"sub\": \"\",\"resetColor\":locale_toolbar.resetColor});\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId);\r\n\r\n $(\"#\" + menuButtonId).find(\".luckysheet-color-selected\").spectrum({\r\n showPalette: true,\r\n showPaletteOnly: true,\r\n preferredFormat: \"hex\",\r\n clickoutFiresChange: false,\r\n showInitial: true,\r\n showInput: true,\r\n flat: true,\r\n hideAfterPaletteSelect: true,\r\n showSelectionPalette: true,\r\n maxPaletteSize: 8,\r\n maxSelectionSize: 8,\r\n cancelText: locale_button.cancel,\r\n chooseText: locale_button.confirm,\r\n togglePaletteMoreText: locale_toolbar.customColor,\r\n togglePaletteLessText: locale_toolbar.collapse,\r\n togglePaletteOnly: true,\r\n clearText: locale_toolbar.clearText,\r\n color: luckysheetConfigsetting.defaultTextColor,\r\n noColorSelectedText: locale_toolbar.noColorSelectedText,\r\n localStorageKey: \"spectrum.textcolor\" + server.gridKey,\r\n palette: [[\"#000\",\"#444\",\"#666\",\"#999\",\"#ccc\",\"#eee\",\"#f3f3f3\",\"#fff\"],\r\n [\"#f00\",\"#f90\",\"#ff0\",\"#0f0\",\"#0ff\",\"#00f\",\"#90f\",\"#f0f\"],\r\n [\"#f4cccc\",\"#fce5cd\",\"#fff2cc\",\"#d9ead3\",\"#d0e0e3\",\"#cfe2f3\",\"#d9d2e9\",\"#ead1dc\"],\r\n [\"#ea9999\",\"#f9cb9c\",\"#ffe599\",\"#b6d7a8\",\"#a2c4c9\",\"#9fc5e8\",\"#b4a7d6\",\"#d5a6bd\"],\r\n [\"#e06666\",\"#f6b26b\",\"#ffd966\",\"#93c47d\",\"#76a5af\",\"#6fa8dc\",\"#8e7cc3\",\"#c27ba0\"],\r\n [\"#c00\",\"#e69138\",\"#f1c232\",\"#6aa84f\",\"#45818e\",\"#3d85c6\",\"#674ea7\",\"#a64d79\"],\r\n [\"#900\",\"#b45f06\",\"#bf9000\",\"#38761d\",\"#134f5c\",\"#0b5394\",\"#351c75\",\"#741b47\"],\r\n [\"#600\",\"#783f04\",\"#7f6000\",\"#274e13\",\"#0c343d\",\"#073763\",\"#20124d\",\"#4c1130\"]],\r\n change: function (color) {\r\n if (color != null) {\r\n color = color.toHexString();\r\n }\r\n else {\r\n color = \"#000\";\r\n }\r\n\r\n // $(\"#luckysheet-icon-text-color .luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", color);\r\n // 下边框换成了一个DIV\r\n $(\"#luckysheet-icon-text-color .text-color-bar\").css(\"background-color\", color);\r\n $(\"#luckysheet-icon-text-color\").attr(\"color\", color);\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"fc\", color);\r\n\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n /* 备注:在单元格编辑状态下切换了文本的颜色存在bug,此处需设置编辑框的color样式, */\r\n $(\"#luckysheet-input-box\").css(\"color\",color);\r\n },\r\n });\r\n\r\n $menuButton.find(\".luckysheet-color-reset\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $input = $(\"#\"+ menuButtonId).find(\".luckysheet-color-selected\");\r\n $input.val(\"#000000\");\r\n $(\"#luckysheet-icon-text-color\").attr(\"color\", null);\r\n $input.spectrum(\"set\", \"#000000\");\r\n $(\"#luckysheet-icon-text-color .luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", \"#000000\");\r\n \r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"fc\", null);\r\n });\r\n\r\n //交替颜色\r\n $menuButton.find(\".luckysheet-icon-alternateformat\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n if(Store.luckysheet_select_save.length > 1){\r\n if(isEditMode()){\r\n alert(locale_alternatingColors.errorInfo);\r\n }\r\n else{\r\n tooltip.info(locale_alternatingColors.errorInfo, \"\");\r\n }\r\n return;\r\n }\r\n\r\n let range = $.extend(true, {}, Store.luckysheet_select_save[0]);\r\n\r\n let isExists = alternateformat.rangeIsExists(range)[0];\r\n if(!isExists){\r\n alternateformat.modelfocusIndex = 0;\r\n alternateformat.new(range); \r\n }\r\n\r\n alternateformat.init();\r\n alternateformat.perfect();\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n\r\n let offsetTop = $(this).offset().top+26;\r\n setTimeout(function(){\r\n let $input = $(\"#\" + menuButtonId).find(\".luckysheet-color-selected\");\r\n $input.spectrum(\"set\", $input.val());\r\n mouseclickposition($menuButton, menuleft-28, offsetTop, \"lefttop\");\r\n }, 1);\r\n });\r\n\r\n //背景颜色\r\n $(\"#luckysheet-icon-cell-color\").click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let color = $(this).attr(\"color\");\r\n if(color == null){\r\n color = \"#ffffff\";\r\n }\r\n _this.updateFormat(d, \"bg\", color);\r\n });\r\n\r\n $(\"#luckysheet-icon-cell-color-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n let subid = \"cell-color-self\";\r\n\r\n const _locale = locale();\r\n const locale_toolbar = _locale.toolbar;\r\n const locale_button = _locale.button;\r\n const locale_alternatingColors = _locale.alternatingColors;\r\n\r\n let coloritem = replaceHtml(_this.coloritem, { \"class\": \"luckysheet-icon-alternateformat\", \"name\": locale_toolbar.alternatingColors+\"...\" });\r\n let menu = replaceHtml(_this.color, { \"id\": menuButtonId, \"coloritem\": coloritem, \"colorself\": subid, \"sub\": \"\",\"resetColor\":locale_toolbar.resetColor });\r\n \r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId);\r\n\r\n $(\"#\" + menuButtonId).find(\".luckysheet-color-selected\").spectrum({\r\n showPalette: true,\r\n showPaletteOnly: true,\r\n preferredFormat: \"hex\",\r\n clickoutFiresChange: false,\r\n showInitial: true,\r\n showInput: true,\r\n flat: true,\r\n hideAfterPaletteSelect: true,\r\n showSelectionPalette: true,\r\n maxPaletteSize: 8,\r\n maxSelectionSize: 8,\r\n color: luckysheetConfigsetting.defaultCellColor,\r\n cancelText: locale_button.cancel,\r\n chooseText: locale_button.confirm,\r\n togglePaletteMoreText: locale_toolbar.customColor,\r\n togglePaletteLessText: locale_toolbar.collapse,\r\n togglePaletteOnly: true,\r\n clearText: locale_toolbar.clearText,\r\n noColorSelectedText: locale_toolbar.noColorSelectedText,\r\n localStorageKey: \"spectrum.bgcolor\" + server.gridKey,\r\n palette: [\r\n [\"#000\", \"#444\", \"#666\", \"#999\", \"#ccc\", \"#eee\", \"#f3f3f3\", \"#fff\"],\r\n [\"#f00\", \"#f90\", \"#ff0\", \"#0f0\", \"#0ff\", \"#00f\", \"#90f\", \"#f0f\"],\r\n [\"#f4cccc\", \"#fce5cd\", \"#fff2cc\", \"#d9ead3\", \"#d0e0e3\", \"#cfe2f3\", \"#d9d2e9\", \"#ead1dc\"],\r\n [\"#ea9999\", \"#f9cb9c\", \"#ffe599\", \"#b6d7a8\", \"#a2c4c9\", \"#9fc5e8\", \"#b4a7d6\", \"#d5a6bd\"],\r\n [\"#e06666\", \"#f6b26b\", \"#ffd966\", \"#93c47d\", \"#76a5af\", \"#6fa8dc\", \"#8e7cc3\", \"#c27ba0\"],\r\n [\"#c00\", \"#e69138\", \"#f1c232\", \"#6aa84f\", \"#45818e\", \"#3d85c6\", \"#674ea7\", \"#a64d79\"],\r\n [\"#900\", \"#b45f06\", \"#bf9000\", \"#38761d\", \"#134f5c\", \"#0b5394\", \"#351c75\", \"#741b47\"],\r\n [\"#600\", \"#783f04\", \"#7f6000\", \"#274e13\", \"#0c343d\", \"#073763\", \"#20124d\", \"#4c1130\"]\r\n ],\r\n change: function (color) {\r\n if (color != null) {\r\n color = color.toHexString();\r\n }\r\n else {\r\n color = \"#fff\";\r\n }\r\n\r\n // $(\"#luckysheet-icon-cell-color .luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", color);\r\n // 下边框换成了一个DIV\r\n $(\"#luckysheet-icon-cell-color .text-color-bar\").css(\"background-color\", color);\r\n \r\n $(\"#luckysheet-icon-cell-color\").attr(\"color\", color);\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"bg\", color);\r\n\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n }\r\n });\r\n\r\n $menuButton.find(\".luckysheet-color-reset\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $input = $(\"#\" + menuButtonId).find(\".luckysheet-color-selected\");\r\n $input.val(\"#ffffff\");\r\n $(\"#luckysheet-icon-cell-color\").attr(\"color\", null);\r\n $input.spectrum(\"set\", \"#ffffff\");\r\n $(\"#luckysheet-icon-cell-color .luckysheet-color-menu-button-indicator\").css(\"border-bottom-color\", \"#ffffff\");\r\n \r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"bg\", null);\r\n });\r\n\r\n //交替颜色\r\n $menuButton.find(\".luckysheet-icon-alternateformat\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n if(Store.luckysheet_select_save.length > 1){\r\n if(isEditMode()){\r\n alert(locale_alternatingColors.errorInfo);\r\n }\r\n else{\r\n tooltip.info(locale_alternatingColors.errorInfo, \"\");\r\n }\r\n return;\r\n }\r\n\r\n let range = $.extend(true, {}, Store.luckysheet_select_save[0]);\r\n\r\n let isExists = alternateformat.rangeIsExists(range)[0];\r\n if(!isExists){\r\n alternateformat.modelfocusIndex = 0;\r\n alternateformat.new(range); \r\n }\r\n\r\n alternateformat.init();\r\n alternateformat.perfect();\r\n });\r\n\r\n $(\"#\" + menuButtonId).find(\".luckysheet-color-selected\").val(\"#fff\");\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n\r\n let offsetTop = $(this).offset().top + 26;\r\n setTimeout(function(){\r\n let $input = $(\"#\"+ menuButtonId).find(\".luckysheet-color-selected\");\r\n $input.spectrum(\"set\", $input.val());\r\n mouseclickposition($menuButton, menuleft - 28, offsetTop, \"lefttop\");\r\n }, 1);\r\n });\r\n\r\n\r\n //字体大小\r\n let luckysheet_fs_setTimeout = null;\r\n $(\"#luckysheet-icon-font-size\").mousedown(function(e){\r\n if (parseInt($(\"#luckysheet-input-box\").css(\"top\")) > 0){\r\n let w = window.getSelection();\r\n if(w.type!=\"None\"){\r\n let range = w.getRangeAt(0);\r\n if(!range.collapsed){\r\n Store.inlineStringEditRange = range.cloneRange();\r\n }\r\n }\r\n }\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n let itemdata = [\r\n { \"text\": \"9\", \"value\": \"9\", \"example\": \"\" },\r\n { \"text\": \"10\", \"value\": \"10\", \"example\": \"\" },\r\n { \"text\": \"11\", \"value\": \"11\", \"example\": \"\" },\r\n { \"text\": \"12\", \"value\": \"12\", \"example\": \"\" },\r\n { \"text\": \"14\", \"value\": \"14\", \"example\": \"\" },\r\n { \"text\": \"16\", \"value\": \"16\", \"example\": \"\" },\r\n { \"text\": \"18\", \"value\": \"18\", \"example\": \"\" },\r\n { \"text\": \"20\", \"value\": \"20\", \"example\": \"\" },\r\n { \"text\": \"22\", \"value\": \"22\", \"example\": \"\" },\r\n { \"text\": \"24\", \"value\": \"24\", \"example\": \"\" },\r\n { \"text\": \"26\", \"value\": \"26\", \"example\": \"\" },\r\n { \"text\": \"28\", \"value\": \"28\", \"example\": \"\" },\r\n { \"text\": \"36\", \"value\": \"36\", \"example\": \"\" },\r\n { \"text\": \"48\", \"value\": \"48\", \"example\": \"\" },\r\n { \"text\": \"72\", \"value\": \"72\", \"example\": \"\" }\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"font-size\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(150);\r\n _this.focus($menuButton, 10);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\"), $input = $(\"#luckysheet-icon-font-size input\");\r\n $(\"#luckysheet-icon-font-size\").attr(\"itemvalue\", itemvalue);\r\n _this.focus($menuButton, itemvalue);\r\n $input.val(itemvalue);\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"fs\", itemvalue);\r\n \r\n clearTimeout(luckysheet_fs_setTimeout);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let defualtvalue = $(\"#luckysheet-icon-font-size\").attr(\"itemvalue\");\r\n if(defualtvalue == null){\r\n defualtvalue = 10;\r\n }\r\n _this.focus($menuButton, defualtvalue);\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top + 25, \"lefttop\");\r\n\r\n\r\n })\r\n .find(\"input.luckysheet-toolbar-textinput\").keydown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).keyup(function(e){\r\n if(e.keyCode != 13){//Enter\r\n return;\r\n }\r\n\r\n let $this = $(this);\r\n\r\n let itemvalue = parseInt($this.val());\r\n let $menuButton = $(\"#luckysheet-icon-font-size-menuButton\");\r\n _this.focus($menuButton, itemvalue);\r\n \r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"fs\", itemvalue);\r\n \r\n luckysheet_fs_setTimeout = setTimeout(function(){\r\n $menuButton.hide();\r\n $this.blur();\r\n }, 200);\r\n });\r\n\r\n //边框设置\r\n $(\"#luckysheet-icon-border-all\").click(function(){\r\n\r\n if(!checkProtectionFormatCells(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let type = $(this).attr(\"type\");\r\n if(type == null){\r\n type = \"border-all\";\r\n }\r\n\r\n let subcolormenuid = \"luckysheet-icon-borderColor-menuButton\";\r\n let color = $(\"#\" + subcolormenuid).find(\".luckysheet-color-selected\").val();\r\n let style = $(\"#luckysheetborderSizepreview\").attr(\"itemvalue\");\r\n\r\n if(color == null || color == \"\"){\r\n color = \"#000\";\r\n }\r\n\r\n if(style == null || style == \"\"){\r\n style = \"1\";\r\n }\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n let borderInfo = {\r\n \"rangeType\": \"range\",\r\n \"borderType\": type,\r\n \"color\": color,\r\n \"style\": style,\r\n \"range\": $.extend(true, [], Store.luckysheet_select_save)\r\n }\r\n\r\n cfg[\"borderInfo\"].push(borderInfo);\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let redo = [];\r\n\r\n redo[\"type\"] = \"borderChange\";\r\n\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = $.extend(true, {}, cfg);\r\n \r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, cfg[\"borderInfo\"], { \"k\": \"borderInfo\" });\r\n\r\n Store.config = cfg;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n });\r\n\r\n $(\"#luckysheet-icon-border-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n\r\n if($menuButton.length == 0){\r\n let canvasH = 10, canvasW = 120;\r\n const _locale = locale();\r\n const locale_border = _locale.border;\r\n const locale_toolbar = _locale.toolbar;\r\n const locale_button = _locale.button;\r\n let itemdata = [\r\n {\"text\": locale_border.borderTop, \"value\": \"border-top\", \"example\": '
'},\r\n {\"text\": locale_border.borderBottom, \"value\":\"border-bottom\", \"example\": '
'},\r\n {\"text\": locale_border.borderLeft, \"value\":\"border-left\", \"example\": '
'},\r\n {\"text\": locale_border.borderRight, \"value\":\"border-right\", \"example\": '
'},\r\n {\"text\": \"\", \"value\": \"split\", \"example\":\"\"},\r\n {\"text\": locale_border.borderNone, \"value\": \"border-none\", \"example\": '
'},\r\n {\"text\": locale_border.borderAll, \"value\": \"border-all\", \"example\": '
'},\r\n {\"text\": locale_border.borderOutside, \"value\": \"border-outside\", \"example\": '
'},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_border.borderInside, \"value\": \"border-inside\", \"example\": '
'},\r\n {\"text\": locale_border.borderHorizontal, \"value\": \"border-horizontal\", \"example\": '
'},\r\n {\"text\": locale_border.borderVertical, \"value\": \"border-vertical\", \"example\": '
'},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": \"\"+ locale_border.borderColor +\"\", \"value\":\"borderColor\", \"example\":\"more\"},\r\n {\"text\": \"\"+ locale_border.borderSize +\"\", \"value\":\"borderSize\", \"example\":\"more\"}\r\n ];\r\n\r\n // itemvalue to iconfont\r\n const iconfontObject = iconfontObjects.border;\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"border-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n let subitemdata = [\r\n {\"text\": locale_border.borderNone, \"value\": \"0\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"1\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"2\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"3\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"4\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"5\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"6\", \"example\": \"\"},\r\n // {\"text\":\"\", \"value\":\"7\", \"example\":\"\"},\r\n {\"text\": \"\", \"value\": \"8\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"9\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"10\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"11\", \"example\": \"\"},\r\n // {\"text\":\"\", \"value\":\"12\", \"example\":\"\"},\r\n {\"text\": \"\", \"value\": \"13\", \"example\": \"\"}\r\n ];\r\n\r\n let subitemset = _this.createButtonMenu(subitemdata);\r\n let submenu = replaceHtml(_this.menu, { \"id\": \"borderSize\", \"item\": subitemset, \"subclass\": \"luckysheet-menuButton-sub\" });\r\n let submenuid = \"luckysheet-icon-borderSize-menuButton\";\r\n let subcolormenuid = \"luckysheet-icon-borderColor-menuButton\";\r\n let colormenu = replaceHtml(_this.color, { \"id\": subcolormenuid, \"coloritem\": \"\", \"colorself\": \"\", \"sub\": \"luckysheet-menuButton-sub\",resetColor:locale_toolbar.resetColor });\r\n\r\n $(\"body\").append(menu + colormenu + submenu);\r\n $menuButton = $(\"#\" + menuButtonId).width(170);\r\n _this.focus($menuButton, \"border-all\");\r\n\r\n $(\"#\" + submenuid + \" canvas\").each(function(i){\r\n let type = $(this).attr(\"type\");\r\n let itemvalue = $(this).closest(\".luckysheet-cols-menuitem\").attr(\"itemvalue\");\r\n let canvasborder = $(this).addClass(\"luckysheet-mousedown-cancel\").get(0).getContext(\"2d\");\r\n canvasborder.translate(0.5, 0.5);\r\n\r\n _this.setLineDash(canvasborder, itemvalue, \"h\", 0, 5, 100, 5);\r\n \r\n canvasborder.strokeStyle = \"#000000\";\r\n canvasborder.stroke();\r\n canvasborder.closePath();\r\n });\r\n\r\n $(\"#\" + submenuid + \" .luckysheet-cols-menuitem\").click(function(){\r\n $(\"#\"+ submenuid).hide();\r\n\r\n let $t = $(this), \r\n itemvalue = $t.attr(\"itemvalue\");\r\n \r\n if(itemvalue == 0){\r\n $(\"#luckysheetborderSizepreview\").attr(\"src\", \"data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==\").attr(\"itemvalue\", null);\r\n }\r\n else{\r\n let bg = $t.find(\"canvas\").get(0).toDataURL(\"image/png\");\r\n $(\"#luckysheetborderSizepreview\").attr(\"src\", bg).attr(\"itemvalue\", itemvalue);\r\n }\r\n \r\n _this.focus($(\"#\" + submenuid), itemvalue);\r\n });\r\n \r\n // border choose menu\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n if(itemvalue == \"borderColor\" || itemvalue == \"borderSize\"){\r\n return;\r\n }\r\n\r\n if(!checkProtectionFormatCells(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n let color = $(\"#\"+ subcolormenuid).find(\".luckysheet-color-selected\").val();\r\n let style = $(\"#luckysheetborderSizepreview\").attr(\"itemvalue\");\r\n\r\n if(color == null || color == \"\"){\r\n color = \"#000\";\r\n }\r\n\r\n if(style == null || style == \"\"){\r\n style = \"1\";\r\n }\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"borderInfo\"] == null){\r\n cfg[\"borderInfo\"] = [];\r\n }\r\n\r\n let borderInfo = {\r\n \"rangeType\": \"range\",\r\n \"borderType\": itemvalue,\r\n \"color\": color,\r\n \"style\": style,\r\n \"range\": $.extend(true, [], Store.luckysheet_select_save)\r\n }\r\n\r\n cfg[\"borderInfo\"].push(borderInfo);\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n\r\n let redo = [];\r\n\r\n redo[\"type\"] = \"borderChange\";\r\n\r\n redo[\"config\"] = $.extend(true, {}, Store.config);\r\n redo[\"curconfig\"] = $.extend(true, {}, cfg);\r\n \r\n redo[\"sheetIndex\"] = Store.currentSheetIndex;\r\n\r\n Store.jfredo.push(redo);\r\n }\r\n\r\n server.saveParam(\"cg\", Store.currentSheetIndex, cfg[\"borderInfo\"], { \"k\": \"borderInfo\" });\r\n\r\n Store.config = cfg;\r\n Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = Store.config;\r\n\r\n setTimeout(function () {\r\n luckysheetrefreshgrid();\r\n }, 1);\r\n\r\n $(\"#luckysheet-icon-border-all\").attr(\"type\", itemvalue);\r\n\r\n let $icon = $(\"#luckysheet-icon-border-all\").find(\".luckysheet-icon-img-container\");\r\n\r\n // add iconfont\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-\" + itemvalue + iconfontObject[itemvalue]);\r\n\r\n _this.focus($menuButton, itemvalue);\r\n });\r\n\r\n $(\"#\" + subcolormenuid).find(\".luckysheet-color-selected\").spectrum({\r\n showPalette: true,\r\n showPaletteOnly: true,\r\n preferredFormat: \"hex\",\r\n clickoutFiresChange: false,\r\n showInitial: true,\r\n showInput: true,\r\n flat: true,\r\n hideAfterPaletteSelect: true,\r\n showSelectionPalette: true,\r\n maxPaletteSize: 8,\r\n maxSelectionSize: 8,\r\n color: \"#000\",\r\n cancelText: locale_button.cancel,\r\n chooseText: locale_button.confirm,\r\n togglePaletteMoreText: locale_toolbar.customColor,\r\n togglePaletteLessText: locale_toolbar.collapse,\r\n togglePaletteOnly: true,\r\n clearText: locale_toolbar.clearText,\r\n noColorSelectedText:locale_toolbar.noColorSelectedText,\r\n localStorageKey: \"spectrum.bordercolor\" + server.gridKey,\r\n palette: [\r\n [\"#000\", \"#444\", \"#666\", \"#999\", \"#ccc\", \"#eee\", \"#f3f3f3\", \"#fff\"],\r\n [\"#f00\", \"#f90\", \"#ff0\", \"#0f0\", \"#0ff\", \"#00f\", \"#90f\", \"#f0f\"],\r\n [\"#f4cccc\", \"#fce5cd\", \"#fff2cc\", \"#d9ead3\", \"#d0e0e3\", \"#cfe2f3\", \"#d9d2e9\", \"#ead1dc\"],\r\n [\"#ea9999\", \"#f9cb9c\", \"#ffe599\", \"#b6d7a8\", \"#a2c4c9\", \"#9fc5e8\", \"#b4a7d6\", \"#d5a6bd\"],\r\n [\"#e06666\", \"#f6b26b\", \"#ffd966\", \"#93c47d\", \"#76a5af\", \"#6fa8dc\", \"#8e7cc3\", \"#c27ba0\"],\r\n [\"#c00\", \"#e69138\", \"#f1c232\", \"#6aa84f\", \"#45818e\", \"#3d85c6\", \"#674ea7\", \"#a64d79\"],\r\n [\"#900\", \"#b45f06\", \"#bf9000\", \"#38761d\", \"#134f5c\", \"#0b5394\", \"#351c75\", \"#741b47\"],\r\n [\"#600\", \"#783f04\", \"#7f6000\", \"#274e13\", \"#0c343d\", \"#073763\", \"#20124d\", \"#4c1130\"]\r\n ],\r\n change: function (color) {\r\n let $input = $(this);\r\n if (color != null) {\r\n color = color.toHexString();\r\n }\r\n else {\r\n color = \"#000\";\r\n }\r\n\r\n let oldcolor = null;\r\n $(\"#luckysheet-icon-borderColor-linecolor\").css(\"border-bottom-color\", color);\r\n $(\"#\"+ subcolormenuid).find(\".luckysheet-color-selected\").val(color);\r\n }\r\n });\r\n\r\n $(\"#\"+ subcolormenuid).find(\".luckysheet-color-reset\").click(function(){\r\n let $input = $(\"#\"+ subcolormenuid).find(\".luckysheet-color-selected\");\r\n $input.val(\"#000\");\r\n $(\"#luckysheet-icon-cell-color\").attr(\"color\", null);\r\n $input.spectrum(\"set\", \"#000\");\r\n $(\"#luckysheet-icon-borderColor-linecolor\").css(\"border-bottom-color\", \"#000\");\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft-28, $(this).offset().top+25, \"lefttop\");\r\n });\r\n\r\n //合并单元格\r\n $(\"#luckysheet-icon-merge-button\").click(function(){\r\n\r\n if(!checkProtectionNotEnable(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n if(selectIsOverlap()){\r\n if(isEditMode()){\r\n alert(\"不能合并重叠区域\");\r\n }\r\n else{\r\n tooltip.info(\"不能合并重叠区域\", \"\");\r\n }\r\n return;\r\n }\r\n\r\n if(Store.config[\"merge\"] != null){\r\n let has_PartMC = false;\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let r1 = Store.luckysheet_select_save[s].row[0], \r\n r2 = Store.luckysheet_select_save[s].row[1];\r\n let c1 = Store.luckysheet_select_save[s].column[0], \r\n c2 = Store.luckysheet_select_save[s].column[1];\r\n\r\n has_PartMC = hasPartMC(Store.config, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n break;\r\n }\r\n }\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(\"无法对部分合并单元格执行此操作\");\r\n }\r\n else{\r\n tooltip.info(\"无法对部分合并单元格执行此操作\", \"\"); \r\n }\r\n return; \r\n }\r\n }\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat_mc(d, \"mergeAll\");\r\n });\r\n\r\n $(\"#luckysheet-icon-merge-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n const _locale = locale();\r\n const locale_merge = _locale.merge;\r\n\r\n let itemdata = [\r\n {\"text\": locale_merge.mergeAll, \"value\": \"mergeAll\", \"example\": \"\"},\r\n {\"text\": locale_merge.mergeV, \"value\": \"mergeV\", \"example\": \"\"},\r\n {\"text\": locale_merge.mergeH, \"value\": \"mergeH\", \"example\": \"\"},\r\n {\"text\": locale_merge.mergeCancel, \"value\": \"mergeCancel\", \"example\": \"\"}\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"merge-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\"+menuButtonId).width(110);\r\n _this.focus($menuButton);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n if(selectIsOverlap()){\r\n if(isEditMode()){\r\n alert(locale_merge.overlappingError);\r\n }\r\n else{\r\n tooltip.info(locale_merge.overlappingError, \"\");\r\n }\r\n return;\r\n }\r\n\r\n if(Store.config[\"merge\"] != null){\r\n let has_PartMC = false;\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let r1 = Store.luckysheet_select_save[s].row[0], \r\n r2 = Store.luckysheet_select_save[s].row[1];\r\n let c1 = Store.luckysheet_select_save[s].column[0], \r\n c2 = Store.luckysheet_select_save[s].column[1];\r\n\r\n has_PartMC = hasPartMC(Store.config, r1, r2, c1, c2);\r\n\r\n if(has_PartMC){\r\n break;\r\n }\r\n }\r\n\r\n if(has_PartMC){\r\n if(isEditMode()){\r\n alert(locale_merge.partiallyError);\r\n }\r\n else{\r\n tooltip.info(locale_merge.partiallyError, \"\"); \r\n }\r\n return; \r\n }\r\n }\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n _this.focus($menuButton, itemvalue);\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat_mc(d, itemvalue);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft - 28, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //水平对齐\r\n $(\"#luckysheet-icon-align\").click(function(){\r\n \tlet itemvalue = $(\"#luckysheet-icon-align\").attr(\"type\");\r\n \tif(itemvalue == null){\r\n \t\titemvalue = \"left\";\r\n \t}\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"ht\", itemvalue);\r\n });\r\n\r\n $(\"#luckysheet-icon-align-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n const _locale = locale();\r\n const locale_align = _locale.align;\r\n let itemdata = [\r\n {\"text\": locale_align.left, \"value\": \"left\", \"example\": '
'},\r\n {\"text\": locale_align.center, \"value\": \"center\", \"example\": '
'},\r\n {\"text\": locale_align.right, \"value\": \"right\", \"example\": '
'}\r\n ];\r\n\r\n // itemvalue to iconfont\r\n const iconfontObject = iconfontObjects.align;\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"align-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(120);\r\n _this.focus($menuButton);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n _this.focus($menuButton, itemvalue);\r\n\r\n let $icon = $(\"#luckysheet-icon-align\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n\r\n // add iconfont\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-align-\" + itemvalue + iconfontObject[itemvalue]);\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"ht\", itemvalue);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft - 28, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //垂直对齐\r\n $(\"#luckysheet-icon-valign\").click(function(){\r\n \tlet itemvalue = $(\"#luckysheet-icon-valign\").attr(\"type\");\r\n \tif(itemvalue == null){\r\n \t\titemvalue = \"bottom\";\r\n \t}\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"vt\", itemvalue);\r\n });\r\n\r\n $(\"#luckysheet-icon-valign-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n const _locale = locale();\r\n const locale_align = _locale.align;\r\n if($menuButton.length == 0){\r\n let itemdata = [\r\n {\"text\": locale_align.top, \"value\": \"top\", \"example\": '
'},\r\n {\"text\": locale_align.middle, \"value\": \"middle\", \"example\": '
'},\r\n {\"text\": locale_align.bottom, \"value\": \"bottom\", \"example\": '
'}\r\n ];\r\n\r\n // itemvalue to iconfont\r\n const iconfontObject = iconfontObjects.align;\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"valign-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(120);\r\n _this.focus($menuButton, \"bottom\");\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n _this.focus($menuButton, itemvalue);\r\n\r\n let $icon = $(\"#luckysheet-icon-valign\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n\r\n // add iconfont\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-valign-\" + itemvalue + iconfontObject[itemvalue]);\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"vt\", itemvalue);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft - 28, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //文本换行\r\n $(\"#luckysheet-icon-textwrap-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n const _locale = locale();\r\n const locale_textWrap = _locale.textWrap;\r\n let itemdata = [\r\n {\"text\": locale_textWrap.overflow, \"value\": \"overflow\", \"example\": '
'},\r\n {\"text\": locale_textWrap.wrap, \"value\": \"wrap\", \"example\": '
'},\r\n {\"text\": locale_textWrap.clip, \"value\": \"clip\", \"example\": '
'}\r\n ];\r\n\r\n // itemvalue to iconfont\r\n const iconfontObject = iconfontObjects.textWrap;\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"textwrap-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(120);\r\n _this.focus($menuButton, \"clip\");\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n _this.focus($menuButton, itemvalue);\r\n\r\n let $icon = $(\"#luckysheet-icon-textwrap\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n\r\n // add iconfont\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-textwrap-\" + itemvalue + iconfontObject[itemvalue]);\r\n\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"tb\", itemvalue);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft - 28, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //文本旋转\r\n $(\"#luckysheet-icon-rotation-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n const _locale = locale();\r\n const locale_rotation = _locale.rotation;\r\n let itemdata = [\r\n {\"text\": locale_rotation.none, \"value\": \"none\", \"example\": '
'},\r\n {\"text\": locale_rotation.angleup, \"value\": \"angleup\", \"example\": '
'},\r\n {\"text\": locale_rotation.angledown, \"value\": \"angledown\", \"example\": '
'},\r\n {\"text\": locale_rotation.vertical, \"value\": \"vertical\", \"example\": '
'},\r\n {\"text\": locale_rotation.rotationUp, \"value\": \"rotation-up\", \"example\": '
'},\r\n {\"text\": locale_rotation.rotationDown, \"value\": \"rotation-down\", \"example\": '
'},\r\n ];\r\n\r\n // itemvalue to iconfont\r\n const iconfontObject = iconfontObjects.rotation;\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"rotation-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n\r\n // 文字旋转总 Stack Vertically 太长了,拉宽到160\r\n $menuButton = $(\"#\" + menuButtonId).width(160);\r\n _this.focus($menuButton);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n _this.focus($menuButton, itemvalue);\r\n\r\n let $icon = $(\"#luckysheet-icon-rotation\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n\r\n // add iconfont\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-rotation-\" + itemvalue + iconfontObject[itemvalue]);\r\n \r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n _this.updateFormat(d, \"tr\", itemvalue);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft - 28, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //冻结行列\r\n $(\"#luckysheet-icon-freezen-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n const _locale = locale();\r\n const locale_freezen = _locale.freezen;\r\n let itemdata = [\r\n {\"text\": locale_freezen.freezenRow, \"value\": \"freezenRow\", \"example\": ''},\r\n {\"text\": locale_freezen.freezenColumn, \"value\": \"freezenColumn\", \"example\": ''},\r\n {\"text\": locale_freezen.freezenRC, \"value\": \"freezenRC\", \"example\": ''},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_freezen.freezenRowRange, \"value\": \"freezenRowRange\", \"example\": ''},\r\n {\"text\": locale_freezen.freezenColumnRange, \"value\": \"freezenColumnRange\", \"example\": ''},\r\n {\"text\": locale_freezen.freezenRCRange, \"value\": \"freezenRCRange\", \"example\": ''},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_freezen.freezenCancel, \"value\": \"freezenCancel\", \"example\": ''}\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"freezen-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(170);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n _this.focus($menuButton, itemvalue);\r\n\r\n // store frozen\r\n luckysheetFreezen.saveFrozen(itemvalue);\r\n\r\n if(itemvalue == \"freezenRow\"){ //首行冻结\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n if (luckysheetFreezen.freezenverticaldata != null) {\r\n luckysheetFreezen.cancelFreezenVertical();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n else if(itemvalue == \"freezenColumn\"){ //首列冻结\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n if (luckysheetFreezen.freezenhorizontaldata != null) {\r\n luckysheetFreezen.cancelFreezenHorizontal();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n else if(itemvalue == \"freezenRC\"){ //首行列冻结\r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n else if(itemvalue == \"freezenRowRange\"){ //选区行冻结\r\n if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(locale_freezen.noSeletionError);\r\n }\r\n else{\r\n tooltip.info(locale_freezen.noSeletionError, \"\");\r\n }\r\n\r\n return;\r\n }\r\n \r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let row_focus = last[\"row_focus\"] == null ? last[\"row\"][0] : last[\"row_focus\"];\r\n\r\n if(row_focus > row_st){\r\n row_st = row_focus;\r\n }\r\n \r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n if (luckysheetFreezen.freezenverticaldata != null) {\r\n luckysheetFreezen.cancelFreezenVertical();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n else if(itemvalue == \"freezenColumnRange\"){ //选区列冻结\r\n if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(locale_freezen.noSeletionError);\r\n }\r\n else{\r\n tooltip.info(locale_freezen.noSeletionError,\"\");\r\n }\r\n\r\n return;\r\n }\r\n \r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let column_focus = last[\"column_focus\"] == null ? last[\"column\"][0] : last[\"column_focus\"];\r\n\r\n if(column_focus > col_st){\r\n col_st = column_focus;\r\n }\r\n\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n\r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n if (luckysheetFreezen.freezenhorizontaldata != null) {\r\n luckysheetFreezen.cancelFreezenHorizontal();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n else if(itemvalue == \"freezenRCRange\"){ //选区行列冻结\r\n if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(locale_freezen.noSeletionError);\r\n }\r\n else{\r\n tooltip.info(locale_freezen.noSeletionError,\"\");\r\n }\r\n\r\n return;\r\n }\r\n \r\n let scrollTop = $(\"#luckysheet-cell-main\").scrollTop();\r\n let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let row_focus = last[\"row_focus\"] == null ? last[\"row\"][0] : last[\"row_focus\"];\r\n\r\n if(row_focus > row_st){\r\n row_st = row_focus;\r\n }\r\n \r\n if(row_st == -1){\r\n row_st = 0;\r\n }\r\n\r\n let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columnHeaderHeight;\r\n let freezenhorizontaldata = [Store.visibledatarow[row_st], row_st + 1, scrollTop, luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1), top];\r\n luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);\r\n\r\n luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);\r\n\r\n let scrollLeft = $(\"#luckysheet-cell-main\").scrollLeft();\r\n let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);\r\n\r\n let column_focus = last[\"column_focus\"] == null ? last[\"column\"][0] : last[\"column_focus\"];\r\n\r\n if(column_focus > col_st){\r\n col_st = column_focus;\r\n }\r\n\r\n if(col_st == -1){\r\n col_st = 0;\r\n }\r\n \r\n let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;\r\n let freezenverticaldata = [Store.visibledatacolumn[col_st], col_st + 1, scrollLeft, luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1), left];\r\n luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);\r\n\r\n luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);\r\n \r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n else if(itemvalue == \"freezenCancel\"){ //Cancel freezen\r\n if (luckysheetFreezen.freezenverticaldata != null) {\r\n luckysheetFreezen.cancelFreezenVertical();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n if (luckysheetFreezen.freezenhorizontaldata != null) {\r\n luckysheetFreezen.cancelFreezenHorizontal();\r\n luckysheetFreezen.createAssistCanvas();\r\n luckysheetrefreshgrid();\r\n }\r\n\r\n luckysheetFreezen.scrollAdapt();\r\n }\r\n\r\n setTimeout(function(){\r\n luckysheetsizeauto();\r\n },0);\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft - 68, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //过滤和排序\r\n $(\"#luckysheet-icon-autofilter\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n if($menuButton.length == 0){\r\n const _locale = locale();\r\n const locale_sort = _locale.sort;\r\n const locale_filter = _locale.filter;\r\n let itemdata = [\r\n {\"text\": locale_sort.asc, \"value\": \"asc\", \"example\": ''},\r\n {\"text\": locale_sort.desc, \"value\": \"desc\", \"example\": ''},\r\n {\"text\": locale_sort.custom+\"...\", \"value\": \"diysort\", \"example\": ''},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_filter.filter, \"value\": \"filter\", \"example\": ''},\r\n {\"text\": locale_filter.clearFilter, \"value\": \"clearfilter\", \"example\": ''}\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, {\"id\":\"autofilter\", \"item\": itemset, \"subclass\":\"\", \"sub\":\"\"});\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(150);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(itemvalue == \"diysort\"){\r\n $(\"#luckysheetorderby\").click();\r\n }\r\n else if(itemvalue == \"asc\"){\r\n sortSelection(true);\r\n }\r\n else if(itemvalue == \"desc\"){\r\n sortSelection(false);\r\n }\r\n else if(itemvalue == \"filter\"){\r\n if($('#luckysheet-filter-options-sheet' + Store.currentSheetIndex).length > 0){\r\n $(\"#luckysheet-filter-initial\").click();\r\n }\r\n else{\r\n createFilter();\r\n }\r\n }\r\n else if(itemvalue == \"clearfilter\"){\r\n $(\"#luckysheet-filter-initial\").click();\r\n }\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //查找和替换\r\n $(\"#luckysheet-icon-seachmore\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n const _locale = locale();\r\n const locale_findAndReplace = _locale.findAndReplace;\r\n if($menuButton.length == 0){\r\n let itemdata = [\r\n {\"text\": locale_findAndReplace.find+\" ...\", \"value\": \"search\", \"example\": ''},\r\n {\"text\": locale_findAndReplace.replace+\" ...\", \"value\": \"replace\", \"example\": ''},\r\n // {\"text\": locale_findAndReplace.goto+\" ...\", \"value\": \"goto\", \"example\": ''},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_findAndReplace.location+\" ...\", \"value\": \"location\", \"example\": ''},\r\n {\"text\": locale_findAndReplace.formula, \"value\": \"locationFormula\", \"example\": locale_findAndReplace.locationExample},\r\n {\"text\": locale_findAndReplace.date, \"value\": \"locationConstantDate\", \"example\": locale_findAndReplace.locationExample},\r\n {\"text\": locale_findAndReplace.number, \"value\": \"locationConstantNumber\", \"example\": locale_findAndReplace.locationExample},\r\n {\"text\": locale_findAndReplace.string, \"value\": \"locationConstantString\", \"example\": locale_findAndReplace.locationExample},\r\n {\"text\": locale_findAndReplace.error, \"value\": \"locationConstantError\", \"example\": locale_findAndReplace.locationExample},\r\n {\"text\": locale_findAndReplace.condition, \"value\": \"locationCF\", \"example\": locale_findAndReplace.locationExample},\r\n {\"text\": locale_findAndReplace.rowSpan, \"value\": \"locationStepRow\", \"example\": locale_findAndReplace.locationExample},\r\n {\"text\": locale_findAndReplace.columnSpan, \"value\": \"locationStepColumn\", \"example\": locale_findAndReplace.locationExample}\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"seachmore\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(180);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(itemvalue == \"search\" || itemvalue == \"replace\"){ //查找替换\r\n if(itemvalue == \"search\"){\r\n luckysheetSearchReplace.createDialog(0);\r\n }\r\n else if(itemvalue == \"replace\"){\r\n luckysheetSearchReplace.createDialog(1); \r\n }\r\n \r\n luckysheetSearchReplace.init();\r\n\r\n $(\"#luckysheet-search-replace #searchInput input\").focus();\r\n }\r\n else if(itemvalue == \"location\"){ //定位条件\r\n luckysheetLocationCell.createDialog();\r\n luckysheetLocationCell.init();\r\n }\r\n else if(itemvalue == \"locationFormula\" || itemvalue == \"locationConstantDate\" || itemvalue == \"locationConstantNumber\" || itemvalue == \"locationConstantString\" || itemvalue == \"locationConstantError\" || itemvalue == \"locationCF\"){ \r\n let last = Store.luckysheet_select_save[0];\r\n \r\n let range;\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && last.row[0] == last.row[1] && last.column[0] == last.column[1])){\r\n //单个单元格\r\n range = [{\"row\": [0, Store.flowdata.length - 1], \"column\": [0, Store.flowdata[0].length - 1]}];\r\n }\r\n else{\r\n range = $.extend(true, [], Store.luckysheet_select_save);\r\n }\r\n\r\n if(itemvalue == \"locationFormula\"){ //公式\r\n luckysheetLocationCell.apply(range, \"locationFormula\", \"all\");\r\n }\r\n else if(itemvalue == \"locationConstantDate\"){ //日期\r\n luckysheetLocationCell.apply(range, \"locationConstant\", \"d\");\r\n }\r\n else if(itemvalue == \"locationConstantNumber\"){ //数字\r\n luckysheetLocationCell.apply(range, \"locationConstant\", \"n\");\r\n }\r\n else if(itemvalue == \"locationConstantString\"){ //字符\r\n luckysheetLocationCell.apply(range, \"locationConstant\", \"s,g\");\r\n }\r\n else if(itemvalue == \"locationConstantError\"){ //错误\r\n luckysheetLocationCell.apply(range, \"locationConstant\", \"e\");\r\n }\r\n else if(itemvalue == \"locationCF\"){ //条件格式\r\n luckysheetLocationCell.apply(range, \"locationCF\");\r\n }\r\n }\r\n else if(itemvalue == \"locationStepRow\"){ //间隔行\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].row[0] == Store.luckysheet_select_save[0].row[1])){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.lessTwoRowTip);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_findAndReplace.lessTwoRowTip); \r\n }\r\n return; \r\n }\r\n\r\n let range = $.extend(true, [], Store.luckysheet_select_save);\r\n\r\n luckysheetLocationCell.apply(range, \"locationStepRow\");\r\n }\r\n else if(itemvalue == \"locationStepColumn\"){ //间隔列\r\n if(Store.luckysheet_select_save.length == 0 || (Store.luckysheet_select_save.length == 1 && Store.luckysheet_select_save[0].column[0] == Store.luckysheet_select_save[0].column[1])){\r\n if(isEditMode()){\r\n alert(locale_findAndReplace.lessTwoColumnTip);\r\n }\r\n else{\r\n tooltip.info(\"\", locale_findAndReplace.lessTwoColumnTip); \r\n }\r\n return; \r\n }\r\n\r\n let range = $.extend(true, [], Store.luckysheet_select_save);\r\n\r\n luckysheetLocationCell.apply(range, \"locationStepColumn\");\r\n }\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //公式\r\n $(\"#luckysheet-icon-function\").click(function(){\r\n _this.autoSelectionFormula(\"SUM\");\r\n });\r\n\r\n //公式菜单\r\n $(\"#luckysheet-icon-function-menu\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n\r\n const _locale = locale();\r\n const locale_formula = _locale.formula;\r\n \r\n if($menuButton.length == 0){\r\n let itemdata = [\r\n {\"text\": locale_formula.sum, \"value\": \"SUM\", \"example\": 'SUM'},\r\n {\"text\": locale_formula.average, \"value\": \"AVERAGE\", \"example\": 'AVERAGE'},\r\n {\"text\": locale_formula.count, \"value\": \"COUNT\", \"example\": 'COUNT'},\r\n {\"text\": locale_formula.max, \"value\": \"MAX\", \"example\": 'MAX'},\r\n {\"text\": locale_formula.min, \"value\": \"MIN\", \"example\": 'MIN'},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_formula.ifGenerate, \"value\": \"if\", \"example\": 'IF'},\r\n {\"text\": locale_formula.find+\" ...\", \"value\": \"formula\", \"example\": \"\"}\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"function-menu\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(180);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(itemvalue == \"if\"){\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n let r = last[\"row_focus\"] == null ? last[\"row\"][0] : last[\"row_focus\"];\r\n let c = last[\"column_focus\"] == null ? last[\"column\"][0] : last[\"column_focus\"];\r\n\r\n if(!!Store.flowdata[r] && !!Store.flowdata[r][c] && !!Store.flowdata[r][c][\"f\"]){\r\n let fp = Store.flowdata[r][c][\"f\"].toString();\r\n\r\n if(fp.indexOf(\"=if(\") != -1){\r\n ifFormulaGenerator.ifFormulaDialog(fp);\r\n }\r\n else{\r\n if(isEditMode()){\r\n alert(locale_formula.tipNotBelongToIf);\r\n }\r\n else{\r\n tooltip.info(locale_formula.tipNotBelongToIf,\"\");\r\n }\r\n return;\r\n }\r\n }\r\n else{\r\n ifFormulaGenerator.ifFormulaDialog();\r\n }\r\n\r\n ifFormulaGenerator.init();\r\n }\r\n else if(itemvalue == \"formula\"){\r\n //点击函数查找弹出框\r\n if(Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(locale_formula.tipSelectCell);\r\n }\r\n else{\r\n tooltip.info(locale_formula.tipSelectCell,\"\");\r\n }\r\n\r\n return;\r\n }\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n\r\n let row_index = last[\"row_focus\"], col_index = last[\"column_focus\"];\r\n\r\n luckysheetupdateCell(row_index, col_index, Store.flowdata);\r\n \r\n let cell = Store.flowdata[row_index][col_index];\r\n if(cell != null && cell.f != null){\r\n //单元格有计算\r\n let functionStr = luckysheetformula.getfunctionParam(cell.f);\r\n if(functionStr.fn != null){\r\n //有函数公式\r\n insertFormula.formulaParmDialog(functionStr.fn, functionStr.param);\r\n }\r\n else{\r\n //无函数公式\r\n insertFormula.formulaListDialog();\r\n }\r\n }\r\n else{\r\n //单元格无计算\r\n $(\"#luckysheet-rich-text-editor\").html('=');\r\n $(\"#luckysheet-functionbox-cell\").html($(\"#luckysheet-rich-text-editor\").html());\r\n insertFormula.formulaListDialog();\r\n }\r\n\r\n insertFormula.init();\r\n }\r\n else {\r\n _this.autoSelectionFormula(itemvalue);\r\n }\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft-48, $(this).offset().top+25, \"lefttop\");\r\n });\r\n\r\n //加粗\r\n $(\"#luckysheet-icon-bold\").mousedown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(e){\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let row_index = Store.luckysheet_select_save[0][\"row_focus\"], \r\n col_index = Store.luckysheet_select_save[0][\"column_focus\"];\r\n let foucsStatus = _this.checkstatus(d, row_index, col_index, \"bl\");\r\n\r\n if(foucsStatus == 1){\r\n foucsStatus = 0;\r\n }\r\n else{\r\n foucsStatus = 1;\r\n }\r\n\r\n _this.updateFormat(d, \"bl\", foucsStatus);\r\n _this.menuButtonFocus(d, row_index, col_index);\r\n });\r\n\r\n //斜体\r\n $(\"#luckysheet-icon-italic\").mousedown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let row_index = Store.luckysheet_select_save[0][\"row_focus\"], \r\n col_index = Store.luckysheet_select_save[0][\"column_focus\"];\r\n let foucsStatus = _this.checkstatus(d, row_index, col_index, \"it\");\r\n\r\n if(foucsStatus == 1){\r\n foucsStatus = 0;\r\n }\r\n else{\r\n foucsStatus = 1;\r\n }\r\n\r\n _this.updateFormat(d, \"it\", foucsStatus);\r\n _this.menuButtonFocus(d, row_index, col_index);\r\n });\r\n\r\n //删除线\r\n $(\"#luckysheet-icon-strikethrough\").mousedown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let row_index = Store.luckysheet_select_save[0][\"row_focus\"], \r\n col_index = Store.luckysheet_select_save[0][\"column_focus\"];\r\n let foucsStatus = _this.checkstatus(d, row_index, col_index, \"cl\");\r\n\r\n if(foucsStatus == 1){\r\n foucsStatus = 0;\r\n }\r\n else{\r\n foucsStatus = 1;\r\n }\r\n\r\n _this.updateFormat(d, \"cl\", foucsStatus);\r\n _this.menuButtonFocus(d, row_index, col_index);\r\n });\r\n\r\n //下划线\r\n $(\"#luckysheet-icon-underline\").mousedown(function(e){\r\n hideMenuByCancel(e);\r\n e.stopPropagation();\r\n }).click(function(){\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let row_index = Store.luckysheet_select_save[0][\"row_focus\"], \r\n col_index = Store.luckysheet_select_save[0][\"column_focus\"];\r\n let foucsStatus = _this.checkstatus(d, row_index, col_index, \"un\");\r\n\r\n if(foucsStatus == 1){\r\n foucsStatus = 0;\r\n }\r\n else{\r\n foucsStatus = 1;\r\n }\r\n\r\n _this.updateFormat(d, \"un\", foucsStatus);\r\n _this.menuButtonFocus(d, row_index, col_index);\r\n });\r\n\r\n //条件格式\r\n $(\"#luckysheet-icon-conditionformat\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n\r\n const conditionformat_text = locale().conditionformat;\r\n \r\n if($menuButton.length == 0){\r\n let itemdata = [\r\n { \"text\": conditionformat_text.highlightCellRules, \"value\": \"highlightCellRule\", \"example\": \"more\" },\r\n { \"text\": conditionformat_text.itemSelectionRules, \"value\": \"projectSelectRule\", \"example\": \"more\" },\r\n { \"text\": conditionformat_text.dataBar, \"value\": \"dataBar\", \"example\": \"more\" },\r\n { \"text\": conditionformat_text.colorGradation, \"value\": \"colorGradation\", \"example\": \"more\" },\r\n { \"text\": conditionformat_text.icons, \"value\": \"icons\", \"example\": \"\" },\r\n { \"text\": \"\", \"value\": \"split\", \"example\": \"\" },\r\n { \"text\": conditionformat_text.newRule, \"value\": \"newRule\", \"example\": \"\" },\r\n { \"text\": conditionformat_text.deleteRule, \"value\": \"deleteRule\", \"example\": \"more\" },\r\n { \"text\": conditionformat_text.manageRules, \"value\": \"administerRule\", \"example\": \"\" }\r\n ];\r\n let itemset = _this.createButtonMenu(itemdata);\r\n let menu = replaceHtml(_this.menu, {\"id\": \"conditionformat\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\"});\r\n \r\n //突出显示单元格规则子菜单\r\n let subitemdata = [\r\n { \"text\": conditionformat_text.greaterThan, \"value\": \"greaterThan\", \"example\": \">\" },\r\n { \"text\": conditionformat_text.lessThan, \"value\": \"lessThan\", \"example\": \"<\" },\r\n { \"text\": conditionformat_text.between, \"value\": \"betweenness\", \"example\": \"[]\" },\r\n { \"text\": conditionformat_text.equal, \"value\": \"equal\", \"example\": \"=\" },\r\n { \"text\": conditionformat_text.textContains, \"value\": \"textContains\", \"example\": \"()\" },\r\n { \"text\": conditionformat_text.occurrence, \"value\": \"occurrenceDate\", \"example\": conditionformat_text.yesterday },\r\n { \"text\": conditionformat_text.duplicateValue, \"value\": \"duplicateValue\", \"example\": \"##\" }\r\n ];\r\n let subitemset = _this.createButtonMenu(subitemdata);\r\n let submenu = replaceHtml(_this.menu, {\"id\": \"highlightCellRule\", \"item\": subitemset, \"subclass\": \"luckysheet-menuButton-sub\"});\r\n \r\n //项目选取规则子菜单\r\n let subitemdata2 = [\r\n { \"text\": conditionformat_text.top10, \"value\": \"top10\", \"example\": conditionformat_text.top10 },\r\n { \"text\": conditionformat_text.top10_percent, \"value\": \"top10%\", \"example\": conditionformat_text.top10_percent },\r\n { \"text\": conditionformat_text.last10, \"value\": \"last10\", \"example\": conditionformat_text.last10 },\r\n { \"text\": conditionformat_text.last10_percent, \"value\": \"last10%\", \"example\": conditionformat_text.last10_percent },\r\n { \"text\": conditionformat_text.aboveAverage, \"value\": \"AboveAverage\", \"example\": conditionformat_text.above },\r\n { \"text\": conditionformat_text.belowAverage, \"value\": \"SubAverage\", \"example\": conditionformat_text.below }\r\n ];\r\n let subitemset2 = _this.createButtonMenu(subitemdata2);\r\n let submenu2 = replaceHtml(_this.menu, {\"id\": \"projectSelectRule\", \"item\": subitemset2, \"subclass\": \"luckysheet-menuButton-sub\"});\r\n \r\n //数据条子菜单\r\n let submenu3 = `
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
`;\r\n\r\n //色阶\r\n let submenu4 = `
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
`;\r\n\r\n //清除规则子菜单\r\n let subitemdata6 = [\r\n { \"text\": conditionformat_text.deleteSheetRule, \"value\": \"delSheet\", \"example\": \"\" }\r\n ];\r\n let subitemset6 = _this.createButtonMenu(subitemdata6);\r\n let submenu6 = replaceHtml(_this.menu, {\"id\": \"deleteRule\", \"item\": subitemset6, \"subclass\":\"luckysheet-menuButton-sub\"});\r\n\r\n $(\"body\").append(menu + submenu + submenu2 + submenu3 + submenu4 + submenu6);\r\n $menuButton = $(\"#\" + menuButtonId).width(190);\r\n $(\"#luckysheet-icon-highlightCellRule-menuButton\").width(160);\r\n $(\"#luckysheet-icon-projectSelectRule-menuButton\").width(180);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(itemvalue == \"icons\"){\r\n if(Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(conditionformat_text.pleaseSelectRange);\r\n }\r\n else{\r\n tooltip.info(conditionformat_text.pleaseSelectRange, \"\");\r\n }\r\n return;\r\n }\r\n\r\n conditionformat.CFiconsDialog();\r\n conditionformat.init();\r\n }\r\n else if(itemvalue == \"newRule\"){\r\n if(Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(conditionformat_text.pleaseSelectRange);\r\n }\r\n else{\r\n tooltip.info(conditionformat_text.pleaseSelectRange, \"\");\r\n }\r\n return;\r\n }\r\n\r\n conditionformat.newConditionRuleDialog(0);\r\n conditionformat.init();\r\n }\r\n else if(itemvalue == \"administerRule\"){\r\n let loadSheetUrl = server.loadSheetUrl;\r\n let file = getluckysheetfile();\r\n\r\n if(loadSheetUrl != \"\" && loadSheetUrl != null){\r\n let sheetindex = [];\r\n for(let i = 0; i < file.length; i++){\r\n sheetindex.push(file[i].index);\r\n }\r\n\r\n $.post(loadSheetUrl, {\"gridKey\" : server.gridKey, \"index\": sheetindex.join(\",\")}, function (d) {\r\n let dataset = new Function(\"return \" + d)();\r\n\r\n setTimeout(function(){\r\n $(\"#luckysheetloadingdata\").fadeOut().remove();\r\n }, 500);\r\n\r\n for(let item in dataset){\r\n if(item == Store.currentSheetIndex){\r\n continue;\r\n }\r\n\r\n let otherfile = file[getSheetIndex(item)];\r\n\r\n otherfile.celldata = dataset[item.toString()];\r\n otherfile[\"data\"] = sheetmanage.buildGridData(otherfile);\r\n }\r\n\r\n setluckysheetfile(file);\r\n\r\n conditionformat.fileClone = $.extend(true, [], file);\r\n conditionformat.administerRuleDialog();\r\n conditionformat.init();\r\n });\r\n }\r\n else{\r\n conditionformat.fileClone = $.extend(true, [], file);\r\n conditionformat.administerRuleDialog();\r\n conditionformat.init();\r\n }\r\n }\r\n });\r\n\r\n //突出显示单元格规则子菜单点击事件\r\n $(document).off(\"click.CFhighlightCellRule\").on(\"click.CFhighlightCellRule\", \"#luckysheet-icon-highlightCellRule-menuButton .luckysheet-cols-menuitem\", function(){\r\n $menuButton.hide();\r\n $(\"#luckysheet-icon-highlightCellRule-menuButton\").hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(conditionformat_text.pleaseSelectRange);\r\n }\r\n else{\r\n tooltip.info(conditionformat_text.pleaseSelectRange, \"\"); \r\n }\r\n return;\r\n }\r\n else{\r\n let textCellColorHtml = conditionformat.textCellColorHtml();\r\n\r\n let title, content;\r\n switch(itemvalue){\r\n case \"greaterThan\":\r\n title = conditionformat_text.conditionformat_greaterThan;\r\n content = `
\r\n
${conditionformat_text.conditionformat_greaterThan_title}:
\r\n
\r\n \r\n \r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml} \r\n
`;\r\n break;\r\n case \"lessThan\":\r\n title = conditionformat_text.conditionformat_lessThan;\r\n content = `
\r\n
${conditionformat_text.conditionformat_lessThan_title}:
\r\n
\r\n \r\n \r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break;\r\n case \"betweenness\":\r\n title = conditionformat_text.conditionformat_betweenness;\r\n content = `
\r\n
${conditionformat_text.conditionformat_betweenness_title}:
\r\n
\r\n
\r\n \r\n \r\n
\r\n
${conditionformat_text.to}
\r\n
\r\n \r\n \r\n
\r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break;\r\n case \"equal\":\r\n title = conditionformat_text.conditionformat_equal;\r\n content = `
\r\n
${conditionformat_text.conditionformat_equal_title}:
\r\n
\r\n \r\n \r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break;\r\n case \"textContains\":\r\n title = conditionformat_text.conditionformat_textContains;\r\n content = `
\r\n
${conditionformat_text.conditionformat_textContains_title}:
\r\n
\r\n \r\n \r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break; \r\n case \"occurrenceDate\":\r\n title = conditionformat_text.conditionformat_occurrenceDate;\r\n content = `
\r\n
${conditionformat_text.conditionformat_occurrenceDate_title}:
\r\n
\r\n \r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break; \r\n case \"duplicateValue\":\r\n title = conditionformat_text.conditionformat_duplicateValue;\r\n content = `
\r\n
${conditionformat_text.conditionformat_duplicateValue_title}:
\r\n \r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break; \r\n }\r\n\r\n conditionformat.conditionformatDialog(title, content); \r\n }\r\n });\r\n\r\n //项目选取规则子菜单点击事件\r\n $(document).off(\"click.CFprojectSelectRule\").on(\"click.CFprojectSelectRule\", \"#luckysheet-icon-projectSelectRule-menuButton .luckysheet-cols-menuitem\", function(){\r\n $menuButton.hide();\r\n $(\"#luckysheet-icon-projectSelectRule-menuButton\").hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(Store.luckysheet_select_save.length == 0){\r\n if(isEditMode()){\r\n alert(conditionformat_text.pleaseSelectRange);\r\n }\r\n else{\r\n tooltip.info(conditionformat_text.pleaseSelectRange, \"\"); \r\n }\r\n return;\r\n }\r\n else{\r\n let textCellColorHtml = conditionformat.textCellColorHtml();\r\n\r\n let title, content;\r\n switch(itemvalue){\r\n case \"top10\":\r\n title = conditionformat_text.conditionformat_top10;\r\n content = `
\r\n
${conditionformat_text.conditionformat_top10_title}:
\r\n
\r\n
${conditionformat_text.top}
\r\n
\r\n \r\n
\r\n
${conditionformat_text.oneself}
\r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break;\r\n case \"top10%\":\r\n title = conditionformat_text.conditionformat_top10_percent;\r\n content = `
\r\n
${conditionformat_text.conditionformat_top10_title}:
\r\n
\r\n
${conditionformat_text.top}
\r\n
\r\n \r\n
\r\n
%
\r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break;\r\n case \"last10\":\r\n title = conditionformat_text.conditionformat_last10;\r\n content = `
\r\n
${conditionformat_text.conditionformat_last10_title}:
\r\n
\r\n
${conditionformat_text.last}
\r\n
\r\n \r\n
\r\n
${conditionformat_text.oneself}
\r\n
\r\n
${conditionformat_text.setAs}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break;\r\n case \"last10%\":\r\n title = conditionformat_text.conditionformat_last10_percent;\r\n content = `
\r\n
${conditionformat_text.conditionformat_last10_title}:
\r\n
\r\n
${conditionformat_text.last}
\r\n
\r\n \r\n
\r\n
%
\r\n
\r\n
设置为:
\r\n ${textCellColorHtml}\r\n
`;\r\n break;\r\n case \"AboveAverage\":\r\n title = conditionformat_text.conditionformat_AboveAverage;\r\n content = `
\r\n
${conditionformat_text.conditionformat_AboveAverage_title}:
\r\n
${conditionformat_text.setAsByArea}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break; \r\n case \"SubAverage\":\r\n title = conditionformat_text.conditionformat_SubAverage;\r\n content = `
\r\n
${conditionformat_text.conditionformat_SubAverage_title}:
\r\n
${conditionformat_text.setAsByArea}:
\r\n ${textCellColorHtml}\r\n
`;\r\n break; \r\n }\r\n\r\n conditionformat.conditionformatDialog(title,content);\r\n }\r\n });\r\n\r\n //数据条子菜单点击事件\r\n $(document).off(\"click.CFdataBar\").on(\"click.CFdataBar\", \"#luckysheet-icon-dataBar-menuButton .luckysheet-cols-menuitem\", function(){\r\n $menuButton.hide();\r\n $(\"#luckysheet-icon-dataBar-menuButton\").hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(Store.luckysheet_select_save.length > 0){\r\n let cellrange = $.extend(true, [], Store.luckysheet_select_save);\r\n let format = conditionformat.dataBarList[itemvalue][\"format\"];\r\n\r\n conditionformat.updateItem(\"dataBar\", cellrange, format);\r\n }\r\n });\r\n\r\n //色阶子菜单点击事件\r\n $(document).off(\"click.CFcolorGradation\").on(\"click.CFcolorGradation\", \"#luckysheet-icon-colorGradation-menuButton .luckysheet-cols-menuitem\", function(){\r\n $menuButton.hide();\r\n $(\"#luckysheet-icon-colorGradation-menuButton\").hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(Store.luckysheet_select_save.length > 0){\r\n let cellrange = $.extend(true, [], Store.luckysheet_select_save);\r\n let format = conditionformat.colorGradationList[itemvalue][\"format\"];\r\n\r\n conditionformat.updateItem(\"colorGradation\", cellrange, format);\r\n }\r\n });\r\n\r\n //清除规则子菜单点击事件\r\n $(document).off(\"click.CFdeleteRule\").on(\"click.CFdeleteRule\", \"#luckysheet-icon-deleteRule-menuButton .luckysheet-cols-menuitem\", function(){\r\n $menuButton.hide();\r\n $(\"#luckysheet-icon-deleteRule-menuButton\").hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(itemvalue == \"delSheet\"){\r\n conditionformat.updateItem(\"delSheet\");\r\n }\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n\r\n //批注\r\n $(\"#luckysheet-icon-postil\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\")+\"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n \r\n const locale_comment = locale().comment;\r\n\r\n $menuButton.remove();\r\n\r\n // if($menuButton.length == 0){\r\n luckysheetPostil.removeActivePs();\r\n\r\n let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];\r\n \r\n let row_index = last[\"row_focus\"];\r\n if(row_index == null){\r\n row_index = last[\"row\"][0];\r\n }\r\n\r\n let col_index = last[\"column_focus\"];\r\n if(col_index == null){\r\n col_index = last[\"column\"][0];\r\n }\r\n\r\n let itemdata;\r\n if(Store.flowdata[row_index][col_index] != null && Store.flowdata[row_index][col_index].ps != null){\r\n itemdata = [\r\n {\"text\": locale_comment.edit, \"value\": \"editPs\", \"example\": \"\"},\r\n {\"text\": locale_comment.delete, \"value\": \"delPs\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_comment.showOne, \"value\": \"showHidePs\", \"example\": \"\"},\r\n {\"text\": locale_comment.showAll, \"value\": \"showHideAllPs\", \"example\": \"\"}\r\n ];\r\n }\r\n else{\r\n itemdata = [\r\n {\"text\": locale_comment.insert, \"value\": \"newPs\", \"example\": \"\"},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_comment.showAll, \"value\": \"showHideAllPs\", \"example\": \"\"}\r\n ];\r\n }\r\n \r\n let itemset = _this.createButtonMenu(itemdata);\r\n let menu = replaceHtml(_this.menu, {\"id\": \"postil\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\"});\r\n \r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\"+menuButtonId).width(150);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n \r\n if(itemvalue == \"newPs\"){\r\n luckysheetPostil.newPs(row_index, col_index);\r\n }\r\n else if(itemvalue == \"editPs\"){\r\n luckysheetPostil.editPs(row_index, col_index);\r\n }\r\n else if(itemvalue == \"delPs\"){\r\n luckysheetPostil.delPs(row_index, col_index);\r\n }\r\n else if(itemvalue == \"showHidePs\"){\r\n luckysheetPostil.showHidePs(row_index, col_index);\r\n }\r\n else if(itemvalue == \"showHideAllPs\"){\r\n luckysheetPostil.showHideAllPs();\r\n }\r\n });\r\n // }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n \r\n //sheet protection\r\n $(\"#luckysheet-icon-protection\").click(function(){\r\n let sheetFile = sheetmanage.getSheetByIndex();\r\n openProtectionModal(sheetFile);\r\n });\r\n\r\n //print\r\n $(\"#luckysheet-icon-print\").click(function(){\r\n let menuButtonId = $(this).attr(\"id\") + \"-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n const _locale = locale();\r\n const locale_print = _locale.print;\r\n if($menuButton.length == 0){\r\n let itemdata = [\r\n {\"text\": locale_print.menuItemPrint, \"value\": \"print\", \"example\": ''},\r\n {\"text\": \"\", \"value\": \"split\", \"example\": \"\"},\r\n {\"text\": locale_print.menuItemAreas, \"value\": \"areas\", \"example\": ''},\r\n {\"text\": locale_print.menuItemRows, \"value\": \"rows\", \"example\": ''},\r\n {\"text\": locale_print.menuItemColumns, \"value\": \"columns\", \"example\": ''},\r\n ];\r\n\r\n let itemset = _this.createButtonMenu(itemdata);\r\n\r\n let menu = replaceHtml(_this.menu, { \"id\": \"print\", \"item\": itemset, \"subclass\": \"\", \"sub\": \"\" });\r\n\r\n $(\"body\").append(menu);\r\n $menuButton = $(\"#\" + menuButtonId).width(180);\r\n\r\n $menuButton.find(\".luckysheet-cols-menuitem\").click(function(){\r\n $menuButton.hide();\r\n luckysheetContainerFocus();\r\n\r\n let $t = $(this), itemvalue = $t.attr(\"itemvalue\");\r\n\r\n if(itemvalue == \"print\"){ //Print config\r\n alert(\"print\");\r\n }\r\n else if(itemvalue == \"areas\" || itemvalue == \"rows\" || itemvalue == \"columns\"){ //range\r\n alert(\"areas\");\r\n }\r\n });\r\n }\r\n\r\n let userlen = $(this).outerWidth();\r\n let tlen = $menuButton.outerWidth();\r\n\r\n let menuleft = $(this).offset().left;\r\n if(tlen > userlen && (tlen + menuleft) > $(\"#\" + Store.container).width()){\r\n menuleft = menuleft - tlen + userlen;\r\n }\r\n mouseclickposition($menuButton, menuleft, $(this).offset().top + 25, \"lefttop\");\r\n });\r\n \r\n $(\"body\").on(\"mouseover mouseleave\",\".luckysheet-menuButton .luckysheet-cols-submenu\", function(e){\r\n let $t = $(this), attrid = $t.attr(\"itemvalue\"), \r\n $attr = $(\"#luckysheet-icon-\" + attrid + \"-menuButton\");\r\n \r\n if (e.type === \"mouseover\") {\r\n let $con = $t.parent();\r\n let winW = $(window).width(), winH = $(window).height();\r\n let menuW = $con.width(), attrH = $attr.height() + 25, attrW = $attr.width() + 5;\r\n let offset = $t.offset();\r\n let top = offset.top, left = offset.left + menuW;\r\n\r\n if (left + attrW > winW) {\r\n left = offset.left - attrW;\r\n }\r\n\r\n if (top + attrH > winH) {\r\n top = winH - attrH;\r\n }\r\n\r\n $attr.css({ \"top\": top, \"left\": left }).show();\r\n _this.rightclickmenu = $t;\r\n } else {\r\n clearTimeout(_this.submenuhide[$attr.attr('id')]);\r\n _this.submenuhide[$attr.attr('id')] = setTimeout(function () { $attr.hide(); }, 200);\r\n }\r\n }).on(\"mouseover mouseleave\",\".luckysheet-menuButton-sub\", function(e){\r\n if (e.type === \"mouseover\") {\r\n _this.rightclickmenu.addClass(\"luckysheet-cols-menuitem-hover\");\r\n clearTimeout(_this.submenuhide[$(this).attr('id')]);\r\n } \r\n else {\r\n _this.rightclickmenu.removeClass(\"luckysheet-cols-menuitem-hover\");\r\n $(this).hide();\r\n }\r\n });\r\n },\r\n getQKBorder: function(width, type, color){\r\n let bordertype = \"\";\r\n\r\n if(width.indexOf(\"pt\") > -1){\r\n width = parseFloat(width);\r\n \r\n if(width < 1){\r\n\r\n }\r\n else if(width < 1.5){\r\n bordertype = \"Medium\";\r\n }\r\n else{\r\n bordertype = \"Thick\";\r\n }\r\n }\r\n else{\r\n width = parseFloat(width);\r\n \r\n if(width < 2){\r\n\r\n }\r\n else if(width < 3){\r\n bordertype = \"Medium\";\r\n }\r\n else{\r\n bordertype = \"Thick\";\r\n }\r\n }\r\n\r\n let style = 0;\r\n type = type.toLowerCase();\r\n\r\n if(type == \"double\"){\r\n style = 2;\r\n }\r\n else if(type == \"dotted\"){\r\n if(bordertype == \"Medium\" || bordertype == \"Thick\"){\r\n style = 3;\r\n }\r\n else{\r\n style = 10;\r\n }\r\n }\r\n else if(type == \"dashed\"){\r\n if(bordertype == \"Medium\" || bordertype == \"Thick\"){\r\n style = 4;\r\n }\r\n else{\r\n style = 9;\r\n }\r\n }\r\n else if(type == \"solid\"){\r\n if(bordertype == \"Medium\"){\r\n style = 8;\r\n }\r\n else if(bordertype == \"Thick\"){\r\n style = 13;\r\n }\r\n else{\r\n style = 1;\r\n }\r\n }\r\n \r\n return [style, color];\r\n },\r\n updateFormatCell:function(d, attr, foucsStatus,row_st, row_ed, col_st, col_ed){\r\n if(d==null || attr==null){\r\n return;\r\n }\r\n if(attr == \"ct\"){\r\n for (let r = row_st; r <= row_ed; r++) {\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n for (let c = col_st; c <= col_ed; c++) {\r\n let cell = d[r][c], value = null;\r\n \r\n if (getObjType(cell) == \"object\") {\r\n value = d[r][c][\"v\"];\r\n }\r\n else{\r\n value = d[r][c];\r\n }\r\n\r\n if(foucsStatus != \"@\" && isRealNum(value)){\r\n value = parseFloat(value);\r\n }\r\n\r\n let mask = update(foucsStatus, value);\r\n let type = \"n\";\r\n \r\n if(is_date(foucsStatus) || foucsStatus === 14 || foucsStatus === 15 || foucsStatus === 16 || foucsStatus === 17 || foucsStatus === 18 || foucsStatus === 19 || foucsStatus === 20 || foucsStatus === 21 || foucsStatus === 22 || foucsStatus === 45 || foucsStatus === 46 || foucsStatus === 47){\r\n type = \"d\";\r\n }\r\n else if(foucsStatus == \"@\" || foucsStatus === 49){\r\n type = \"s\"\r\n }\r\n else if(foucsStatus == \"General\" || foucsStatus === 0){\r\n type = \"g\";\r\n }\r\n\r\n if (getObjType(cell) == \"object\") {\r\n d[r][c][\"m\"] = mask;\r\n if(d[r][c][\"ct\"] == null){\r\n d[r][c][\"ct\"] = {};\r\n }\r\n d[r][c][\"ct\"][\"fa\"] = foucsStatus;\r\n d[r][c][\"ct\"][\"t\"] = type;\r\n }\r\n else{\r\n d[r][c] = { \"ct\":{\"fa\":foucsStatus, \"t\":type}, \"v\": value, \"m\": mask };\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n if(attr == \"ht\"){\r\n if(foucsStatus == \"left\"){\r\n foucsStatus = \"1\";\r\n }\r\n else if(foucsStatus == \"center\"){\r\n foucsStatus = \"0\";\r\n }\r\n else if(foucsStatus == \"right\"){\r\n foucsStatus = \"2\";\r\n }\r\n }\r\n else if(attr == \"vt\"){\r\n if(foucsStatus == \"top\"){\r\n foucsStatus = \"1\";\r\n }\r\n else if(foucsStatus == \"middle\"){\r\n foucsStatus = \"0\";\r\n }\r\n else if(foucsStatus == \"bottom\"){\r\n foucsStatus = \"2\";\r\n }\r\n }\r\n else if(attr == \"tb\"){\r\n if(foucsStatus == \"overflow\"){\r\n foucsStatus = \"1\";\r\n }\r\n else if(foucsStatus == \"clip\"){\r\n foucsStatus = \"0\";\r\n }\r\n else if(foucsStatus == \"wrap\"){\r\n foucsStatus = \"2\";\r\n }\r\n }\r\n else if(attr == \"tr\"){\r\n if(foucsStatus == \"none\"){\r\n foucsStatus = \"0\";\r\n }\r\n else if(foucsStatus == \"angleup\"){\r\n foucsStatus = \"1\";\r\n }\r\n else if(foucsStatus == \"angledown\"){\r\n foucsStatus = \"2\";\r\n }\r\n else if(foucsStatus == \"vertical\"){\r\n foucsStatus = \"3\";\r\n }\r\n else if(foucsStatus == \"rotation-up\"){\r\n foucsStatus = \"4\";\r\n }\r\n else if(foucsStatus == \"rotation-down\"){\r\n foucsStatus = \"5\";\r\n }\r\n }\r\n\r\n for (let r = row_st; r <= row_ed; r++) {\r\n if (Store.config[\"rowhidden\"] != null && Store.config[\"rowhidden\"][r] != null) {\r\n continue;\r\n }\r\n\r\n for (let c = col_st; c <= col_ed; c++) {\r\n let value = d[r][c];\r\n \r\n if (getObjType(value) == \"object\") {\r\n // if(attr in inlineStyleAffectAttribute && isInlineStringCell(value)){\r\n updateInlineStringFormatOutside(value, attr, foucsStatus);\r\n // }\r\n // else{\r\n d[r][c][attr] = foucsStatus;\r\n // }\r\n \r\n }\r\n else{\r\n d[r][c] = { v: value };\r\n d[r][c][attr] = foucsStatus;\r\n }\r\n\r\n // if(attr == \"tr\" && d[r][c].tb != null){\r\n // d[r][c].tb = \"0\";\r\n // }\r\n }\r\n }\r\n }\r\n\r\n },\r\n updateFormat: function(d, attr, foucsStatus){\r\n let _this = this;\r\n\r\n if(!checkProtectionFormatCells(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n if(Store.allowEdit===false){\r\n return;\r\n }\r\n\r\n let canvasElement = document.createElement('canvas');\r\n let canvas = canvasElement.getContext(\"2d\");\r\n\r\n if(attr in inlineStyleAffectAttribute ){\r\n if (parseInt($(\"#luckysheet-input-box\").css(\"top\")) > 0 ) {\r\n let value = $(\"#luckysheet-input-box\").text();\r\n if(value.substr(0,1)!=\"=\"){\r\n let cell = d[Store.luckysheetCellUpdate[0]][Store.luckysheetCellUpdate[1]];\r\n updateInlineStringFormat(cell, attr, foucsStatus, luckysheetformula.rangeResizeTo);\r\n // return;\r\n }\r\n }\r\n }\r\n\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"rowlen\"] == null){\r\n cfg[\"rowlen\"] = {};\r\n }\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let row_st = Store.luckysheet_select_save[s][\"row\"][0], \r\n row_ed = Store.luckysheet_select_save[s][\"row\"][1];\r\n let col_st = Store.luckysheet_select_save[s][\"column\"][0], \r\n col_ed = Store.luckysheet_select_save[s][\"column\"][1];\r\n\r\n this.updateFormatCell(d, attr, foucsStatus, row_st, row_ed, col_st, col_ed);\r\n\r\n if(attr == \"tb\" || attr == \"tr\" || attr == \"fs\"){\r\n cfg = rowlenByRange(d, row_st, row_ed, cfg);\r\n }\r\n }\r\n\r\n let allParam = {};\r\n if(attr == \"tb\" || attr == \"tr\" || attr == \"fs\"){\r\n allParam = {\r\n \"cfg\": cfg,\r\n \"RowlChange\": true\r\n }\r\n }\r\n\r\n jfrefreshgrid(d, Store.luckysheet_select_save, allParam, false);\r\n },\r\n updateFormat_mc: function(d, foucsStatus){\r\n let cfg = $.extend(true, {}, Store.config);\r\n if(cfg[\"merge\"] == null){\r\n cfg[\"merge\"] = {};\r\n }\r\n\r\n if(!checkProtectionNotEnable(Store.currentSheetIndex)){\r\n return;\r\n }\r\n\r\n if(foucsStatus == \"mergeCancel\"){\r\n for(let i = 0; i < Store.luckysheet_select_save.length; i++){\r\n let range = Store.luckysheet_select_save[i];\r\n let r1 = range[\"row\"][0], r2 = range[\"row\"][1];\r\n let c1 = range[\"column\"][0], c2 = range[\"column\"][1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n continue;\r\n }\r\n\r\n let fv = {};\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = d[r][c];\r\n\r\n if(cell != null && cell.mc != null){\r\n let mc_r = cell.mc.r, mc_c = cell.mc.c;\r\n\r\n if(\"rs\" in cell.mc){\r\n delete cell.mc;\r\n delete cfg[\"merge\"][mc_r + \"_\" + mc_c];\r\n\r\n fv[mc_r + \"_\" + mc_c] = $.extend(true, {}, cell);\r\n }\r\n else{\r\n // let cell_clone = fv[mc_r + \"_\" + mc_c];\r\n let cell_clone = JSON.parse(JSON.stringify(fv[mc_r + \"_\" + mc_c]));\r\n\r\n delete cell_clone.v;\r\n delete cell_clone.m;\r\n delete cell_clone.ct;\r\n delete cell_clone.f;\r\n delete cell_clone.spl;\r\n\r\n d[r][c] = cell_clone;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n let isHasMc = false; //选区是否含有 合并的单元格\r\n\r\n for(let i = 0; i < Store.luckysheet_select_save.length; i++){\r\n let range = Store.luckysheet_select_save[i];\r\n let r1 = range[\"row\"][0], r2 = range[\"row\"][1];\r\n let c1 = range[\"column\"][0], c2 = range[\"column\"][1];\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = d[r][c];\r\n\r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n isHasMc = true;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if(isHasMc){//选区有合并单元格(选区都执行 取消合并)\r\n for(let i = 0; i < Store.luckysheet_select_save.length; i++){\r\n let range = Store.luckysheet_select_save[i];\r\n let r1 = range[\"row\"][0], r2 = range[\"row\"][1];\r\n let c1 = range[\"column\"][0], c2 = range[\"column\"][1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n continue;\r\n }\r\n\r\n let fv = {};\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = d[r][c];\r\n\r\n if(cell != null && cell.mc != null){\r\n let mc_r = cell.mc.r, mc_c = cell.mc.c;\r\n\r\n if(\"rs\" in cell.mc){\r\n delete cell.mc;\r\n delete cfg[\"merge\"][mc_r + \"_\" + mc_c];\r\n\r\n fv[mc_r + \"_\" + mc_c] = $.extend(true, {}, cell);\r\n }\r\n else{\r\n // let cell_clone = fv[mc_r + \"_\" + mc_c];\r\n let cell_clone = JSON.parse(JSON.stringify(fv[mc_r + \"_\" + mc_c]));\r\n\r\n delete cell_clone.v;\r\n delete cell_clone.m;\r\n delete cell_clone.ct;\r\n delete cell_clone.f;\r\n delete cell_clone.spl;\r\n\r\n d[r][c] = cell_clone;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n for(let i = 0; i < Store.luckysheet_select_save.length; i++){\r\n let range = Store.luckysheet_select_save[i];\r\n let r1 = range[\"row\"][0], r2 = range[\"row\"][1];\r\n let c1 = range[\"column\"][0], c2 = range[\"column\"][1];\r\n\r\n if(r1 == r2 && c1 == c2){\r\n continue;\r\n }\r\n\r\n if(foucsStatus == \"mergeAll\"){\r\n let fv = {}, isfirst = false;\r\n\r\n for(let r = r1; r <= r2; r++){\r\n for(let c = c1; c <= c2; c++){\r\n let cell = d[r][c];\r\n\r\n if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){\r\n fv = $.extend(true, {}, cell);\r\n isfirst = true;\r\n }\r\n\r\n d[r][c] = { \"mc\": { \"r\": r1, \"c\": c1 } };\r\n }\r\n }\r\n\r\n d[r1][c1] = fv;\r\n d[r1][c1].mc = { \"r\": r1, \"c\": c1, \"rs\": r2 - r1 + 1, \"cs\": c2 - c1 + 1 };\r\n\r\n cfg[\"merge\"][r1 + \"_\" + c1] = { \"r\": r1, \"c\": c1, \"rs\": r2 - r1 + 1, \"cs\": c2 - c1 + 1 };\r\n }\r\n else if(foucsStatus == \"mergeV\"){\r\n for(let c = c1; c <= c2; c++){\r\n let fv = {}, isfirst = false;\r\n\r\n for(let r = r1; r <= r2; r++){\r\n let cell = d[r][c];\r\n\r\n if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){\r\n fv = $.extend(true, {}, cell);\r\n isfirst = true;\r\n }\r\n\r\n d[r][c] = { \"mc\": { \"r\": r1, \"c\": c } };\r\n }\r\n\r\n d[r1][c] = fv;\r\n d[r1][c].mc = { \"r\": r1, \"c\": c, \"rs\": r2 - r1 + 1, \"cs\": 1 };\r\n\r\n cfg[\"merge\"][r1 + \"_\" + c] = { \"r\": r1, \"c\": c, \"rs\": r2 - r1 + 1, \"cs\": 1 };\r\n }\r\n }\r\n else if(foucsStatus == \"mergeH\"){\r\n for(let r = r1; r <= r2; r++){\r\n let fv = {}, isfirst = false;\r\n\r\n for(let c = c1; c <= c2; c++){\r\n let cell = d[r][c];\r\n\r\n if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){\r\n fv = $.extend(true, {}, cell);\r\n isfirst = true;\r\n }\r\n\r\n d[r][c] = { \"mc\": { \"r\": r, \"c\": c1 } };\r\n }\r\n\r\n d[r][c1] = fv;\r\n d[r][c1].mc = { \"r\": r, \"c\": c1, \"rs\": 1, \"cs\": c2 - c1 + 1 };\r\n\r\n cfg[\"merge\"][r + \"_\" + c1] = { \"r\": r, \"c\": c1, \"rs\": 1, \"cs\": c2 - c1 + 1 };\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (Store.clearjfundo) {\r\n Store.jfundo.length = 0;\r\n Store.jfredo.push({\r\n \"type\": \"mergeChange\",\r\n \"sheetIndex\": Store.currentSheetIndex,\r\n \"data\": Store.flowdata,\r\n \"curData\": d,\r\n \"range\": $.extend(true, [], Store.luckysheet_select_save),\r\n \"config\": $.extend(true, {}, Store.config),\r\n \"curConfig\": cfg\r\n });\r\n }\r\n\r\n Store.clearjfundo = false;\r\n jfrefreshgrid(d, Store.luckysheet_select_save, {\"cfg\": cfg});\r\n Store.clearjfundo = true;\r\n },\r\n borderfix: function(d, r, c){\r\n // return [-1, -1, 2, 2];\r\n\r\n let cell = d[r][c];\r\n let bg = null;\r\n \r\n if(cell == null){\r\n return [-1, 0, 0, -1];\r\n }\r\n else if(d[r][c].bg == null || d[r][c].bg == \"\"){\r\n return [-1, 0, 0, -1];\r\n }\r\n else {\r\n return [-2, -1, 1, 0];\r\n //return [-2, -2, 1, 0];\r\n }\r\n },\r\n changeMenuButtonDom:function(attr, foucsStatus, _locale){\r\n let _this = this;\r\n if(_locale==null){\r\n _locale = locale();\r\n }\r\n const locale_fontarray = _locale.fontarray;\r\n const locale_fontjson = _locale.fontjson;\r\n\r\n if(attr == \"bl\"){\r\n if(foucsStatus != \"0\"){\r\n $(\"#luckysheet-icon-bold\").addClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n else{\r\n $(\"#luckysheet-icon-bold\").removeClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n }\r\n else if(attr == \"it\"){\r\n if(foucsStatus != \"0\"){\r\n $(\"#luckysheet-icon-italic\").addClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n else{\r\n $(\"#luckysheet-icon-italic\").removeClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n }\r\n else if(attr == \"cl\"){\r\n if(foucsStatus != \"0\"){\r\n $(\"#luckysheet-icon-strikethrough\").addClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n else{\r\n $(\"#luckysheet-icon-strikethrough\").removeClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n }\r\n else if(attr == \"un\"){\r\n if(foucsStatus != \"0\"){\r\n $(\"#luckysheet-icon-underline\").addClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n else{\r\n $(\"#luckysheet-icon-underline\").removeClass(\"luckysheet-toolbar-button-hover\");\r\n }\r\n }\r\n else if(attr == \"ff\"){\r\n let menuButtonId = \"luckysheet-icon-font-family-menuButton\";\r\n let $menuButton = $(\"#\" + menuButtonId);\r\n // const locale_fontarray = locale().fontarray;\r\n let itemname = locale_fontarray[0], itemvalue = 0;\r\n if(foucsStatus != null){\r\n if(isdatatypemulti(foucsStatus)[\"num\"]){\r\n itemvalue = parseInt(foucsStatus);\r\n itemname = locale_fontarray[itemvalue];\r\n\r\n if(itemname==null){\r\n itemvalue = _this.defualtFont[itemvalue];\r\n itemname = itemvalue;\r\n if(itemvalue!=null){\r\n _this.addFontTolist(itemvalue);\r\n }\r\n }\r\n }\r\n else{\r\n foucsStatus = foucsStatus.replace(/\"/g, \"\").replace(/'/g, \"\");\r\n itemvalue = foucsStatus;\r\n itemname = foucsStatus;\r\n\r\n _this.addFontTolist(itemvalue);\r\n } \r\n }\r\n\r\n _this.focus($menuButton, itemvalue);\r\n $(\"#luckysheet-icon-font-family\").find(\".luckysheet-toolbar-menu-button-caption\").html(\" \"+ itemname +\" \");\r\n }\r\n else if(attr == \"fs\"){\r\n let $menuButton = $(\"#luckysheet-icon-font-size-menuButton\");\r\n let itemvalue = foucsStatus, $input = $(\"#luckysheet-icon-font-size input\");\r\n _this.focus($menuButton, itemvalue);\r\n $(\"#luckysheet-icon-font-size\").attr(\"itemvalue\", itemvalue);\r\n $input.val(itemvalue);\r\n }\r\n else if(attr == \"ht\"){\r\n let $menuButton = $(\"#luckysheet-icon-align-menu-menuButton\");\r\n let $t = $(\"luckysheet-icon-align\"), itemvalue = \"left\";\r\n \r\n if(foucsStatus == \"0\"){\r\n itemvalue = \"center\";\r\n }\r\n else if(foucsStatus == \"2\"){\r\n itemvalue = \"right\";\r\n }\r\n\r\n _this.focus($menuButton, itemvalue);\r\n\r\n // add iconfont\r\n const iconfontObject = iconfontObjects.align;\r\n\r\n let $icon = $(\"#luckysheet-icon-align\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-align-\" + itemvalue + iconfontObject[itemvalue]);\r\n $menuButton.hide();\r\n }\r\n else if(attr == \"vt\"){\r\n let $menuButton = $(\"#luckysheet-icon-valign-menu-menuButton\");\r\n let $t = $(\"luckysheet-icon-valign\"), itemvalue = \"bottom\";\r\n \r\n if(foucsStatus == \"1\"){\r\n itemvalue = \"top\";\r\n }\r\n else if(foucsStatus == \"0\"){\r\n itemvalue = \"middle\";\r\n }\r\n\r\n _this.focus($menuButton, itemvalue);\r\n\r\n // add iconfont\r\n const iconfontObject = iconfontObjects.align;\r\n\r\n let $icon = $(\"#luckysheet-icon-valign\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-valign-\" + itemvalue+ iconfontObject[itemvalue]);\r\n $menuButton.hide();\r\n }\r\n else if(attr == \"tb\"){\r\n let $menuButton = $(\"#luckysheet-icon-textwrap-menu-menuButton\");\r\n let $t = $(\"luckysheet-icon-textwrap\"), itemvalue = \"clip\";\r\n \r\n if(foucsStatus == \"1\"){\r\n itemvalue = \"overflow\";\r\n }\r\n else if(foucsStatus == \"2\"){\r\n itemvalue = \"wrap\";\r\n }\r\n\r\n _this.focus($menuButton, itemvalue);\r\n\r\n // add iconfont\r\n const iconfontObject = iconfontObjects.textWrap;\r\n\r\n let $icon = $(\"#luckysheet-icon-textwrap\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-textwrap-\" + itemvalue + iconfontObject[itemvalue]);\r\n $menuButton.hide();\r\n }\r\n else if(attr == \"tr\"){\r\n let $menuButton = $(\"#luckysheet-icon-rotation-menu-menuButton\");\r\n let $t = $(\"luckysheet-icon-rotation\"), itemvalue = \"none\";\r\n \r\n if(foucsStatus == \"1\"){\r\n itemvalue = \"angleup\";\r\n }\r\n else if(foucsStatus == \"2\"){\r\n itemvalue = \"angledown\";\r\n }\r\n else if(foucsStatus == \"3\"){\r\n itemvalue = \"vertical\";\r\n }\r\n else if(foucsStatus == \"4\"){\r\n itemvalue = \"rotation-up\";\r\n }\r\n else if(foucsStatus == \"5\"){\r\n itemvalue = \"rotation-down\";\r\n }\r\n\r\n _this.focus($menuButton, itemvalue);\r\n\r\n // add iconfont\r\n const iconfontObject = iconfontObjects.rotation;\r\n\r\n let $icon = $(\"#luckysheet-icon-rotation\").attr(\"type\", itemvalue).find(\".luckysheet-icon-img-container\");\r\n $icon.removeAttr(\"class\").addClass(\"luckysheet-icon-img-container luckysheet-icon-img luckysheet-icon-rotation-\" + itemvalue + iconfontObject[itemvalue]);\r\n $menuButton.hide();\r\n }\r\n else if(attr == \"ct\") {\r\n let $menuButton = $(\"#luckysheet-icon-fmt-other\");\r\n const _locale = locale();\r\n const locale_defaultFmt = _locale.defaultFmt;\r\n if(!foucsStatus) {\r\n $menuButton.find(\".luckysheet-toolbar-menu-button-caption\").html(\" \"+ locale_defaultFmt[0].text +\" \");\r\n return;\r\n }\r\n const {fa} = foucsStatus;\r\n const format = locale_defaultFmt.find(f => f.value === fa);\r\n if(format) {\r\n $menuButton.find(\".luckysheet-toolbar-menu-button-caption\").html(\" \"+ format.text +\" \");\r\n } else {\r\n const otherFormat = locale_defaultFmt.find(f => f.value === \"fmtOtherSelf\");\r\n $menuButton.find(\".luckysheet-toolbar-menu-button-caption\").html(\" \"+ otherFormat.text +\" \");\r\n }\r\n }\r\n },\r\n inputMenuButtonFocus:function(focusTarget){\r\n var w = window.getSelection(); \r\n var range = w.getRangeAt(0);\r\n let startContainer = range.startContainer;\r\n Store.inlineStringEditRange = null;\r\n const _locale = locale();\r\n if(startContainer.parentNode.tagName==\"SPAN\"){\r\n let cssText = startContainer.parentNode.style.cssText;\r\n let stylelist = convertCssToStyleList(cssText);\r\n for(let key in stylelist){\r\n this.changeMenuButtonDom(key, stylelist[key], _locale);\r\n }\r\n }\r\n },\r\n menuButtonFocus: function(d, r, c){\r\n let _this = this;\r\n let foucsList = [\"bl\", \"it\", \"cl\", \"ff\", \"ht\", \"vt\", \"fs\", \"tb\", \"tr\", \"ct\", \"un\"];\r\n const _locale = locale();\r\n for(let i = 0; i < foucsList.length; i++){\r\n let attr = foucsList[i];\r\n let foucsStatus = _this.checkstatus(d, r, c, attr);\r\n\r\n this.changeMenuButtonDom(attr, foucsStatus, _locale);\r\n }\r\n },\r\n checkstatus: function(d, r, c, a){\r\n if(d==null || d[r]==null){\r\n console.warn(\"It's incorrect data\", r, c);\r\n return null;\r\n }\r\n let foucsStatus = d[r][c];\r\n return checkstatusByCell(foucsStatus, a);\r\n },\r\n setLineDash: function(canvasborder, type, hv, m_st, m_ed, line_st, line_ed){\r\n \tlet borderType = {\r\n \"0\": \"none\", \r\n \"1\": \"Thin\", \r\n \"2\": \"Hair\", \r\n \"3\": \"Dotted\", \r\n \"4\": \"Dashed\", \r\n \"5\": \"DashDot\", \r\n \"6\": \"DashDotDot\", \r\n \"7\": \"Double\", \r\n \"8\": \"Medium\", \r\n \"9\": \"MediumDashed\", \r\n \"10\": \"MediumDashDot\", \r\n \"11\": \"MediumDashDotDot\", \r\n \"12\": \"SlantedDashDot\", \r\n \"13\": \"Thick\"\r\n };\r\n\r\n type = borderType[type.toString()];\r\n\r\n \ttry {\r\n \tif(type == \"Hair\"){\r\n canvasborder.setLineDash([1, 2]);\r\n }\r\n else if(type.indexOf(\"DashDotDot\") > -1){\r\n canvasborder.setLineDash([2, 2, 5, 2, 2]);\r\n }\r\n else if(type.indexOf(\"DashDot\") > -1){\r\n canvasborder.setLineDash([2, 5, 2]);\r\n }\r\n else if(type.indexOf(\"Dotted\") > -1){\r\n canvasborder.setLineDash([2]);\r\n }\r\n else if(type.indexOf(\"Dashed\") > -1){\r\n canvasborder.setLineDash([3]);\r\n }\r\n else{\r\n \tcanvasborder.setLineDash([0]);\r\n }\r\n } \r\n catch(e) {\r\n \t\tconsole.log(e);\r\n \t}\r\n\r\n canvasborder.beginPath();\r\n\r\n if(type.indexOf(\"Medium\") > -1){\r\n \tif(hv == \"h\"){\r\n \t\tcanvasborder.moveTo(m_st, m_ed - 0.5);\r\n \tcanvasborder.lineTo(line_st, line_ed - 0.5);\r\n \t}\r\n \telse{\r\n \t\tcanvasborder.moveTo(m_st - 0.5, m_ed);\r\n \tcanvasborder.lineTo(line_st - 0.5, line_ed);\r\n \t}\r\n \r\n canvasborder.lineWidth = 2;\r\n }\r\n else if(type == \"Thick\"){\r\n canvasborder.moveTo(m_st, m_ed);\r\n canvasborder.lineTo(line_st, line_ed);\r\n canvasborder.lineWidth = 3;\r\n }\r\n else {\r\n canvasborder.moveTo(m_st, m_ed);\r\n canvasborder.lineTo(line_st, line_ed);\r\n canvasborder.lineWidth = 1;\r\n }\r\n },\r\n moveMergeData: function(d, offset_r, offset_c){\r\n if(isRealNull(d)){\r\n return d;\r\n }\r\n\r\n let deleMC = [], insertMC=[], hasMC = false;\r\n\r\n for(let r = 0; r < d.length; r++){\r\n for(let c = 0; c < d[0].length; c++){\r\n let cell = d[r][c];\r\n \r\n if(getObjType(cell) == \"object\" && (\"mc\" in cell)){\r\n if(cell.mc.rs != null){\r\n deleMC.push({ \r\n rs: cell.mc.rs, \r\n cs: cell.mc.cs, \r\n r: cell.mc.r, \r\n c: cell.mc.c\r\n });\r\n insertMC.push({ \r\n rs: cell.mc.rs, \r\n cs: cell.mc.cs, \r\n r: cell.mc.r + offset_r, \r\n c: cell.mc.c + offset_c\r\n });\r\n\r\n hasMC= true;\r\n }\r\n\r\n d[r][c].mc.r += offset_r;\r\n d[r][c].mc.c += offset_c;\r\n }\r\n }\r\n }\r\n\r\n return { \"deleMC\": deleMC, \"insertMC\": insertMC, \"hasMC\": hasMC };\r\n },\r\n getRangeInMerge: function(st_r, rlen, st_c, clen, sheetIndex){\r\n let _this = this;\r\n\r\n let mergelist = [];\r\n let cfg = null;\r\n if(sheetIndex != null){\r\n cfg = $.extend(true, {}, _this.getSheetConfig());\r\n }\r\n else{\r\n cfg = $.extend(true, {}, Store.config);\r\n }\r\n\r\n if(cfg != null && cfg[\"merge\"] != null){\r\n for(let key in cfg[\"merge\"]){\r\n let mc = cfg[\"merge\"][key];\r\n if(!((st_r + rlen - 1) < mc.r || st_r > (mc.r + mc.rs - 1)) && !((st_c + clen - 1) < mc.c || st_c > (mc.c + mc.cs - 1))){\r\n mergelist.push(mc);\r\n }\r\n }\r\n }\r\n\r\n return mergelist;\r\n },\r\n mergeborer: function(d, row_index, col_index){\r\n if(d==null || d[row_index]==null){\r\n console.warn(\"Merge info is null\", row_index, col_index);\r\n return null;\r\n }\r\n let value = d[row_index][col_index];\r\n \r\n if(getObjType(value) == \"object\" && (\"mc\" in value)){\r\n let margeMaindata = value[\"mc\"];\r\n if(margeMaindata==null){\r\n console.warn(\"Merge info is null\", row_index, col_index);\r\n return null;\r\n }\r\n col_index = margeMaindata.c;\r\n row_index = margeMaindata.r;\r\n\r\n\r\n if(d[row_index][col_index]==null){\r\n console.warn(\"Main merge Cell info is null\", row_index, col_index);\r\n return null;\r\n }\r\n let col_rs = d[row_index][col_index].mc.cs;\r\n let row_rs = d[row_index][col_index].mc.rs;\r\n\r\n let margeMain = d[row_index][col_index].mc;\r\n \r\n let start_r, end_r, row, row_pre;\r\n for(let r = row_index; r < margeMain.rs + row_index; r++){\r\n if (r == 0) {\r\n start_r = - 1;\r\n }\r\n else {\r\n start_r = Store.visibledatarow[r - 1] - 1;\r\n }\r\n\r\n end_r = Store.visibledatarow[r];\r\n\r\n if(row_pre == null){\r\n row_pre = start_r;\r\n row = end_r;\r\n }\r\n else{\r\n row += end_r - start_r - 1;\r\n }\r\n }\r\n\r\n let start_c, end_c, col, col_pre; \r\n for(let c = col_index; c < margeMain.cs + col_index; c++){\r\n if (c == 0) {\r\n start_c = 0;\r\n }\r\n else {\r\n start_c = Store.visibledatacolumn[c - 1];\r\n }\r\n\r\n end_c = Store.visibledatacolumn[c];\r\n\r\n if(col_pre == null){\r\n col_pre = start_c;\r\n col = end_c;\r\n }\r\n else{\r\n col += end_c - start_c;\r\n }\r\n }\r\n\r\n return {\r\n \"row\": [row_pre , row, row_index, row_index + row_rs - 1], \r\n \"column\": [col_pre, col , col_index, col_index + col_rs - 1]\r\n };\r\n }\r\n else{\r\n return null;\r\n }\r\n },\r\n mergeMoveData: {},\r\n mergeMoveMain: function(columnseleted, rowseleted, s, top , height, left , width){\r\n let _this = this;\r\n let mergesetting = sheetmanage.getSheetMerge();\r\n \r\n if(mergesetting == null){\r\n return;\r\n }\r\n\r\n let mcset = [];\r\n for(let key in mergesetting){\r\n mcset.push(key);\r\n }\r\n\r\n if(rowseleted[0] > rowseleted[1]){\r\n rowseleted[1] = rowseleted[0];\r\n }\r\n\r\n if(columnseleted[0] > columnseleted[1]){\r\n columnseleted[1] = columnseleted[0];\r\n }\r\n\r\n let offloop = true;\r\n _this.mergeMoveData = {};\r\n\r\n while (offloop) {\r\n offloop = false;\r\n\r\n for(let i = 0; i < mcset.length; i++){\r\n let key = mcset[i];\r\n let mc = mergesetting[key];\r\n\r\n if(key in _this.mergeMoveData){\r\n continue;\r\n }\r\n\r\n let changeparam = _this.mergeMove(mc, columnseleted, rowseleted, s, top, height, left, width);\r\n\r\n if(changeparam != null){\r\n _this.mergeMoveData[key] = mc;\r\n \r\n columnseleted = changeparam[0];\r\n rowseleted= changeparam[1];\r\n top = changeparam[2];\r\n height = changeparam[3];\r\n left = changeparam[4];\r\n width = changeparam[5];\r\n\r\n offloop = true;\r\n }\r\n else{\r\n delete _this.mergeMoveData[key];\r\n }\r\n }\r\n }\r\n \r\n return [columnseleted, rowseleted, top, height, left, width];\r\n },\r\n mergeMove: function(mc, columnseleted, rowseleted, s, top , height, left , width){\r\n let _this = this;\r\n \r\n let row_st = mc.r, row_ed = mc.r + mc.rs - 1;\r\n let col_st = mc.c, col_ed = mc.c + mc.cs - 1;\r\n let ismatch = false;\r\n\r\n if(columnseleted[1] < columnseleted[0]){\r\n columnseleted[0] = columnseleted[1];\r\n }\r\n\r\n if(rowseleted[1] < rowseleted[0]){\r\n rowseleted[0] = rowseleted[1];\r\n }\r\n\r\n if( (columnseleted[0] <= col_st && columnseleted[1] >= col_ed && rowseleted[0] <= row_st && rowseleted[1] >= row_ed) || (!(columnseleted[1] < col_st || columnseleted[0] > col_ed) && !(rowseleted[1] < row_st || rowseleted[0] > row_ed))){\r\n let margeset = _this.mergeborer(Store.flowdata, mc.r, mc.c);\r\n if(!!margeset){\r\n let row = margeset.row[1],\r\n row_pre = margeset.row[0],\r\n row_index = margeset.row[2],\r\n col = margeset.column[1],\r\n col_pre = margeset.column[0],\r\n col_index = margeset.column[2];\r\n\r\n if(!(columnseleted[1] < col_st || columnseleted[0] > col_ed)){\r\n //向上滑动\r\n if(rowseleted[0] <= row_ed && rowseleted[0] >= row_st){\r\n height += top - row_pre;\r\n top = row_pre;\r\n rowseleted[0] = row_st;\r\n }\r\n \r\n //向下滑动或者居中时往上滑动的向下补齐\r\n if(rowseleted[1] >= row_st && rowseleted[1] <= row_ed){\r\n if(s.row_focus >= row_st && s.row_focus <= row_ed){\r\n height = row - top;\r\n }\r\n else{\r\n height = row - top;\r\n }\r\n \r\n rowseleted[1] = row_ed;\r\n }\r\n }\r\n \r\n if(!(rowseleted[1] < row_st || rowseleted[0] > row_ed)){\r\n if(columnseleted[0] <= col_ed && columnseleted[0] >= col_st){\r\n width += left - col_pre;\r\n left = col_pre;\r\n columnseleted[0] = col_st;\r\n }\r\n \r\n //向右滑动或者居中时往左滑动的向下补齐\r\n if(columnseleted[1] >= col_st && columnseleted[1] <= col_ed){\r\n if(s.column_focus >= col_st && s.column_focus <= col_ed){\r\n width = col - left;\r\n }\r\n else{\r\n width = col - left;\r\n }\r\n \r\n columnseleted[1] = col_ed;\r\n }\r\n }\r\n\r\n ismatch = true;\r\n }\r\n }\r\n \r\n if(ismatch){\r\n return [columnseleted, rowseleted, top , height, left , width];\r\n }\r\n else{\r\n return null;\r\n }\r\n },\r\n getCellRealSize: function(d, cell_r, cell_c){\r\n let _this = this;\r\n\r\n let width = Store.defaultcollen;\r\n let height = Store.defaultrowlen;\r\n let celldata = d[cell_r][cell_c];\r\n\r\n if(!!celldata && celldata[\"mc\"] != null){\r\n let mc = celldata[\"mc\"];\r\n let margeset = _this.mergeborer(d, mc.r, mc.c);\r\n\r\n if(!!margeset){\r\n let row = margeset.row[1];\r\n let row_pre = margeset.row[0];\r\n let row_index = margeset.row[2];\r\n let row_index_ed = margeset.row[3];\r\n\r\n let col = margeset.column[1];\r\n let col_pre = margeset.column[0];\r\n let col_index = margeset.column[2];\r\n let col_index_ed = margeset.column[3]; \r\n\r\n width = col - col_pre - 1;\r\n height = row - row_pre - 1;\r\n }\r\n }\r\n else{\r\n let config = getluckysheetfile()[getSheetIndex(Store.currentSheetIndex)][\"config\"];\r\n \r\n if (config[\"columnlen\"] != null && config[\"columnlen\"][cell_c] != null) {\r\n width = config[\"columnlen\"][cell_c];\r\n }\r\n \r\n if (config[\"rowlen\"] != null && config[\"rowlen\"][cell_r] != null) {\r\n height = config[\"rowlen\"][cell_r];\r\n }\r\n }\r\n\r\n return [width, height];\r\n },\r\n getTextHeightCache: {},\r\n getTextSize: function(text, font){\r\n let fontarray = locale().fontarray;\r\n let f = font || '10pt ' + fontarray[0];\r\n \r\n let _this = this;\r\n\r\n if (f in _this.getTextHeightCache){\r\n return _this.getTextHeightCache[f];\r\n }\r\n\r\n if($(\"#luckysheetTextSizeTest\").length == 0){\r\n $('').appendTo($('body'));\r\n }\r\n\r\n let o = $(\"#luckysheetTextSizeTest\").text(text).css({'font': f}),\r\n w = o.innerWidth(), \r\n h = o.innerHeight();\r\n\r\n _this.getTextHeightCache[f] = [w, h];\r\n \r\n return [w, h];\r\n },\r\n activeFormulaInput: function(row_index, col_index, rowh, columnh, formula, isnull){\r\n let _this = this;\r\n\r\n if(isnull == null){\r\n isnull = false;\r\n }\r\n\r\n luckysheetupdateCell(row_index, col_index, Store.flowdata, true);\r\n\r\n if(isnull){\r\n let formulaTxt = '='+ formula.toUpperCase() +'()';\r\n\r\n $(\"#luckysheet-rich-text-editor\").html(formulaTxt);\r\n\r\n let currSelection = window.getSelection();\r\n let $span = $(\"#luckysheet-rich-text-editor\").find(\"span\");\r\n luckysheetformula.setCaretPosition($span.get($span.length-2), 0, 1);\r\n\r\n return;\r\n }\r\n\r\n let row_pre = rowLocationByIndex(rowh[0])[0], \r\n row = rowLocationByIndex(rowh[1])[1], \r\n col_pre = colLocationByIndex(columnh[0])[0], \r\n col = colLocationByIndex(columnh[1])[1];\r\n\r\n let formulaTxt = '='+ formula.toUpperCase() +'('+ getRangetxt(Store.currentSheetIndex, {\"row\":rowh, \"column\":columnh }, Store.currentSheetIndex) +')';\r\n $(\"#luckysheet-rich-text-editor\").html(formulaTxt);\r\n\r\n luckysheetformula.israngeseleciton();\r\n luckysheetformula.rangestart = true;\r\n luckysheetformula.rangedrag_column_start = false;\r\n luckysheetformula.rangedrag_row_start = false;\r\n luckysheetformula.rangechangeindex = 0;\r\n luckysheetformula.rangeSetValue({ \"row\": rowh, \"column\": columnh });\r\n luckysheetformula.func_selectedrange = { \r\n \"left\": col_pre, \r\n \"width\": col - col_pre - 1, \r\n \"top\": row_pre, \r\n \"height\": row - row_pre - 1, \r\n \"left_move\": col_pre, \r\n \"width_move\": col - col_pre - 1, \r\n \"top_move\": row_pre, \r\n \"height_move\": row - row_pre - 1, \r\n \"row\": [row_index, row_index], \r\n \"column\": [col_index, col_index] \r\n };\r\n \r\n $(\"#luckysheet-formula-functionrange-select\").css({ \"left\": col_pre, \"width\": col - col_pre - 1, \"top\": row_pre, \"height\": row - row_pre - 1 }).show();\r\n\r\n $(\"#luckysheet-formula-help-c\").hide();\r\n },\r\n backFormulaInput: function(d, r, c, rowh, columnh, formula){\r\n let _this = this;\r\n\r\n let f = '='+ formula.toUpperCase() +'('+ getRangetxt(Store.currentSheetIndex, {\"row\":rowh, \"column\":columnh }, Store.currentSheetIndex) +')';\r\n let v = luckysheetformula.execfunction(f, r, c);\r\n let value = { \"v\": v[1], \"f\": v[2] };\r\n setcellvalue(r, c, d, value);\r\n luckysheetformula.execFunctionExist.push({ \"r\": r, \"c\": c, \"i\": Store.currentSheetIndex });\r\n\r\n server.historyParam(d, Store.currentSheetIndex, {\"row\": [r, r], \"column\": [c, c]});\r\n },\r\n checkNoNullValue: function(cell){\r\n let v = cell;\r\n if(getObjType(v) == \"object\"){\r\n v = v.v;\r\n }\r\n\r\n if(!isRealNull(v) && isdatatypemulti(v).num && (cell.ct == null || cell.ct.t == null || cell.ct.t == \"n\" || cell.ct.t == \"g\") ){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n },\r\n checkNoNullValueAll: function(cell){\r\n let v = cell;\r\n if(getObjType(v) == \"object\"){\r\n v = v.v;\r\n }\r\n\r\n if(!isRealNull(v)){\r\n return true;\r\n }\r\n else{\r\n return false;\r\n }\r\n },\r\n getNoNullValue: function(d, st_x, ed, type){\r\n let _this = this;\r\n let hasValueSum = 0, hasValueStart = null;\r\n let nullNum = 0, nullTime = 0;\r\n\r\n for(let r = ed - 1 ; r >= 0; r--){\r\n let cell;\r\n if(type == \"c\"){\r\n cell = d[st_x][r];\r\n }\r\n else{\r\n cell = d[r][st_x];\r\n }\r\n\r\n if(_this.checkNoNullValue(cell)){\r\n hasValueSum++;\r\n hasValueStart = r;\r\n }\r\n else if(cell == null || cell.v == null || cell.v == \"\"){\r\n nullNum++;\r\n\r\n if(nullNum >= 40){\r\n if(nullTime <= 0){\r\n nullTime = 1;\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n }\r\n else{\r\n break;\r\n }\r\n }\r\n\r\n return hasValueStart;\r\n },\r\n singleFormulaInput: function(d, _index, fix, st_m, ed_m, formula, type, noNum, noNull){\r\n let _this = this;\r\n\r\n if(type == null){\r\n type = \"r\";\r\n }\r\n\r\n if(noNum == null){\r\n noNum = true;\r\n }\r\n\r\n if(noNull == null){\r\n noNull = true;\r\n }\r\n \r\n let isNull = true, isNum= false;\r\n \r\n for(let c = st_m; c <= ed_m; c++){\r\n let cell = null;\r\n\r\n if(type == \"c\"){\r\n cell = d[c][fix];\r\n }\r\n else{\r\n cell = d[fix][c];\r\n }\r\n\r\n if(_this.checkNoNullValue(cell)){\r\n isNull = false;\r\n isNum= true;\r\n }\r\n else if(_this.checkNoNullValueAll(cell)){\r\n isNull = false;\r\n }\r\n } \r\n\r\n if(isNull && noNull){\r\n let st_r_r = _this.getNoNullValue(d, _index, fix, type);\r\n\r\n if(st_r_r == null){\r\n if(type == \"c\"){\r\n _this.activeFormulaInput(_index, fix, null, null, formula, true);\r\n }\r\n else{\r\n _this.activeFormulaInput(fix, _index, null, null, formula, true);\r\n }\r\n }\r\n else{\r\n if(_index == st_m){\r\n for(let c = st_m; c <= ed_m; c++){\r\n let st_r_r = _this.getNoNullValue(d, c, fix, type);\r\n \r\n if(st_r_r == null){\r\n break;\r\n }\r\n\r\n if(type == \"c\"){\r\n _this.backFormulaInput(d, c, fix, [c, c], [st_r_r, fix-1], formula);\r\n }\r\n else{\r\n _this.backFormulaInput(d, fix, c, [st_r_r, fix-1], [c, c], formula);\r\n }\r\n }\r\n }\r\n else{\r\n for(let c = ed_m; c >= st_m; c--){\r\n let st_r_r = _this.getNoNullValue(d, c, fix, type);\r\n \r\n if(st_r_r == null){\r\n break;\r\n }\r\n\r\n if(type == \"c\"){\r\n _this.backFormulaInput(d, c, fix, [c, c], [st_r_r, fix-1], formula);\r\n }\r\n else{\r\n _this.backFormulaInput(d, fix, c, [st_r_r, fix-1], [c, c], formula);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n else if(isNum && noNum){\r\n let cell = null;\r\n\r\n if(type == \"c\"){\r\n cell = d[ed_m][fix];\r\n }\r\n else{\r\n cell = d[fix][ed_m];\r\n }\r\n\r\n if(cell != null && cell.v != null && cell.v.toString().length > 0){\r\n let c = ed_m;\r\n\r\n if(type == \"c\"){\r\n cell = d[ed_m][fix];\r\n }\r\n else{\r\n cell = d[fix][ed_m];\r\n }\r\n\r\n while ( cell != null && cell.v != null && cell.v.toString().length > 0) {\r\n c++;\r\n let len = null;\r\n \r\n if(type == \"c\"){\r\n len = d.length;\r\n }\r\n else{\r\n len = d[0].length;\r\n }\r\n\r\n if(c >= len){\r\n return;\r\n }\r\n \r\n if(type == \"c\"){\r\n cell = d[c][fix];\r\n }\r\n else{\r\n cell = d[fix][c];\r\n }\r\n }\r\n\r\n if(type == \"c\"){\r\n _this.backFormulaInput(d, c, fix, [st_m, ed_m], [fix ,fix], formula);\r\n }\r\n else{\r\n _this.backFormulaInput(d, fix, c, [fix ,fix], [st_m, ed_m], formula);\r\n }\r\n }\r\n else{\r\n if(type == \"c\"){\r\n _this.backFormulaInput(d, ed_m, fix, [st_m, ed_m], [fix ,fix], formula);\r\n }\r\n else{\r\n _this.backFormulaInput(d, fix, ed_m, [fix ,fix], [st_m, ed_m], formula);\r\n }\r\n }\r\n }\r\n else{\r\n return true;\r\n }\r\n },\r\n autoSelectionFormula: function(formula){\r\n let _this = this;\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n let nullfindnum = 40;\r\n let isfalse = true;\r\n luckysheetformula.execFunctionExist = [];\r\n\r\n let execFormulaInput_c = function(d, st_r, ed_r, st_c, ed_c, formula){\r\n let st_c_c = _this.getNoNullValue(d, st_r, ed_c, \"c\");\r\n\r\n if(st_c_c == null){\r\n _this.activeFormulaInput(st_r, st_c, null, null, formula, true);\r\n }\r\n else{\r\n _this.activeFormulaInput(st_r, st_c, [st_r, ed_r], [st_c_c, ed_c - 1], formula);\r\n }\r\n }\r\n\r\n let execFormulaInput = function(d, st_r, ed_r, st_c, ed_c, formula){\r\n let st_r_c = _this.getNoNullValue(d, st_c, ed_r, \"r\");\r\n\r\n if(st_r_c == null){\r\n execFormulaInput_c(d, st_r, ed_r, st_c, ed_c, formula);\r\n }\r\n else{\r\n _this.activeFormulaInput(st_r, st_c, [st_r_c, ed_r - 1], [st_c, ed_c], formula);\r\n }\r\n }\r\n\r\n for(let s = 0; s < Store.luckysheet_select_save.length; s++){\r\n let st_r = Store.luckysheet_select_save[s].row[0], \r\n ed_r = Store.luckysheet_select_save[s].row[1];\r\n let st_c = Store.luckysheet_select_save[s].column[0], \r\n ed_c = Store.luckysheet_select_save[s].column[1];\r\n let row_index = Store.luckysheet_select_save[s].row_focus, \r\n col_index = Store.luckysheet_select_save[s].column_focus;\r\n\r\n if(st_r == ed_r && st_c == ed_c){\r\n if(ed_r - 1 < 0 && ed_c - 1 < 0){\r\n _this.activeFormulaInput(st_r, st_c, null, null, formula, true);\r\n return;\r\n }\r\n\r\n if(ed_r - 1 >= 0 && _this.checkNoNullValue(d[ed_r - 1][st_c])){\r\n execFormulaInput(d, st_r, ed_r, st_c, ed_c, formula);\r\n }\r\n else if(ed_c - 1 >= 0 && _this.checkNoNullValue(d[st_r][ed_c - 1])){\r\n execFormulaInput_c(d, st_r, ed_r, st_c, ed_c, formula);\r\n }\r\n else{\r\n execFormulaInput(d, st_r, ed_r, st_c, ed_c, formula);\r\n }\r\n }\r\n else if(st_r == ed_r){\r\n isfalse = _this.singleFormulaInput(d, col_index, st_r, st_c, ed_c, formula, \"r\");\r\n }\r\n else if(st_c == ed_c){\r\n isfalse = _this.singleFormulaInput(d, row_index, st_c, st_r, ed_r, formula, \"c\");\r\n }\r\n else{\r\n let r_false = true;\r\n for(let r = st_r; r <= ed_r; r++){\r\n r_false = _this.singleFormulaInput(d, col_index, r, st_c, ed_c, formula, \"r\", true, false) && r_false;\r\n }\r\n\r\n let c_false = true;\r\n for(let c = st_c; c <= ed_c; c++){\r\n c_false = _this.singleFormulaInput(d, row_index, c, st_r, ed_r, formula, \"c\", true, false) && c_false;\r\n }\r\n\r\n isfalse = !!r_false && !!c_false;\r\n }\r\n\r\n isfalse = isfalse && isfalse;\r\n }\r\n\r\n if(!isfalse){\r\n luckysheetformula.execFunctionExist.reverse();\r\n luckysheetformula.execFunctionGroup(null, null, null, null, d);\r\n jfrefreshgrid(d, Store.luckysheet_select_save);\r\n\r\n clearTimeout(Store.jfcountfuncTimeout);\r\n Store.jfcountfuncTimeout = setTimeout(function () { countfunc() }, 500);\r\n }\r\n },\r\n getStyleByCell: function(d, r, c){\r\n let _this = this;\r\n let style = \"\";\r\n \r\n //交替颜色\r\n let af_compute = alternateformat.getComputeMap();\r\n let checksAF = alternateformat.checksAF(r, c, af_compute);\r\n\r\n //条件格式\r\n let cf_compute = conditionformat.getComputeMap();\r\n let checksCF = conditionformat.checksCF(r, c, cf_compute);\r\n\r\n const locale_fontarray = locale().fontarray;\r\n\r\n let cell = d[r][c];\r\n let ct = cell.ct, isInline=false;\r\n if(isInlineStringCell(cell)){\r\n isInline = true;\r\n }\r\n for(let key in cell){\r\n let value = _this.checkstatus(d, r, c , key);\r\n\r\n if(checksAF != null || (checksCF != null && checksCF[\"cellColor\"] != null)){\r\n if(checksCF != null && checksCF[\"cellColor\"] != null){\r\n style += \"background: \" + checksCF[\"cellColor\"] + \";\";\r\n }\r\n else if(checksAF != null){\r\n style += \"background: \" + checksAF[1] + \";\";\r\n }\r\n }\r\n\r\n if(getObjType(value) == \"object\"){\r\n continue;\r\n }\r\n\r\n if(key == \"bg\" || checksAF != null || (checksCF != null && checksCF[\"cellColor\"] != null)){\r\n if(checksCF != null && checksCF[\"cellColor\"] != null){\r\n style += \"background: \" + checksCF[\"cellColor\"] + \";\";\r\n }\r\n else if(checksAF != null){\r\n style += \"background: \" + checksAF[1] + \";\";\r\n }\r\n else{\r\n style += \"background: \" + value + \";\";\r\n }\r\n }\r\n\r\n // if(!isInline){\r\n // if(key == \"bl\" && value != \"0\"){\r\n // style += \"font-weight: bold;\";\r\n // }\r\n \r\n // if(key == \"it\" && value != \"0\"){\r\n // style += \"font-style:italic;\";\r\n // }\r\n \r\n // if(key == \"ff\" && value != \"0\"){\r\n // let f = value;\r\n // if(!isNaN(parseInt(value))){\r\n // f = locale_fontarray[parseInt(value)];\r\n // }\r\n // style += \"font-family: \" + f + \";\";\r\n // }\r\n \r\n // if(key == \"fs\" && value != \"10\"){\r\n // style += \"font-size: \"+ value + \"pt;\";\r\n // }\r\n \r\n // if((key == \"fc\" && value != \"#000000\") || checksAF != null || (checksCF != null && checksCF[\"textColor\"] != null)){\r\n // if(checksCF != null && checksCF[\"textColor\"] != null){\r\n // style += \"color: \" + checksCF[\"textColor\"] + \";\";\r\n // }\r\n // else if(checksAF != null){\r\n // style += \"color: \" + checksAF[0] + \";\";\r\n // }\r\n // else{\r\n // style += \"color: \" + value + \";\"; \r\n // }\r\n // }\r\n // }\r\n\r\n if(key == \"ht\" && value != \"1\"){\r\n if(value == \"0\"){\r\n style += \"text-align: center;\";\r\n }\r\n else if(value == \"2\"){\r\n style += \"text-align: right;\";\r\n }\r\n }\r\n\r\n if(key == \"vt\" && value != \"1\"){\r\n if(value == \"0\"){\r\n style += \"align-items: center;\";\r\n }\r\n else if(value == \"2\"){\r\n style += \"align-items: flex-end;\";\r\n }\r\n }\r\n }\r\n\r\n if(!isInline){\r\n style += getFontStyleByCell(cell,checksAF,checksCF);\r\n }\r\n\r\n return style;\r\n },\r\n fontSelectList:[],\r\n defualtFont:[\"Times New Roman\",\"Arial\",\"Tahoma\",\"Verdana\",\"微软雅黑\",\"宋体\",\"黑体\",\"楷体\",\"仿宋\",\"新宋体\",\"华文新魏\",\"华文行楷\",\"华文隶书\"],\r\n addFontTolist:function(fontName) {\r\n fontName = fontName.replace(/\"/g, \"\").replace(/'/g, \"\");\r\n let isNone = true;\r\n for(let a=0;a\"+fontName+\"\";\r\n ret.example = \"\";\r\n this.fontSelectList.push(ret);\r\n\r\n let $menuButton = $(\"#luckysheet-icon-font-family-menuButton\");\r\n let itemset = this.createButtonMenu(this.fontSelectList);\r\n $menuButton.html(itemset);\r\n }\r\n },\r\n fontInitial:function(fontList) {\r\n let itemdata = [];\r\n const locale_fontarray = locale().fontarray;\r\n for(let a=0;a\"+fItem+\"\";\r\n ret.example = \"\";\r\n itemdata.push(ret);\r\n }\r\n\r\n if(fontList!=null){\r\n for(let a=0;a\"+fItem.fontName+\"\";\r\n ret.example = \"\";\r\n itemdata.push(ret);\r\n\r\n if(document.fonts && !document.fonts.check(\"12px \"+fItem.fontName)){\r\n if(fItem.url){\r\n const fontface = new FontFace(fItem.fontName, `url(${fItem.url})`);\r\n document.fonts.add(fontface);\r\n fontface.load();\r\n }\r\n }\r\n }\r\n\r\n document.fonts && document.fonts.ready.then(function() {\r\n // Any operation that needs to be done only after all the fonts\r\n // have finished loading can go here.\r\n // console.log(\"font ready\");\r\n });\r\n }\r\n\r\n this.fontSelectList = itemdata;\r\n }\r\n}\r\n\r\nexport default menuButton;","module.exports = typeof ArrayBuffer !== 'undefined' && typeof DataView !== 'undefined';\n","'use strict';\nvar NATIVE_ARRAY_BUFFER = require('../internals/array-buffer-native');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar global = require('../internals/global');\nvar isObject = require('../internals/is-object');\nvar has = require('../internals/has');\nvar classof = require('../internals/classof');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar redefine = require('../internals/redefine');\nvar defineProperty = require('../internals/object-define-property').f;\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\nvar setPrototypeOf = require('../internals/object-set-prototype-of');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar uid = require('../internals/uid');\n\nvar Int8Array = global.Int8Array;\nvar Int8ArrayPrototype = Int8Array && Int8Array.prototype;\nvar Uint8ClampedArray = global.Uint8ClampedArray;\nvar Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype;\nvar TypedArray = Int8Array && getPrototypeOf(Int8Array);\nvar TypedArrayPrototype = Int8ArrayPrototype && getPrototypeOf(Int8ArrayPrototype);\nvar ObjectPrototype = Object.prototype;\nvar isPrototypeOf = ObjectPrototype.isPrototypeOf;\n\nvar TO_STRING_TAG = wellKnownSymbol('toStringTag');\nvar TYPED_ARRAY_TAG = uid('TYPED_ARRAY_TAG');\n// Fixing native typed arrays in Opera Presto crashes the browser, see #595\nvar NATIVE_ARRAY_BUFFER_VIEWS = NATIVE_ARRAY_BUFFER && !!setPrototypeOf && classof(global.opera) !== 'Opera';\nvar TYPED_ARRAY_TAG_REQIRED = false;\nvar NAME;\n\nvar TypedArrayConstructorsList = {\n Int8Array: 1,\n Uint8Array: 1,\n Uint8ClampedArray: 1,\n Int16Array: 2,\n Uint16Array: 2,\n Int32Array: 4,\n Uint32Array: 4,\n Float32Array: 4,\n Float64Array: 8\n};\n\nvar isView = function isView(it) {\n var klass = classof(it);\n return klass === 'DataView' || has(TypedArrayConstructorsList, klass);\n};\n\nvar isTypedArray = function (it) {\n return isObject(it) && has(TypedArrayConstructorsList, classof(it));\n};\n\nvar aTypedArray = function (it) {\n if (isTypedArray(it)) return it;\n throw TypeError('Target is not a typed array');\n};\n\nvar aTypedArrayConstructor = function (C) {\n if (setPrototypeOf) {\n if (isPrototypeOf.call(TypedArray, C)) return C;\n } else for (var ARRAY in TypedArrayConstructorsList) if (has(TypedArrayConstructorsList, NAME)) {\n var TypedArrayConstructor = global[ARRAY];\n if (TypedArrayConstructor && (C === TypedArrayConstructor || isPrototypeOf.call(TypedArrayConstructor, C))) {\n return C;\n }\n } throw TypeError('Target is not a typed array constructor');\n};\n\nvar exportTypedArrayMethod = function (KEY, property, forced) {\n if (!DESCRIPTORS) return;\n if (forced) for (var ARRAY in TypedArrayConstructorsList) {\n var TypedArrayConstructor = global[ARRAY];\n if (TypedArrayConstructor && has(TypedArrayConstructor.prototype, KEY)) {\n delete TypedArrayConstructor.prototype[KEY];\n }\n }\n if (!TypedArrayPrototype[KEY] || forced) {\n redefine(TypedArrayPrototype, KEY, forced ? property\n : NATIVE_ARRAY_BUFFER_VIEWS && Int8ArrayPrototype[KEY] || property);\n }\n};\n\nvar exportTypedArrayStaticMethod = function (KEY, property, forced) {\n var ARRAY, TypedArrayConstructor;\n if (!DESCRIPTORS) return;\n if (setPrototypeOf) {\n if (forced) for (ARRAY in TypedArrayConstructorsList) {\n TypedArrayConstructor = global[ARRAY];\n if (TypedArrayConstructor && has(TypedArrayConstructor, KEY)) {\n delete TypedArrayConstructor[KEY];\n }\n }\n if (!TypedArray[KEY] || forced) {\n // V8 ~ Chrome 49-50 `%TypedArray%` methods are non-writable non-configurable\n try {\n return redefine(TypedArray, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && Int8Array[KEY] || property);\n } catch (error) { /* empty */ }\n } else return;\n }\n for (ARRAY in TypedArrayConstructorsList) {\n TypedArrayConstructor = global[ARRAY];\n if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) {\n redefine(TypedArrayConstructor, KEY, property);\n }\n }\n};\n\nfor (NAME in TypedArrayConstructorsList) {\n if (!global[NAME]) NATIVE_ARRAY_BUFFER_VIEWS = false;\n}\n\n// WebKit bug - typed arrays constructors prototype is Object.prototype\nif (!NATIVE_ARRAY_BUFFER_VIEWS || typeof TypedArray != 'function' || TypedArray === Function.prototype) {\n // eslint-disable-next-line no-shadow\n TypedArray = function TypedArray() {\n throw TypeError('Incorrect invocation');\n };\n if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {\n if (global[NAME]) setPrototypeOf(global[NAME], TypedArray);\n }\n}\n\nif (!NATIVE_ARRAY_BUFFER_VIEWS || !TypedArrayPrototype || TypedArrayPrototype === ObjectPrototype) {\n TypedArrayPrototype = TypedArray.prototype;\n if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {\n if (global[NAME]) setPrototypeOf(global[NAME].prototype, TypedArrayPrototype);\n }\n}\n\n// WebKit bug - one more object in Uint8ClampedArray prototype chain\nif (NATIVE_ARRAY_BUFFER_VIEWS && getPrototypeOf(Uint8ClampedArrayPrototype) !== TypedArrayPrototype) {\n setPrototypeOf(Uint8ClampedArrayPrototype, TypedArrayPrototype);\n}\n\nif (DESCRIPTORS && !has(TypedArrayPrototype, TO_STRING_TAG)) {\n TYPED_ARRAY_TAG_REQIRED = true;\n defineProperty(TypedArrayPrototype, TO_STRING_TAG, { get: function () {\n return isObject(this) ? this[TYPED_ARRAY_TAG] : undefined;\n } });\n for (NAME in TypedArrayConstructorsList) if (global[NAME]) {\n createNonEnumerableProperty(global[NAME], TYPED_ARRAY_TAG, NAME);\n }\n}\n\nmodule.exports = {\n NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS,\n TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQIRED && TYPED_ARRAY_TAG,\n aTypedArray: aTypedArray,\n aTypedArrayConstructor: aTypedArrayConstructor,\n exportTypedArrayMethod: exportTypedArrayMethod,\n exportTypedArrayStaticMethod: exportTypedArrayStaticMethod,\n isView: isView,\n isTypedArray: isTypedArray,\n TypedArray: TypedArray,\n TypedArrayPrototype: TypedArrayPrototype\n};\n","/* eslint-disable no-new */\nvar global = require('../internals/global');\nvar fails = require('../internals/fails');\nvar checkCorrectnessOfIteration = require('../internals/check-correctness-of-iteration');\nvar NATIVE_ARRAY_BUFFER_VIEWS = require('../internals/array-buffer-view-core').NATIVE_ARRAY_BUFFER_VIEWS;\n\nvar ArrayBuffer = global.ArrayBuffer;\nvar Int8Array = global.Int8Array;\n\nmodule.exports = !NATIVE_ARRAY_BUFFER_VIEWS || !fails(function () {\n Int8Array(1);\n}) || !fails(function () {\n new Int8Array(-1);\n}) || !checkCorrectnessOfIteration(function (iterable) {\n new Int8Array();\n new Int8Array(null);\n new Int8Array(1.5);\n new Int8Array(iterable);\n}, true) || fails(function () {\n // Safari (11+) bug - a reason why even Safari 13 should load a typed array polyfill\n return new Int8Array(new ArrayBuffer(2), 1, undefined).length !== 1;\n});\n","var toInteger = require('../internals/to-integer');\nvar toLength = require('../internals/to-length');\n\n// `ToIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-toindex\nmodule.exports = function (it) {\n if (it === undefined) return 0;\n var number = toInteger(it);\n var length = toLength(number);\n if (number !== length) throw RangeError('Wrong length or index');\n return length;\n};\n","// IEEE754 conversions based on https://github.com/feross/ieee754\n// eslint-disable-next-line no-shadow-restricted-names\nvar Infinity = 1 / 0;\nvar abs = Math.abs;\nvar pow = Math.pow;\nvar floor = Math.floor;\nvar log = Math.log;\nvar LN2 = Math.LN2;\n\nvar pack = function (number, mantissaLength, bytes) {\n var buffer = new Array(bytes);\n var exponentLength = bytes * 8 - mantissaLength - 1;\n var eMax = (1 << exponentLength) - 1;\n var eBias = eMax >> 1;\n var rt = mantissaLength === 23 ? pow(2, -24) - pow(2, -77) : 0;\n var sign = number < 0 || number === 0 && 1 / number < 0 ? 1 : 0;\n var index = 0;\n var exponent, mantissa, c;\n number = abs(number);\n // eslint-disable-next-line no-self-compare\n if (number != number || number === Infinity) {\n // eslint-disable-next-line no-self-compare\n mantissa = number != number ? 1 : 0;\n exponent = eMax;\n } else {\n exponent = floor(log(number) / LN2);\n if (number * (c = pow(2, -exponent)) < 1) {\n exponent--;\n c *= 2;\n }\n if (exponent + eBias >= 1) {\n number += rt / c;\n } else {\n number += rt * pow(2, 1 - eBias);\n }\n if (number * c >= 2) {\n exponent++;\n c /= 2;\n }\n if (exponent + eBias >= eMax) {\n mantissa = 0;\n exponent = eMax;\n } else if (exponent + eBias >= 1) {\n mantissa = (number * c - 1) * pow(2, mantissaLength);\n exponent = exponent + eBias;\n } else {\n mantissa = number * pow(2, eBias - 1) * pow(2, mantissaLength);\n exponent = 0;\n }\n }\n for (; mantissaLength >= 8; buffer[index++] = mantissa & 255, mantissa /= 256, mantissaLength -= 8);\n exponent = exponent << mantissaLength | mantissa;\n exponentLength += mantissaLength;\n for (; exponentLength > 0; buffer[index++] = exponent & 255, exponent /= 256, exponentLength -= 8);\n buffer[--index] |= sign * 128;\n return buffer;\n};\n\nvar unpack = function (buffer, mantissaLength) {\n var bytes = buffer.length;\n var exponentLength = bytes * 8 - mantissaLength - 1;\n var eMax = (1 << exponentLength) - 1;\n var eBias = eMax >> 1;\n var nBits = exponentLength - 7;\n var index = bytes - 1;\n var sign = buffer[index--];\n var exponent = sign & 127;\n var mantissa;\n sign >>= 7;\n for (; nBits > 0; exponent = exponent * 256 + buffer[index], index--, nBits -= 8);\n mantissa = exponent & (1 << -nBits) - 1;\n exponent >>= -nBits;\n nBits += mantissaLength;\n for (; nBits > 0; mantissa = mantissa * 256 + buffer[index], index--, nBits -= 8);\n if (exponent === 0) {\n exponent = 1 - eBias;\n } else if (exponent === eMax) {\n return mantissa ? NaN : sign ? -Infinity : Infinity;\n } else {\n mantissa = mantissa + pow(2, mantissaLength);\n exponent = exponent - eBias;\n } return (sign ? -1 : 1) * mantissa * pow(2, exponent - mantissaLength);\n};\n\nmodule.exports = {\n pack: pack,\n unpack: unpack\n};\n","'use strict';\nvar global = require('../internals/global');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar NATIVE_ARRAY_BUFFER = require('../internals/array-buffer-native');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar redefineAll = require('../internals/redefine-all');\nvar fails = require('../internals/fails');\nvar anInstance = require('../internals/an-instance');\nvar toInteger = require('../internals/to-integer');\nvar toLength = require('../internals/to-length');\nvar toIndex = require('../internals/to-index');\nvar IEEE754 = require('../internals/ieee754');\nvar getPrototypeOf = require('../internals/object-get-prototype-of');\nvar setPrototypeOf = require('../internals/object-set-prototype-of');\nvar getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar defineProperty = require('../internals/object-define-property').f;\nvar arrayFill = require('../internals/array-fill');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar InternalStateModule = require('../internals/internal-state');\n\nvar getInternalState = InternalStateModule.get;\nvar setInternalState = InternalStateModule.set;\nvar ARRAY_BUFFER = 'ArrayBuffer';\nvar DATA_VIEW = 'DataView';\nvar PROTOTYPE = 'prototype';\nvar WRONG_LENGTH = 'Wrong length';\nvar WRONG_INDEX = 'Wrong index';\nvar NativeArrayBuffer = global[ARRAY_BUFFER];\nvar $ArrayBuffer = NativeArrayBuffer;\nvar $DataView = global[DATA_VIEW];\nvar $DataViewPrototype = $DataView && $DataView[PROTOTYPE];\nvar ObjectPrototype = Object.prototype;\nvar RangeError = global.RangeError;\n\nvar packIEEE754 = IEEE754.pack;\nvar unpackIEEE754 = IEEE754.unpack;\n\nvar packInt8 = function (number) {\n return [number & 0xFF];\n};\n\nvar packInt16 = function (number) {\n return [number & 0xFF, number >> 8 & 0xFF];\n};\n\nvar packInt32 = function (number) {\n return [number & 0xFF, number >> 8 & 0xFF, number >> 16 & 0xFF, number >> 24 & 0xFF];\n};\n\nvar unpackInt32 = function (buffer) {\n return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];\n};\n\nvar packFloat32 = function (number) {\n return packIEEE754(number, 23, 4);\n};\n\nvar packFloat64 = function (number) {\n return packIEEE754(number, 52, 8);\n};\n\nvar addGetter = function (Constructor, key) {\n defineProperty(Constructor[PROTOTYPE], key, { get: function () { return getInternalState(this)[key]; } });\n};\n\nvar get = function (view, count, index, isLittleEndian) {\n var intIndex = toIndex(index);\n var store = getInternalState(view);\n if (intIndex + count > store.byteLength) throw RangeError(WRONG_INDEX);\n var bytes = getInternalState(store.buffer).bytes;\n var start = intIndex + store.byteOffset;\n var pack = bytes.slice(start, start + count);\n return isLittleEndian ? pack : pack.reverse();\n};\n\nvar set = function (view, count, index, conversion, value, isLittleEndian) {\n var intIndex = toIndex(index);\n var store = getInternalState(view);\n if (intIndex + count > store.byteLength) throw RangeError(WRONG_INDEX);\n var bytes = getInternalState(store.buffer).bytes;\n var start = intIndex + store.byteOffset;\n var pack = conversion(+value);\n for (var i = 0; i < count; i++) bytes[start + i] = pack[isLittleEndian ? i : count - i - 1];\n};\n\nif (!NATIVE_ARRAY_BUFFER) {\n $ArrayBuffer = function ArrayBuffer(length) {\n anInstance(this, $ArrayBuffer, ARRAY_BUFFER);\n var byteLength = toIndex(length);\n setInternalState(this, {\n bytes: arrayFill.call(new Array(byteLength), 0),\n byteLength: byteLength\n });\n if (!DESCRIPTORS) this.byteLength = byteLength;\n };\n\n $DataView = function DataView(buffer, byteOffset, byteLength) {\n anInstance(this, $DataView, DATA_VIEW);\n anInstance(buffer, $ArrayBuffer, DATA_VIEW);\n var bufferLength = getInternalState(buffer).byteLength;\n var offset = toInteger(byteOffset);\n if (offset < 0 || offset > bufferLength) throw RangeError('Wrong offset');\n byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);\n if (offset + byteLength > bufferLength) throw RangeError(WRONG_LENGTH);\n setInternalState(this, {\n buffer: buffer,\n byteLength: byteLength,\n byteOffset: offset\n });\n if (!DESCRIPTORS) {\n this.buffer = buffer;\n this.byteLength = byteLength;\n this.byteOffset = offset;\n }\n };\n\n if (DESCRIPTORS) {\n addGetter($ArrayBuffer, 'byteLength');\n addGetter($DataView, 'buffer');\n addGetter($DataView, 'byteLength');\n addGetter($DataView, 'byteOffset');\n }\n\n redefineAll($DataView[PROTOTYPE], {\n getInt8: function getInt8(byteOffset) {\n return get(this, 1, byteOffset)[0] << 24 >> 24;\n },\n getUint8: function getUint8(byteOffset) {\n return get(this, 1, byteOffset)[0];\n },\n getInt16: function getInt16(byteOffset /* , littleEndian */) {\n var bytes = get(this, 2, byteOffset, arguments.length > 1 ? arguments[1] : undefined);\n return (bytes[1] << 8 | bytes[0]) << 16 >> 16;\n },\n getUint16: function getUint16(byteOffset /* , littleEndian */) {\n var bytes = get(this, 2, byteOffset, arguments.length > 1 ? arguments[1] : undefined);\n return bytes[1] << 8 | bytes[0];\n },\n getInt32: function getInt32(byteOffset /* , littleEndian */) {\n return unpackInt32(get(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined));\n },\n getUint32: function getUint32(byteOffset /* , littleEndian */) {\n return unpackInt32(get(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined)) >>> 0;\n },\n getFloat32: function getFloat32(byteOffset /* , littleEndian */) {\n return unpackIEEE754(get(this, 4, byteOffset, arguments.length > 1 ? arguments[1] : undefined), 23);\n },\n getFloat64: function getFloat64(byteOffset /* , littleEndian */) {\n return unpackIEEE754(get(this, 8, byteOffset, arguments.length > 1 ? arguments[1] : undefined), 52);\n },\n setInt8: function setInt8(byteOffset, value) {\n set(this, 1, byteOffset, packInt8, value);\n },\n setUint8: function setUint8(byteOffset, value) {\n set(this, 1, byteOffset, packInt8, value);\n },\n setInt16: function setInt16(byteOffset, value /* , littleEndian */) {\n set(this, 2, byteOffset, packInt16, value, arguments.length > 2 ? arguments[2] : undefined);\n },\n setUint16: function setUint16(byteOffset, value /* , littleEndian */) {\n set(this, 2, byteOffset, packInt16, value, arguments.length > 2 ? arguments[2] : undefined);\n },\n setInt32: function setInt32(byteOffset, value /* , littleEndian */) {\n set(this, 4, byteOffset, packInt32, value, arguments.length > 2 ? arguments[2] : undefined);\n },\n setUint32: function setUint32(byteOffset, value /* , littleEndian */) {\n set(this, 4, byteOffset, packInt32, value, arguments.length > 2 ? arguments[2] : undefined);\n },\n setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) {\n set(this, 4, byteOffset, packFloat32, value, arguments.length > 2 ? arguments[2] : undefined);\n },\n setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) {\n set(this, 8, byteOffset, packFloat64, value, arguments.length > 2 ? arguments[2] : undefined);\n }\n });\n} else {\n if (!fails(function () {\n NativeArrayBuffer(1);\n }) || !fails(function () {\n new NativeArrayBuffer(-1); // eslint-disable-line no-new\n }) || fails(function () {\n new NativeArrayBuffer(); // eslint-disable-line no-new\n new NativeArrayBuffer(1.5); // eslint-disable-line no-new\n new NativeArrayBuffer(NaN); // eslint-disable-line no-new\n return NativeArrayBuffer.name != ARRAY_BUFFER;\n })) {\n $ArrayBuffer = function ArrayBuffer(length) {\n anInstance(this, $ArrayBuffer);\n return new NativeArrayBuffer(toIndex(length));\n };\n var ArrayBufferPrototype = $ArrayBuffer[PROTOTYPE] = NativeArrayBuffer[PROTOTYPE];\n for (var keys = getOwnPropertyNames(NativeArrayBuffer), j = 0, key; keys.length > j;) {\n if (!((key = keys[j++]) in $ArrayBuffer)) {\n createNonEnumerableProperty($ArrayBuffer, key, NativeArrayBuffer[key]);\n }\n }\n ArrayBufferPrototype.constructor = $ArrayBuffer;\n }\n\n // WebKit bug - the same parent prototype for typed arrays and data view\n if (setPrototypeOf && getPrototypeOf($DataViewPrototype) !== ObjectPrototype) {\n setPrototypeOf($DataViewPrototype, ObjectPrototype);\n }\n\n // iOS Safari 7.x bug\n var testView = new $DataView(new $ArrayBuffer(2));\n var nativeSetInt8 = $DataViewPrototype.setInt8;\n testView.setInt8(0, 2147483648);\n testView.setInt8(1, 2147483649);\n if (testView.getInt8(0) || !testView.getInt8(1)) redefineAll($DataViewPrototype, {\n setInt8: function setInt8(byteOffset, value) {\n nativeSetInt8.call(this, byteOffset, value << 24 >> 24);\n },\n setUint8: function setUint8(byteOffset, value) {\n nativeSetInt8.call(this, byteOffset, value << 24 >> 24);\n }\n }, { unsafe: true });\n}\n\nsetToStringTag($ArrayBuffer, ARRAY_BUFFER);\nsetToStringTag($DataView, DATA_VIEW);\n\nmodule.exports = {\n ArrayBuffer: $ArrayBuffer,\n DataView: $DataView\n};\n","var toPositiveInteger = require('../internals/to-positive-integer');\n\nmodule.exports = function (it, BYTES) {\n var offset = toPositiveInteger(it);\n if (offset % BYTES) throw RangeError('Wrong offset');\n return offset;\n};\n","var toInteger = require('../internals/to-integer');\n\nmodule.exports = function (it) {\n var result = toInteger(it);\n if (result < 0) throw RangeError(\"The argument can't be less than 0\");\n return result;\n};\n","var toObject = require('../internals/to-object');\nvar toLength = require('../internals/to-length');\nvar getIteratorMethod = require('../internals/get-iterator-method');\nvar isArrayIteratorMethod = require('../internals/is-array-iterator-method');\nvar bind = require('../internals/function-bind-context');\nvar aTypedArrayConstructor = require('../internals/array-buffer-view-core').aTypedArrayConstructor;\n\nmodule.exports = function from(source /* , mapfn, thisArg */) {\n var O = toObject(source);\n var argumentsLength = arguments.length;\n var mapfn = argumentsLength > 1 ? arguments[1] : undefined;\n var mapping = mapfn !== undefined;\n var iteratorMethod = getIteratorMethod(O);\n var i, length, result, step, iterator, next;\n if (iteratorMethod != undefined && !isArrayIteratorMethod(iteratorMethod)) {\n iterator = iteratorMethod.call(O);\n next = iterator.next;\n O = [];\n while (!(step = next.call(iterator)).done) {\n O.push(step.value);\n }\n }\n if (mapping && argumentsLength > 2) {\n mapfn = bind(mapfn, arguments[2], 2);\n }\n length = toLength(O.length);\n result = new (aTypedArrayConstructor(this))(length);\n for (i = 0; length > i; i++) {\n result[i] = mapping ? mapfn(O[i], i) : O[i];\n }\n return result;\n};\n","'use strict';\nvar $ = require('../internals/export');\nvar global = require('../internals/global');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar TYPED_ARRAYS_CONSTRUCTORS_REQUIRES_WRAPPERS = require('../internals/typed-array-constructors-require-wrappers');\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar ArrayBufferModule = require('../internals/array-buffer');\nvar anInstance = require('../internals/an-instance');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar createNonEnumerableProperty = require('../internals/create-non-enumerable-property');\nvar toLength = require('../internals/to-length');\nvar toIndex = require('../internals/to-index');\nvar toOffset = require('../internals/to-offset');\nvar toPrimitive = require('../internals/to-primitive');\nvar has = require('../internals/has');\nvar classof = require('../internals/classof');\nvar isObject = require('../internals/is-object');\nvar create = require('../internals/object-create');\nvar setPrototypeOf = require('../internals/object-set-prototype-of');\nvar getOwnPropertyNames = require('../internals/object-get-own-property-names').f;\nvar typedArrayFrom = require('../internals/typed-array-from');\nvar forEach = require('../internals/array-iteration').forEach;\nvar setSpecies = require('../internals/set-species');\nvar definePropertyModule = require('../internals/object-define-property');\nvar getOwnPropertyDescriptorModule = require('../internals/object-get-own-property-descriptor');\nvar InternalStateModule = require('../internals/internal-state');\nvar inheritIfRequired = require('../internals/inherit-if-required');\n\nvar getInternalState = InternalStateModule.get;\nvar setInternalState = InternalStateModule.set;\nvar nativeDefineProperty = definePropertyModule.f;\nvar nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;\nvar round = Math.round;\nvar RangeError = global.RangeError;\nvar ArrayBuffer = ArrayBufferModule.ArrayBuffer;\nvar DataView = ArrayBufferModule.DataView;\nvar NATIVE_ARRAY_BUFFER_VIEWS = ArrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS;\nvar TYPED_ARRAY_TAG = ArrayBufferViewCore.TYPED_ARRAY_TAG;\nvar TypedArray = ArrayBufferViewCore.TypedArray;\nvar TypedArrayPrototype = ArrayBufferViewCore.TypedArrayPrototype;\nvar aTypedArrayConstructor = ArrayBufferViewCore.aTypedArrayConstructor;\nvar isTypedArray = ArrayBufferViewCore.isTypedArray;\nvar BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';\nvar WRONG_LENGTH = 'Wrong length';\n\nvar fromList = function (C, list) {\n var index = 0;\n var length = list.length;\n var result = new (aTypedArrayConstructor(C))(length);\n while (length > index) result[index] = list[index++];\n return result;\n};\n\nvar addGetter = function (it, key) {\n nativeDefineProperty(it, key, { get: function () {\n return getInternalState(this)[key];\n } });\n};\n\nvar isArrayBuffer = function (it) {\n var klass;\n return it instanceof ArrayBuffer || (klass = classof(it)) == 'ArrayBuffer' || klass == 'SharedArrayBuffer';\n};\n\nvar isTypedArrayIndex = function (target, key) {\n return isTypedArray(target)\n && typeof key != 'symbol'\n && key in target\n && String(+key) == String(key);\n};\n\nvar wrappedGetOwnPropertyDescriptor = function getOwnPropertyDescriptor(target, key) {\n return isTypedArrayIndex(target, key = toPrimitive(key, true))\n ? createPropertyDescriptor(2, target[key])\n : nativeGetOwnPropertyDescriptor(target, key);\n};\n\nvar wrappedDefineProperty = function defineProperty(target, key, descriptor) {\n if (isTypedArrayIndex(target, key = toPrimitive(key, true))\n && isObject(descriptor)\n && has(descriptor, 'value')\n && !has(descriptor, 'get')\n && !has(descriptor, 'set')\n // TODO: add validation descriptor w/o calling accessors\n && !descriptor.configurable\n && (!has(descriptor, 'writable') || descriptor.writable)\n && (!has(descriptor, 'enumerable') || descriptor.enumerable)\n ) {\n target[key] = descriptor.value;\n return target;\n } return nativeDefineProperty(target, key, descriptor);\n};\n\nif (DESCRIPTORS) {\n if (!NATIVE_ARRAY_BUFFER_VIEWS) {\n getOwnPropertyDescriptorModule.f = wrappedGetOwnPropertyDescriptor;\n definePropertyModule.f = wrappedDefineProperty;\n addGetter(TypedArrayPrototype, 'buffer');\n addGetter(TypedArrayPrototype, 'byteOffset');\n addGetter(TypedArrayPrototype, 'byteLength');\n addGetter(TypedArrayPrototype, 'length');\n }\n\n $({ target: 'Object', stat: true, forced: !NATIVE_ARRAY_BUFFER_VIEWS }, {\n getOwnPropertyDescriptor: wrappedGetOwnPropertyDescriptor,\n defineProperty: wrappedDefineProperty\n });\n\n module.exports = function (TYPE, wrapper, CLAMPED) {\n var BYTES = TYPE.match(/\\d+$/)[0] / 8;\n var CONSTRUCTOR_NAME = TYPE + (CLAMPED ? 'Clamped' : '') + 'Array';\n var GETTER = 'get' + TYPE;\n var SETTER = 'set' + TYPE;\n var NativeTypedArrayConstructor = global[CONSTRUCTOR_NAME];\n var TypedArrayConstructor = NativeTypedArrayConstructor;\n var TypedArrayConstructorPrototype = TypedArrayConstructor && TypedArrayConstructor.prototype;\n var exported = {};\n\n var getter = function (that, index) {\n var data = getInternalState(that);\n return data.view[GETTER](index * BYTES + data.byteOffset, true);\n };\n\n var setter = function (that, index, value) {\n var data = getInternalState(that);\n if (CLAMPED) value = (value = round(value)) < 0 ? 0 : value > 0xFF ? 0xFF : value & 0xFF;\n data.view[SETTER](index * BYTES + data.byteOffset, value, true);\n };\n\n var addElement = function (that, index) {\n nativeDefineProperty(that, index, {\n get: function () {\n return getter(this, index);\n },\n set: function (value) {\n return setter(this, index, value);\n },\n enumerable: true\n });\n };\n\n if (!NATIVE_ARRAY_BUFFER_VIEWS) {\n TypedArrayConstructor = wrapper(function (that, data, offset, $length) {\n anInstance(that, TypedArrayConstructor, CONSTRUCTOR_NAME);\n var index = 0;\n var byteOffset = 0;\n var buffer, byteLength, length;\n if (!isObject(data)) {\n length = toIndex(data);\n byteLength = length * BYTES;\n buffer = new ArrayBuffer(byteLength);\n } else if (isArrayBuffer(data)) {\n buffer = data;\n byteOffset = toOffset(offset, BYTES);\n var $len = data.byteLength;\n if ($length === undefined) {\n if ($len % BYTES) throw RangeError(WRONG_LENGTH);\n byteLength = $len - byteOffset;\n if (byteLength < 0) throw RangeError(WRONG_LENGTH);\n } else {\n byteLength = toLength($length) * BYTES;\n if (byteLength + byteOffset > $len) throw RangeError(WRONG_LENGTH);\n }\n length = byteLength / BYTES;\n } else if (isTypedArray(data)) {\n return fromList(TypedArrayConstructor, data);\n } else {\n return typedArrayFrom.call(TypedArrayConstructor, data);\n }\n setInternalState(that, {\n buffer: buffer,\n byteOffset: byteOffset,\n byteLength: byteLength,\n length: length,\n view: new DataView(buffer)\n });\n while (index < length) addElement(that, index++);\n });\n\n if (setPrototypeOf) setPrototypeOf(TypedArrayConstructor, TypedArray);\n TypedArrayConstructorPrototype = TypedArrayConstructor.prototype = create(TypedArrayPrototype);\n } else if (TYPED_ARRAYS_CONSTRUCTORS_REQUIRES_WRAPPERS) {\n TypedArrayConstructor = wrapper(function (dummy, data, typedArrayOffset, $length) {\n anInstance(dummy, TypedArrayConstructor, CONSTRUCTOR_NAME);\n return inheritIfRequired(function () {\n if (!isObject(data)) return new NativeTypedArrayConstructor(toIndex(data));\n if (isArrayBuffer(data)) return $length !== undefined\n ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES), $length)\n : typedArrayOffset !== undefined\n ? new NativeTypedArrayConstructor(data, toOffset(typedArrayOffset, BYTES))\n : new NativeTypedArrayConstructor(data);\n if (isTypedArray(data)) return fromList(TypedArrayConstructor, data);\n return typedArrayFrom.call(TypedArrayConstructor, data);\n }(), dummy, TypedArrayConstructor);\n });\n\n if (setPrototypeOf) setPrototypeOf(TypedArrayConstructor, TypedArray);\n forEach(getOwnPropertyNames(NativeTypedArrayConstructor), function (key) {\n if (!(key in TypedArrayConstructor)) {\n createNonEnumerableProperty(TypedArrayConstructor, key, NativeTypedArrayConstructor[key]);\n }\n });\n TypedArrayConstructor.prototype = TypedArrayConstructorPrototype;\n }\n\n if (TypedArrayConstructorPrototype.constructor !== TypedArrayConstructor) {\n createNonEnumerableProperty(TypedArrayConstructorPrototype, 'constructor', TypedArrayConstructor);\n }\n\n if (TYPED_ARRAY_TAG) {\n createNonEnumerableProperty(TypedArrayConstructorPrototype, TYPED_ARRAY_TAG, CONSTRUCTOR_NAME);\n }\n\n exported[CONSTRUCTOR_NAME] = TypedArrayConstructor;\n\n $({\n global: true, forced: TypedArrayConstructor != NativeTypedArrayConstructor, sham: !NATIVE_ARRAY_BUFFER_VIEWS\n }, exported);\n\n if (!(BYTES_PER_ELEMENT in TypedArrayConstructor)) {\n createNonEnumerableProperty(TypedArrayConstructor, BYTES_PER_ELEMENT, BYTES);\n }\n\n if (!(BYTES_PER_ELEMENT in TypedArrayConstructorPrototype)) {\n createNonEnumerableProperty(TypedArrayConstructorPrototype, BYTES_PER_ELEMENT, BYTES);\n }\n\n setSpecies(CONSTRUCTOR_NAME);\n };\n} else module.exports = function () { /* empty */ };\n","var createTypedArrayConstructor = require('../internals/typed-array-constructor');\n\n// `Uint8Array` constructor\n// https://tc39.github.io/ecma262/#sec-typedarray-objects\ncreateTypedArrayConstructor('Uint8', function (init) {\n return function Uint8Array(data, byteOffset, length) {\n return init(this, data, byteOffset, length);\n };\n});\n","'use strict';\nvar toObject = require('../internals/to-object');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar toLength = require('../internals/to-length');\n\nvar min = Math.min;\n\n// `Array.prototype.copyWithin` method implementation\n// https://tc39.github.io/ecma262/#sec-array.prototype.copywithin\nmodule.exports = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {\n var O = toObject(this);\n var len = toLength(O.length);\n var to = toAbsoluteIndex(target, len);\n var from = toAbsoluteIndex(start, len);\n var end = arguments.length > 2 ? arguments[2] : undefined;\n var count = min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);\n var inc = 1;\n if (from < to && to < from + count) {\n inc = -1;\n from += count - 1;\n to += count - 1;\n }\n while (count-- > 0) {\n if (from in O) O[to] = O[from];\n else delete O[to];\n to += inc;\n from += inc;\n } return O;\n};\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $copyWithin = require('../internals/array-copy-within');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.copyWithin` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.copywithin\nexportTypedArrayMethod('copyWithin', function copyWithin(target, start /* , end */) {\n return $copyWithin.call(aTypedArray(this), target, start, arguments.length > 2 ? arguments[2] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $every = require('../internals/array-iteration').every;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.every` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.every\nexportTypedArrayMethod('every', function every(callbackfn /* , thisArg */) {\n return $every(aTypedArray(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $fill = require('../internals/array-fill');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.fill` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.fill\n// eslint-disable-next-line no-unused-vars\nexportTypedArrayMethod('fill', function fill(value /* , start, end */) {\n return $fill.apply(aTypedArray(this), arguments);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $filter = require('../internals/array-iteration').filter;\nvar speciesConstructor = require('../internals/species-constructor');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar aTypedArrayConstructor = ArrayBufferViewCore.aTypedArrayConstructor;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.filter` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.filter\nexportTypedArrayMethod('filter', function filter(callbackfn /* , thisArg */) {\n var list = $filter(aTypedArray(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n var C = speciesConstructor(this, this.constructor);\n var index = 0;\n var length = list.length;\n var result = new (aTypedArrayConstructor(C))(length);\n while (length > index) result[index] = list[index++];\n return result;\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $find = require('../internals/array-iteration').find;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.find` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.find\nexportTypedArrayMethod('find', function find(predicate /* , thisArg */) {\n return $find(aTypedArray(this), predicate, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $findIndex = require('../internals/array-iteration').findIndex;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.findIndex` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.findindex\nexportTypedArrayMethod('findIndex', function findIndex(predicate /* , thisArg */) {\n return $findIndex(aTypedArray(this), predicate, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $forEach = require('../internals/array-iteration').forEach;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.forEach` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.foreach\nexportTypedArrayMethod('forEach', function forEach(callbackfn /* , thisArg */) {\n $forEach(aTypedArray(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $includes = require('../internals/array-includes').includes;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.includes` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.includes\nexportTypedArrayMethod('includes', function includes(searchElement /* , fromIndex */) {\n return $includes(aTypedArray(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $indexOf = require('../internals/array-includes').indexOf;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.indexOf` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.indexof\nexportTypedArrayMethod('indexOf', function indexOf(searchElement /* , fromIndex */) {\n return $indexOf(aTypedArray(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar global = require('../internals/global');\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar ArrayIterators = require('../modules/es.array.iterator');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar ITERATOR = wellKnownSymbol('iterator');\nvar Uint8Array = global.Uint8Array;\nvar arrayValues = ArrayIterators.values;\nvar arrayKeys = ArrayIterators.keys;\nvar arrayEntries = ArrayIterators.entries;\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\nvar nativeTypedArrayIterator = Uint8Array && Uint8Array.prototype[ITERATOR];\n\nvar CORRECT_ITER_NAME = !!nativeTypedArrayIterator\n && (nativeTypedArrayIterator.name == 'values' || nativeTypedArrayIterator.name == undefined);\n\nvar typedArrayValues = function values() {\n return arrayValues.call(aTypedArray(this));\n};\n\n// `%TypedArray%.prototype.entries` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.entries\nexportTypedArrayMethod('entries', function entries() {\n return arrayEntries.call(aTypedArray(this));\n});\n// `%TypedArray%.prototype.keys` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.keys\nexportTypedArrayMethod('keys', function keys() {\n return arrayKeys.call(aTypedArray(this));\n});\n// `%TypedArray%.prototype.values` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.values\nexportTypedArrayMethod('values', typedArrayValues, !CORRECT_ITER_NAME);\n// `%TypedArray%.prototype[@@iterator]` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype-@@iterator\nexportTypedArrayMethod(ITERATOR, typedArrayValues, !CORRECT_ITER_NAME);\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\nvar $join = [].join;\n\n// `%TypedArray%.prototype.join` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.join\n// eslint-disable-next-line no-unused-vars\nexportTypedArrayMethod('join', function join(separator) {\n return $join.apply(aTypedArray(this), arguments);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $lastIndexOf = require('../internals/array-last-index-of');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.lastIndexOf` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.lastindexof\n// eslint-disable-next-line no-unused-vars\nexportTypedArrayMethod('lastIndexOf', function lastIndexOf(searchElement /* , fromIndex */) {\n return $lastIndexOf.apply(aTypedArray(this), arguments);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $map = require('../internals/array-iteration').map;\nvar speciesConstructor = require('../internals/species-constructor');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar aTypedArrayConstructor = ArrayBufferViewCore.aTypedArrayConstructor;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.map` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.map\nexportTypedArrayMethod('map', function map(mapfn /* , thisArg */) {\n return $map(aTypedArray(this), mapfn, arguments.length > 1 ? arguments[1] : undefined, function (O, length) {\n return new (aTypedArrayConstructor(speciesConstructor(O, O.constructor)))(length);\n });\n});\n","var aFunction = require('../internals/a-function');\nvar toObject = require('../internals/to-object');\nvar IndexedObject = require('../internals/indexed-object');\nvar toLength = require('../internals/to-length');\n\n// `Array.prototype.{ reduce, reduceRight }` methods implementation\nvar createMethod = function (IS_RIGHT) {\n return function (that, callbackfn, argumentsLength, memo) {\n aFunction(callbackfn);\n var O = toObject(that);\n var self = IndexedObject(O);\n var length = toLength(O.length);\n var index = IS_RIGHT ? length - 1 : 0;\n var i = IS_RIGHT ? -1 : 1;\n if (argumentsLength < 2) while (true) {\n if (index in self) {\n memo = self[index];\n index += i;\n break;\n }\n index += i;\n if (IS_RIGHT ? index < 0 : length <= index) {\n throw TypeError('Reduce of empty array with no initial value');\n }\n }\n for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) {\n memo = callbackfn(memo, self[index], index, O);\n }\n return memo;\n };\n};\n\nmodule.exports = {\n // `Array.prototype.reduce` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.reduce\n left: createMethod(false),\n // `Array.prototype.reduceRight` method\n // https://tc39.github.io/ecma262/#sec-array.prototype.reduceright\n right: createMethod(true)\n};\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $reduce = require('../internals/array-reduce').left;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.reduce` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduce\nexportTypedArrayMethod('reduce', function reduce(callbackfn /* , initialValue */) {\n return $reduce(aTypedArray(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $reduceRight = require('../internals/array-reduce').right;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.reduceRicht` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reduceright\nexportTypedArrayMethod('reduceRight', function reduceRight(callbackfn /* , initialValue */) {\n return $reduceRight(aTypedArray(this), callbackfn, arguments.length, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\nvar floor = Math.floor;\n\n// `%TypedArray%.prototype.reverse` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.reverse\nexportTypedArrayMethod('reverse', function reverse() {\n var that = this;\n var length = aTypedArray(that).length;\n var middle = floor(length / 2);\n var index = 0;\n var value;\n while (index < middle) {\n value = that[index];\n that[index++] = that[--length];\n that[length] = value;\n } return that;\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar toLength = require('../internals/to-length');\nvar toOffset = require('../internals/to-offset');\nvar toObject = require('../internals/to-object');\nvar fails = require('../internals/fails');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\nvar FORCED = fails(function () {\n // eslint-disable-next-line no-undef\n new Int8Array(1).set({});\n});\n\n// `%TypedArray%.prototype.set` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.set\nexportTypedArrayMethod('set', function set(arrayLike /* , offset */) {\n aTypedArray(this);\n var offset = toOffset(arguments.length > 1 ? arguments[1] : undefined, 1);\n var length = this.length;\n var src = toObject(arrayLike);\n var len = toLength(src.length);\n var index = 0;\n if (len + offset > length) throw RangeError('Wrong length');\n while (index < len) this[offset + index] = src[index++];\n}, FORCED);\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar speciesConstructor = require('../internals/species-constructor');\nvar fails = require('../internals/fails');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar aTypedArrayConstructor = ArrayBufferViewCore.aTypedArrayConstructor;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\nvar $slice = [].slice;\n\nvar FORCED = fails(function () {\n // eslint-disable-next-line no-undef\n new Int8Array(1).slice();\n});\n\n// `%TypedArray%.prototype.slice` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.slice\nexportTypedArrayMethod('slice', function slice(start, end) {\n var list = $slice.call(aTypedArray(this), start, end);\n var C = speciesConstructor(this, this.constructor);\n var index = 0;\n var length = list.length;\n var result = new (aTypedArrayConstructor(C))(length);\n while (length > index) result[index] = list[index++];\n return result;\n}, FORCED);\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar $some = require('../internals/array-iteration').some;\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.some` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.some\nexportTypedArrayMethod('some', function some(callbackfn /* , thisArg */) {\n return $some(aTypedArray(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\nvar $sort = [].sort;\n\n// `%TypedArray%.prototype.sort` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.sort\nexportTypedArrayMethod('sort', function sort(comparefn) {\n return $sort.call(aTypedArray(this), comparefn);\n});\n","'use strict';\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar toLength = require('../internals/to-length');\nvar toAbsoluteIndex = require('../internals/to-absolute-index');\nvar speciesConstructor = require('../internals/species-constructor');\n\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\n\n// `%TypedArray%.prototype.subarray` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.subarray\nexportTypedArrayMethod('subarray', function subarray(begin, end) {\n var O = aTypedArray(this);\n var length = O.length;\n var beginIndex = toAbsoluteIndex(begin, length);\n return new (speciesConstructor(O, O.constructor))(\n O.buffer,\n O.byteOffset + beginIndex * O.BYTES_PER_ELEMENT,\n toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - beginIndex)\n );\n});\n","'use strict';\nvar global = require('../internals/global');\nvar ArrayBufferViewCore = require('../internals/array-buffer-view-core');\nvar fails = require('../internals/fails');\n\nvar Int8Array = global.Int8Array;\nvar aTypedArray = ArrayBufferViewCore.aTypedArray;\nvar exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod;\nvar $toLocaleString = [].toLocaleString;\nvar $slice = [].slice;\n\n// iOS Safari 6.x fails here\nvar TO_LOCALE_STRING_BUG = !!Int8Array && fails(function () {\n $toLocaleString.call(new Int8Array(1));\n});\n\nvar FORCED = fails(function () {\n return [1, 2].toLocaleString() != new Int8Array([1, 2]).toLocaleString();\n}) || !fails(function () {\n Int8Array.prototype.toLocaleString.call([1, 2]);\n});\n\n// `%TypedArray%.prototype.toLocaleString` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tolocalestring\nexportTypedArrayMethod('toLocaleString', function toLocaleString() {\n return $toLocaleString.apply(TO_LOCALE_STRING_BUG ? $slice.call(aTypedArray(this)) : aTypedArray(this), arguments);\n}, FORCED);\n","'use strict';\nvar exportTypedArrayMethod = require('../internals/array-buffer-view-core').exportTypedArrayMethod;\nvar fails = require('../internals/fails');\nvar global = require('../internals/global');\n\nvar Uint8Array = global.Uint8Array;\nvar Uint8ArrayPrototype = Uint8Array && Uint8Array.prototype || {};\nvar arrayToString = [].toString;\nvar arrayJoin = [].join;\n\nif (fails(function () { arrayToString.call({}); })) {\n arrayToString = function toString() {\n return arrayJoin.call(this);\n };\n}\n\nvar IS_NOT_ARRAY_METHOD = Uint8ArrayPrototype.toString != arrayToString;\n\n// `%TypedArray%.prototype.toString` method\n// https://tc39.github.io/ecma262/#sec-%typedarray%.prototype.tostring\nexportTypedArrayMethod('toString', arrayToString, IS_NOT_ARRAY_METHOD);\n","var fails = require('../internals/fails');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\nvar IS_PURE = require('../internals/is-pure');\n\nvar ITERATOR = wellKnownSymbol('iterator');\n\nmodule.exports = !fails(function () {\n var url = new URL('b?a=1&b=2&c=3', 'http://a');\n var searchParams = url.searchParams;\n var result = '';\n url.pathname = 'c%20d';\n searchParams.forEach(function (value, key) {\n searchParams['delete']('b');\n result += key + value;\n });\n return (IS_PURE && !url.toJSON)\n || !searchParams.sort\n || url.href !== 'http://a/c%20d?a=1&c=3'\n || searchParams.get('c') !== '3'\n || String(new URLSearchParams('?a=1')) !== 'a=1'\n || !searchParams[ITERATOR]\n // throws in Edge\n || new URL('https://a@b').username !== 'a'\n || new URLSearchParams(new URLSearchParams('a=b')).get('a') !== 'b'\n // not punycoded in Edge\n || new URL('http://тест').host !== 'xn--e1aybc'\n // not escaped in Chrome 62-\n || new URL('http://a#б').hash !== '#%D0%B1'\n // fails in Chrome 66-\n || result !== 'a1c3'\n // throws in Safari\n || new URL('http://x', undefined).host !== 'x';\n});\n","'use strict';\nvar bind = require('../internals/function-bind-context');\nvar toObject = require('../internals/to-object');\nvar callWithSafeIterationClosing = require('../internals/call-with-safe-iteration-closing');\nvar isArrayIteratorMethod = require('../internals/is-array-iterator-method');\nvar toLength = require('../internals/to-length');\nvar createProperty = require('../internals/create-property');\nvar getIteratorMethod = require('../internals/get-iterator-method');\n\n// `Array.from` method implementation\n// https://tc39.github.io/ecma262/#sec-array.from\nmodule.exports = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {\n var O = toObject(arrayLike);\n var C = typeof this == 'function' ? this : Array;\n var argumentsLength = arguments.length;\n var mapfn = argumentsLength > 1 ? arguments[1] : undefined;\n var mapping = mapfn !== undefined;\n var iteratorMethod = getIteratorMethod(O);\n var index = 0;\n var length, result, step, iterator, next, value;\n if (mapping) mapfn = bind(mapfn, argumentsLength > 2 ? arguments[2] : undefined, 2);\n // if the target is not iterable or it's an array with the default iterator - use a simple case\n if (iteratorMethod != undefined && !(C == Array && isArrayIteratorMethod(iteratorMethod))) {\n iterator = iteratorMethod.call(O);\n next = iterator.next;\n result = new C();\n for (;!(step = next.call(iterator)).done; index++) {\n value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value;\n createProperty(result, index, value);\n }\n } else {\n length = toLength(O.length);\n result = new C(length);\n for (;length > index; index++) {\n value = mapping ? mapfn(O[index], index) : O[index];\n createProperty(result, index, value);\n }\n }\n result.length = index;\n return result;\n};\n","'use strict';\n// based on https://github.com/bestiejs/punycode.js/blob/master/punycode.js\nvar maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1\nvar base = 36;\nvar tMin = 1;\nvar tMax = 26;\nvar skew = 38;\nvar damp = 700;\nvar initialBias = 72;\nvar initialN = 128; // 0x80\nvar delimiter = '-'; // '\\x2D'\nvar regexNonASCII = /[^\\0-\\u007E]/; // non-ASCII chars\nvar regexSeparators = /[.\\u3002\\uFF0E\\uFF61]/g; // RFC 3490 separators\nvar OVERFLOW_ERROR = 'Overflow: input needs wider integers to process';\nvar baseMinusTMin = base - tMin;\nvar floor = Math.floor;\nvar stringFromCharCode = String.fromCharCode;\n\n/**\n * Creates an array containing the numeric code points of each Unicode\n * character in the string. While JavaScript uses UCS-2 internally,\n * this function will convert a pair of surrogate halves (each of which\n * UCS-2 exposes as separate characters) into a single code point,\n * matching UTF-16.\n */\nvar ucs2decode = function (string) {\n var output = [];\n var counter = 0;\n var length = string.length;\n while (counter < length) {\n var value = string.charCodeAt(counter++);\n if (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n // It's a high surrogate, and there is a next character.\n var extra = string.charCodeAt(counter++);\n if ((extra & 0xFC00) == 0xDC00) { // Low surrogate.\n output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n } else {\n // It's an unmatched surrogate; only append this code unit, in case the\n // next code unit is the high surrogate of a surrogate pair.\n output.push(value);\n counter--;\n }\n } else {\n output.push(value);\n }\n }\n return output;\n};\n\n/**\n * Converts a digit/integer into a basic code point.\n */\nvar digitToBasic = function (digit) {\n // 0..25 map to ASCII a..z or A..Z\n // 26..35 map to ASCII 0..9\n return digit + 22 + 75 * (digit < 26);\n};\n\n/**\n * Bias adaptation function as per section 3.4 of RFC 3492.\n * https://tools.ietf.org/html/rfc3492#section-3.4\n */\nvar adapt = function (delta, numPoints, firstTime) {\n var k = 0;\n delta = firstTime ? floor(delta / damp) : delta >> 1;\n delta += floor(delta / numPoints);\n for (; delta > baseMinusTMin * tMax >> 1; k += base) {\n delta = floor(delta / baseMinusTMin);\n }\n return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n};\n\n/**\n * Converts a string of Unicode symbols (e.g. a domain name label) to a\n * Punycode string of ASCII-only symbols.\n */\n// eslint-disable-next-line max-statements\nvar encode = function (input) {\n var output = [];\n\n // Convert the input in UCS-2 to an array of Unicode code points.\n input = ucs2decode(input);\n\n // Cache the length.\n var inputLength = input.length;\n\n // Initialize the state.\n var n = initialN;\n var delta = 0;\n var bias = initialBias;\n var i, currentValue;\n\n // Handle the basic code points.\n for (i = 0; i < input.length; i++) {\n currentValue = input[i];\n if (currentValue < 0x80) {\n output.push(stringFromCharCode(currentValue));\n }\n }\n\n var basicLength = output.length; // number of basic code points.\n var handledCPCount = basicLength; // number of code points that have been handled;\n\n // Finish the basic string with a delimiter unless it's empty.\n if (basicLength) {\n output.push(delimiter);\n }\n\n // Main encoding loop:\n while (handledCPCount < inputLength) {\n // All non-basic code points < n have been handled already. Find the next larger one:\n var m = maxInt;\n for (i = 0; i < input.length; i++) {\n currentValue = input[i];\n if (currentValue >= n && currentValue < m) {\n m = currentValue;\n }\n }\n\n // Increase `delta` enough to advance the decoder's state to , but guard against overflow.\n var handledCPCountPlusOne = handledCPCount + 1;\n if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n throw RangeError(OVERFLOW_ERROR);\n }\n\n delta += (m - n) * handledCPCountPlusOne;\n n = m;\n\n for (i = 0; i < input.length; i++) {\n currentValue = input[i];\n if (currentValue < n && ++delta > maxInt) {\n throw RangeError(OVERFLOW_ERROR);\n }\n if (currentValue == n) {\n // Represent delta as a generalized variable-length integer.\n var q = delta;\n for (var k = base; /* no condition */; k += base) {\n var t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n if (q < t) break;\n var qMinusT = q - t;\n var baseMinusT = base - t;\n output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT)));\n q = floor(qMinusT / baseMinusT);\n }\n\n output.push(stringFromCharCode(digitToBasic(q)));\n bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n delta = 0;\n ++handledCPCount;\n }\n }\n\n ++delta;\n ++n;\n }\n return output.join('');\n};\n\nmodule.exports = function (input) {\n var encoded = [];\n var labels = input.toLowerCase().replace(regexSeparators, '\\u002E').split('.');\n var i, label;\n for (i = 0; i < labels.length; i++) {\n label = labels[i];\n encoded.push(regexNonASCII.test(label) ? 'xn--' + encode(label) : label);\n }\n return encoded.join('.');\n};\n","var anObject = require('../internals/an-object');\nvar getIteratorMethod = require('../internals/get-iterator-method');\n\nmodule.exports = function (it) {\n var iteratorMethod = getIteratorMethod(it);\n if (typeof iteratorMethod != 'function') {\n throw TypeError(String(it) + ' is not iterable');\n } return anObject(iteratorMethod.call(it));\n};\n","'use strict';\n// TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env`\nrequire('../modules/es.array.iterator');\nvar $ = require('../internals/export');\nvar getBuiltIn = require('../internals/get-built-in');\nvar USE_NATIVE_URL = require('../internals/native-url');\nvar redefine = require('../internals/redefine');\nvar redefineAll = require('../internals/redefine-all');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar createIteratorConstructor = require('../internals/create-iterator-constructor');\nvar InternalStateModule = require('../internals/internal-state');\nvar anInstance = require('../internals/an-instance');\nvar hasOwn = require('../internals/has');\nvar bind = require('../internals/function-bind-context');\nvar classof = require('../internals/classof');\nvar anObject = require('../internals/an-object');\nvar isObject = require('../internals/is-object');\nvar create = require('../internals/object-create');\nvar createPropertyDescriptor = require('../internals/create-property-descriptor');\nvar getIterator = require('../internals/get-iterator');\nvar getIteratorMethod = require('../internals/get-iterator-method');\nvar wellKnownSymbol = require('../internals/well-known-symbol');\n\nvar $fetch = getBuiltIn('fetch');\nvar Headers = getBuiltIn('Headers');\nvar ITERATOR = wellKnownSymbol('iterator');\nvar URL_SEARCH_PARAMS = 'URLSearchParams';\nvar URL_SEARCH_PARAMS_ITERATOR = URL_SEARCH_PARAMS + 'Iterator';\nvar setInternalState = InternalStateModule.set;\nvar getInternalParamsState = InternalStateModule.getterFor(URL_SEARCH_PARAMS);\nvar getInternalIteratorState = InternalStateModule.getterFor(URL_SEARCH_PARAMS_ITERATOR);\n\nvar plus = /\\+/g;\nvar sequences = Array(4);\n\nvar percentSequence = function (bytes) {\n return sequences[bytes - 1] || (sequences[bytes - 1] = RegExp('((?:%[\\\\da-f]{2}){' + bytes + '})', 'gi'));\n};\n\nvar percentDecode = function (sequence) {\n try {\n return decodeURIComponent(sequence);\n } catch (error) {\n return sequence;\n }\n};\n\nvar deserialize = function (it) {\n var result = it.replace(plus, ' ');\n var bytes = 4;\n try {\n return decodeURIComponent(result);\n } catch (error) {\n while (bytes) {\n result = result.replace(percentSequence(bytes--), percentDecode);\n }\n return result;\n }\n};\n\nvar find = /[!'()~]|%20/g;\n\nvar replace = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+'\n};\n\nvar replacer = function (match) {\n return replace[match];\n};\n\nvar serialize = function (it) {\n return encodeURIComponent(it).replace(find, replacer);\n};\n\nvar parseSearchParams = function (result, query) {\n if (query) {\n var attributes = query.split('&');\n var index = 0;\n var attribute, entry;\n while (index < attributes.length) {\n attribute = attributes[index++];\n if (attribute.length) {\n entry = attribute.split('=');\n result.push({\n key: deserialize(entry.shift()),\n value: deserialize(entry.join('='))\n });\n }\n }\n }\n};\n\nvar updateSearchParams = function (query) {\n this.entries.length = 0;\n parseSearchParams(this.entries, query);\n};\n\nvar validateArgumentsLength = function (passed, required) {\n if (passed < required) throw TypeError('Not enough arguments');\n};\n\nvar URLSearchParamsIterator = createIteratorConstructor(function Iterator(params, kind) {\n setInternalState(this, {\n type: URL_SEARCH_PARAMS_ITERATOR,\n iterator: getIterator(getInternalParamsState(params).entries),\n kind: kind\n });\n}, 'Iterator', function next() {\n var state = getInternalIteratorState(this);\n var kind = state.kind;\n var step = state.iterator.next();\n var entry = step.value;\n if (!step.done) {\n step.value = kind === 'keys' ? entry.key : kind === 'values' ? entry.value : [entry.key, entry.value];\n } return step;\n});\n\n// `URLSearchParams` constructor\n// https://url.spec.whatwg.org/#interface-urlsearchparams\nvar URLSearchParamsConstructor = function URLSearchParams(/* init */) {\n anInstance(this, URLSearchParamsConstructor, URL_SEARCH_PARAMS);\n var init = arguments.length > 0 ? arguments[0] : undefined;\n var that = this;\n var entries = [];\n var iteratorMethod, iterator, next, step, entryIterator, entryNext, first, second, key;\n\n setInternalState(that, {\n type: URL_SEARCH_PARAMS,\n entries: entries,\n updateURL: function () { /* empty */ },\n updateSearchParams: updateSearchParams\n });\n\n if (init !== undefined) {\n if (isObject(init)) {\n iteratorMethod = getIteratorMethod(init);\n if (typeof iteratorMethod === 'function') {\n iterator = iteratorMethod.call(init);\n next = iterator.next;\n while (!(step = next.call(iterator)).done) {\n entryIterator = getIterator(anObject(step.value));\n entryNext = entryIterator.next;\n if (\n (first = entryNext.call(entryIterator)).done ||\n (second = entryNext.call(entryIterator)).done ||\n !entryNext.call(entryIterator).done\n ) throw TypeError('Expected sequence with length 2');\n entries.push({ key: first.value + '', value: second.value + '' });\n }\n } else for (key in init) if (hasOwn(init, key)) entries.push({ key: key, value: init[key] + '' });\n } else {\n parseSearchParams(entries, typeof init === 'string' ? init.charAt(0) === '?' ? init.slice(1) : init : init + '');\n }\n }\n};\n\nvar URLSearchParamsPrototype = URLSearchParamsConstructor.prototype;\n\nredefineAll(URLSearchParamsPrototype, {\n // `URLSearchParams.prototype.appent` method\n // https://url.spec.whatwg.org/#dom-urlsearchparams-append\n append: function append(name, value) {\n validateArgumentsLength(arguments.length, 2);\n var state = getInternalParamsState(this);\n state.entries.push({ key: name + '', value: value + '' });\n state.updateURL();\n },\n // `URLSearchParams.prototype.delete` method\n // https://url.spec.whatwg.org/#dom-urlsearchparams-delete\n 'delete': function (name) {\n validateArgumentsLength(arguments.length, 1);\n var state = getInternalParamsState(this);\n var entries = state.entries;\n var key = name + '';\n var index = 0;\n while (index < entries.length) {\n if (entries[index].key === key) entries.splice(index, 1);\n else index++;\n }\n state.updateURL();\n },\n // `URLSearchParams.prototype.get` method\n // https://url.spec.whatwg.org/#dom-urlsearchparams-get\n get: function get(name) {\n validateArgumentsLength(arguments.length, 1);\n var entries = getInternalParamsState(this).entries;\n var key = name + '';\n var index = 0;\n for (; index < entries.length; index++) {\n if (entries[index].key === key) return entries[index].value;\n }\n return null;\n },\n // `URLSearchParams.prototype.getAll` method\n // https://url.spec.whatwg.org/#dom-urlsearchparams-getall\n getAll: function getAll(name) {\n validateArgumentsLength(arguments.length, 1);\n var entries = getInternalParamsState(this).entries;\n var key = name + '';\n var result = [];\n var index = 0;\n for (; index < entries.length; index++) {\n if (entries[index].key === key) result.push(entries[index].value);\n }\n return result;\n },\n // `URLSearchParams.prototype.has` method\n // https://url.spec.whatwg.org/#dom-urlsearchparams-has\n has: function has(name) {\n validateArgumentsLength(arguments.length, 1);\n var entries = getInternalParamsState(this).entries;\n var key = name + '';\n var index = 0;\n while (index < entries.length) {\n if (entries[index++].key === key) return true;\n }\n return false;\n },\n // `URLSearchParams.prototype.set` method\n // https://url.spec.whatwg.org/#dom-urlsearchparams-set\n set: function set(name, value) {\n validateArgumentsLength(arguments.length, 1);\n var state = getInternalParamsState(this);\n var entries = state.entries;\n var found = false;\n var key = name + '';\n var val = value + '';\n var index = 0;\n var entry;\n for (; index < entries.length; index++) {\n entry = entries[index];\n if (entry.key === key) {\n if (found) entries.splice(index--, 1);\n else {\n found = true;\n entry.value = val;\n }\n }\n }\n if (!found) entries.push({ key: key, value: val });\n state.updateURL();\n },\n // `URLSearchParams.prototype.sort` method\n // https://url.spec.whatwg.org/#dom-urlsearchparams-sort\n sort: function sort() {\n var state = getInternalParamsState(this);\n var entries = state.entries;\n // Array#sort is not stable in some engines\n var slice = entries.slice();\n var entry, entriesIndex, sliceIndex;\n entries.length = 0;\n for (sliceIndex = 0; sliceIndex < slice.length; sliceIndex++) {\n entry = slice[sliceIndex];\n for (entriesIndex = 0; entriesIndex < sliceIndex; entriesIndex++) {\n if (entries[entriesIndex].key > entry.key) {\n entries.splice(entriesIndex, 0, entry);\n break;\n }\n }\n if (entriesIndex === sliceIndex) entries.push(entry);\n }\n state.updateURL();\n },\n // `URLSearchParams.prototype.forEach` method\n forEach: function forEach(callback /* , thisArg */) {\n var entries = getInternalParamsState(this).entries;\n var boundFunction = bind(callback, arguments.length > 1 ? arguments[1] : undefined, 3);\n var index = 0;\n var entry;\n while (index < entries.length) {\n entry = entries[index++];\n boundFunction(entry.value, entry.key, this);\n }\n },\n // `URLSearchParams.prototype.keys` method\n keys: function keys() {\n return new URLSearchParamsIterator(this, 'keys');\n },\n // `URLSearchParams.prototype.values` method\n values: function values() {\n return new URLSearchParamsIterator(this, 'values');\n },\n // `URLSearchParams.prototype.entries` method\n entries: function entries() {\n return new URLSearchParamsIterator(this, 'entries');\n }\n}, { enumerable: true });\n\n// `URLSearchParams.prototype[@@iterator]` method\nredefine(URLSearchParamsPrototype, ITERATOR, URLSearchParamsPrototype.entries);\n\n// `URLSearchParams.prototype.toString` method\n// https://url.spec.whatwg.org/#urlsearchparams-stringification-behavior\nredefine(URLSearchParamsPrototype, 'toString', function toString() {\n var entries = getInternalParamsState(this).entries;\n var result = [];\n var index = 0;\n var entry;\n while (index < entries.length) {\n entry = entries[index++];\n result.push(serialize(entry.key) + '=' + serialize(entry.value));\n } return result.join('&');\n}, { enumerable: true });\n\nsetToStringTag(URLSearchParamsConstructor, URL_SEARCH_PARAMS);\n\n$({ global: true, forced: !USE_NATIVE_URL }, {\n URLSearchParams: URLSearchParamsConstructor\n});\n\n// Wrap `fetch` for correct work with polyfilled `URLSearchParams`\n// https://github.com/zloirock/core-js/issues/674\nif (!USE_NATIVE_URL && typeof $fetch == 'function' && typeof Headers == 'function') {\n $({ global: true, enumerable: true, forced: true }, {\n fetch: function fetch(input /* , init */) {\n var args = [input];\n var init, body, headers;\n if (arguments.length > 1) {\n init = arguments[1];\n if (isObject(init)) {\n body = init.body;\n if (classof(body) === URL_SEARCH_PARAMS) {\n headers = init.headers ? new Headers(init.headers) : new Headers();\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');\n }\n init = create(init, {\n body: createPropertyDescriptor(0, String(body)),\n headers: createPropertyDescriptor(0, headers)\n });\n }\n }\n args.push(init);\n } return $fetch.apply(this, args);\n }\n });\n}\n\nmodule.exports = {\n URLSearchParams: URLSearchParamsConstructor,\n getState: getInternalParamsState\n};\n","'use strict';\n// TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env`\nrequire('../modules/es.string.iterator');\nvar $ = require('../internals/export');\nvar DESCRIPTORS = require('../internals/descriptors');\nvar USE_NATIVE_URL = require('../internals/native-url');\nvar global = require('../internals/global');\nvar defineProperties = require('../internals/object-define-properties');\nvar redefine = require('../internals/redefine');\nvar anInstance = require('../internals/an-instance');\nvar has = require('../internals/has');\nvar assign = require('../internals/object-assign');\nvar arrayFrom = require('../internals/array-from');\nvar codeAt = require('../internals/string-multibyte').codeAt;\nvar toASCII = require('../internals/string-punycode-to-ascii');\nvar setToStringTag = require('../internals/set-to-string-tag');\nvar URLSearchParamsModule = require('../modules/web.url-search-params');\nvar InternalStateModule = require('../internals/internal-state');\n\nvar NativeURL = global.URL;\nvar URLSearchParams = URLSearchParamsModule.URLSearchParams;\nvar getInternalSearchParamsState = URLSearchParamsModule.getState;\nvar setInternalState = InternalStateModule.set;\nvar getInternalURLState = InternalStateModule.getterFor('URL');\nvar floor = Math.floor;\nvar pow = Math.pow;\n\nvar INVALID_AUTHORITY = 'Invalid authority';\nvar INVALID_SCHEME = 'Invalid scheme';\nvar INVALID_HOST = 'Invalid host';\nvar INVALID_PORT = 'Invalid port';\n\nvar ALPHA = /[A-Za-z]/;\nvar ALPHANUMERIC = /[\\d+-.A-Za-z]/;\nvar DIGIT = /\\d/;\nvar HEX_START = /^(0x|0X)/;\nvar OCT = /^[0-7]+$/;\nvar DEC = /^\\d+$/;\nvar HEX = /^[\\dA-Fa-f]+$/;\n// eslint-disable-next-line no-control-regex\nvar FORBIDDEN_HOST_CODE_POINT = /[\\u0000\\u0009\\u000A\\u000D #%/:?@[\\\\]]/;\n// eslint-disable-next-line no-control-regex\nvar FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT = /[\\u0000\\u0009\\u000A\\u000D #/:?@[\\\\]]/;\n// eslint-disable-next-line no-control-regex\nvar LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE = /^[\\u0000-\\u001F ]+|[\\u0000-\\u001F ]+$/g;\n// eslint-disable-next-line no-control-regex\nvar TAB_AND_NEW_LINE = /[\\u0009\\u000A\\u000D]/g;\nvar EOF;\n\nvar parseHost = function (url, input) {\n var result, codePoints, index;\n if (input.charAt(0) == '[') {\n if (input.charAt(input.length - 1) != ']') return INVALID_HOST;\n result = parseIPv6(input.slice(1, -1));\n if (!result) return INVALID_HOST;\n url.host = result;\n // opaque host\n } else if (!isSpecial(url)) {\n if (FORBIDDEN_HOST_CODE_POINT_EXCLUDING_PERCENT.test(input)) return INVALID_HOST;\n result = '';\n codePoints = arrayFrom(input);\n for (index = 0; index < codePoints.length; index++) {\n result += percentEncode(codePoints[index], C0ControlPercentEncodeSet);\n }\n url.host = result;\n } else {\n input = toASCII(input);\n if (FORBIDDEN_HOST_CODE_POINT.test(input)) return INVALID_HOST;\n result = parseIPv4(input);\n if (result === null) return INVALID_HOST;\n url.host = result;\n }\n};\n\nvar parseIPv4 = function (input) {\n var parts = input.split('.');\n var partsLength, numbers, index, part, radix, number, ipv4;\n if (parts.length && parts[parts.length - 1] == '') {\n parts.pop();\n }\n partsLength = parts.length;\n if (partsLength > 4) return input;\n numbers = [];\n for (index = 0; index < partsLength; index++) {\n part = parts[index];\n if (part == '') return input;\n radix = 10;\n if (part.length > 1 && part.charAt(0) == '0') {\n radix = HEX_START.test(part) ? 16 : 8;\n part = part.slice(radix == 8 ? 1 : 2);\n }\n if (part === '') {\n number = 0;\n } else {\n if (!(radix == 10 ? DEC : radix == 8 ? OCT : HEX).test(part)) return input;\n number = parseInt(part, radix);\n }\n numbers.push(number);\n }\n for (index = 0; index < partsLength; index++) {\n number = numbers[index];\n if (index == partsLength - 1) {\n if (number >= pow(256, 5 - partsLength)) return null;\n } else if (number > 255) return null;\n }\n ipv4 = numbers.pop();\n for (index = 0; index < numbers.length; index++) {\n ipv4 += numbers[index] * pow(256, 3 - index);\n }\n return ipv4;\n};\n\n// eslint-disable-next-line max-statements\nvar parseIPv6 = function (input) {\n var address = [0, 0, 0, 0, 0, 0, 0, 0];\n var pieceIndex = 0;\n var compress = null;\n var pointer = 0;\n var value, length, numbersSeen, ipv4Piece, number, swaps, swap;\n\n var char = function () {\n return input.charAt(pointer);\n };\n\n if (char() == ':') {\n if (input.charAt(1) != ':') return;\n pointer += 2;\n pieceIndex++;\n compress = pieceIndex;\n }\n while (char()) {\n if (pieceIndex == 8) return;\n if (char() == ':') {\n if (compress !== null) return;\n pointer++;\n pieceIndex++;\n compress = pieceIndex;\n continue;\n }\n value = length = 0;\n while (length < 4 && HEX.test(char())) {\n value = value * 16 + parseInt(char(), 16);\n pointer++;\n length++;\n }\n if (char() == '.') {\n if (length == 0) return;\n pointer -= length;\n if (pieceIndex > 6) return;\n numbersSeen = 0;\n while (char()) {\n ipv4Piece = null;\n if (numbersSeen > 0) {\n if (char() == '.' && numbersSeen < 4) pointer++;\n else return;\n }\n if (!DIGIT.test(char())) return;\n while (DIGIT.test(char())) {\n number = parseInt(char(), 10);\n if (ipv4Piece === null) ipv4Piece = number;\n else if (ipv4Piece == 0) return;\n else ipv4Piece = ipv4Piece * 10 + number;\n if (ipv4Piece > 255) return;\n pointer++;\n }\n address[pieceIndex] = address[pieceIndex] * 256 + ipv4Piece;\n numbersSeen++;\n if (numbersSeen == 2 || numbersSeen == 4) pieceIndex++;\n }\n if (numbersSeen != 4) return;\n break;\n } else if (char() == ':') {\n pointer++;\n if (!char()) return;\n } else if (char()) return;\n address[pieceIndex++] = value;\n }\n if (compress !== null) {\n swaps = pieceIndex - compress;\n pieceIndex = 7;\n while (pieceIndex != 0 && swaps > 0) {\n swap = address[pieceIndex];\n address[pieceIndex--] = address[compress + swaps - 1];\n address[compress + --swaps] = swap;\n }\n } else if (pieceIndex != 8) return;\n return address;\n};\n\nvar findLongestZeroSequence = function (ipv6) {\n var maxIndex = null;\n var maxLength = 1;\n var currStart = null;\n var currLength = 0;\n var index = 0;\n for (; index < 8; index++) {\n if (ipv6[index] !== 0) {\n if (currLength > maxLength) {\n maxIndex = currStart;\n maxLength = currLength;\n }\n currStart = null;\n currLength = 0;\n } else {\n if (currStart === null) currStart = index;\n ++currLength;\n }\n }\n if (currLength > maxLength) {\n maxIndex = currStart;\n maxLength = currLength;\n }\n return maxIndex;\n};\n\nvar serializeHost = function (host) {\n var result, index, compress, ignore0;\n // ipv4\n if (typeof host == 'number') {\n result = [];\n for (index = 0; index < 4; index++) {\n result.unshift(host % 256);\n host = floor(host / 256);\n } return result.join('.');\n // ipv6\n } else if (typeof host == 'object') {\n result = '';\n compress = findLongestZeroSequence(host);\n for (index = 0; index < 8; index++) {\n if (ignore0 && host[index] === 0) continue;\n if (ignore0) ignore0 = false;\n if (compress === index) {\n result += index ? ':' : '::';\n ignore0 = true;\n } else {\n result += host[index].toString(16);\n if (index < 7) result += ':';\n }\n }\n return '[' + result + ']';\n } return host;\n};\n\nvar C0ControlPercentEncodeSet = {};\nvar fragmentPercentEncodeSet = assign({}, C0ControlPercentEncodeSet, {\n ' ': 1, '\"': 1, '<': 1, '>': 1, '`': 1\n});\nvar pathPercentEncodeSet = assign({}, fragmentPercentEncodeSet, {\n '#': 1, '?': 1, '{': 1, '}': 1\n});\nvar userinfoPercentEncodeSet = assign({}, pathPercentEncodeSet, {\n '/': 1, ':': 1, ';': 1, '=': 1, '@': 1, '[': 1, '\\\\': 1, ']': 1, '^': 1, '|': 1\n});\n\nvar percentEncode = function (char, set) {\n var code = codeAt(char, 0);\n return code > 0x20 && code < 0x7F && !has(set, char) ? char : encodeURIComponent(char);\n};\n\nvar specialSchemes = {\n ftp: 21,\n file: null,\n http: 80,\n https: 443,\n ws: 80,\n wss: 443\n};\n\nvar isSpecial = function (url) {\n return has(specialSchemes, url.scheme);\n};\n\nvar includesCredentials = function (url) {\n return url.username != '' || url.password != '';\n};\n\nvar cannotHaveUsernamePasswordPort = function (url) {\n return !url.host || url.cannotBeABaseURL || url.scheme == 'file';\n};\n\nvar isWindowsDriveLetter = function (string, normalized) {\n var second;\n return string.length == 2 && ALPHA.test(string.charAt(0))\n && ((second = string.charAt(1)) == ':' || (!normalized && second == '|'));\n};\n\nvar startsWithWindowsDriveLetter = function (string) {\n var third;\n return string.length > 1 && isWindowsDriveLetter(string.slice(0, 2)) && (\n string.length == 2 ||\n ((third = string.charAt(2)) === '/' || third === '\\\\' || third === '?' || third === '#')\n );\n};\n\nvar shortenURLsPath = function (url) {\n var path = url.path;\n var pathSize = path.length;\n if (pathSize && (url.scheme != 'file' || pathSize != 1 || !isWindowsDriveLetter(path[0], true))) {\n path.pop();\n }\n};\n\nvar isSingleDot = function (segment) {\n return segment === '.' || segment.toLowerCase() === '%2e';\n};\n\nvar isDoubleDot = function (segment) {\n segment = segment.toLowerCase();\n return segment === '..' || segment === '%2e.' || segment === '.%2e' || segment === '%2e%2e';\n};\n\n// States:\nvar SCHEME_START = {};\nvar SCHEME = {};\nvar NO_SCHEME = {};\nvar SPECIAL_RELATIVE_OR_AUTHORITY = {};\nvar PATH_OR_AUTHORITY = {};\nvar RELATIVE = {};\nvar RELATIVE_SLASH = {};\nvar SPECIAL_AUTHORITY_SLASHES = {};\nvar SPECIAL_AUTHORITY_IGNORE_SLASHES = {};\nvar AUTHORITY = {};\nvar HOST = {};\nvar HOSTNAME = {};\nvar PORT = {};\nvar FILE = {};\nvar FILE_SLASH = {};\nvar FILE_HOST = {};\nvar PATH_START = {};\nvar PATH = {};\nvar CANNOT_BE_A_BASE_URL_PATH = {};\nvar QUERY = {};\nvar FRAGMENT = {};\n\n// eslint-disable-next-line max-statements\nvar parseURL = function (url, input, stateOverride, base) {\n var state = stateOverride || SCHEME_START;\n var pointer = 0;\n var buffer = '';\n var seenAt = false;\n var seenBracket = false;\n var seenPasswordToken = false;\n var codePoints, char, bufferCodePoints, failure;\n\n if (!stateOverride) {\n url.scheme = '';\n url.username = '';\n url.password = '';\n url.host = null;\n url.port = null;\n url.path = [];\n url.query = null;\n url.fragment = null;\n url.cannotBeABaseURL = false;\n input = input.replace(LEADING_AND_TRAILING_C0_CONTROL_OR_SPACE, '');\n }\n\n input = input.replace(TAB_AND_NEW_LINE, '');\n\n codePoints = arrayFrom(input);\n\n while (pointer <= codePoints.length) {\n char = codePoints[pointer];\n switch (state) {\n case SCHEME_START:\n if (char && ALPHA.test(char)) {\n buffer += char.toLowerCase();\n state = SCHEME;\n } else if (!stateOverride) {\n state = NO_SCHEME;\n continue;\n } else return INVALID_SCHEME;\n break;\n\n case SCHEME:\n if (char && (ALPHANUMERIC.test(char) || char == '+' || char == '-' || char == '.')) {\n buffer += char.toLowerCase();\n } else if (char == ':') {\n if (stateOverride && (\n (isSpecial(url) != has(specialSchemes, buffer)) ||\n (buffer == 'file' && (includesCredentials(url) || url.port !== null)) ||\n (url.scheme == 'file' && !url.host)\n )) return;\n url.scheme = buffer;\n if (stateOverride) {\n if (isSpecial(url) && specialSchemes[url.scheme] == url.port) url.port = null;\n return;\n }\n buffer = '';\n if (url.scheme == 'file') {\n state = FILE;\n } else if (isSpecial(url) && base && base.scheme == url.scheme) {\n state = SPECIAL_RELATIVE_OR_AUTHORITY;\n } else if (isSpecial(url)) {\n state = SPECIAL_AUTHORITY_SLASHES;\n } else if (codePoints[pointer + 1] == '/') {\n state = PATH_OR_AUTHORITY;\n pointer++;\n } else {\n url.cannotBeABaseURL = true;\n url.path.push('');\n state = CANNOT_BE_A_BASE_URL_PATH;\n }\n } else if (!stateOverride) {\n buffer = '';\n state = NO_SCHEME;\n pointer = 0;\n continue;\n } else return INVALID_SCHEME;\n break;\n\n case NO_SCHEME:\n if (!base || (base.cannotBeABaseURL && char != '#')) return INVALID_SCHEME;\n if (base.cannotBeABaseURL && char == '#') {\n url.scheme = base.scheme;\n url.path = base.path.slice();\n url.query = base.query;\n url.fragment = '';\n url.cannotBeABaseURL = true;\n state = FRAGMENT;\n break;\n }\n state = base.scheme == 'file' ? FILE : RELATIVE;\n continue;\n\n case SPECIAL_RELATIVE_OR_AUTHORITY:\n if (char == '/' && codePoints[pointer + 1] == '/') {\n state = SPECIAL_AUTHORITY_IGNORE_SLASHES;\n pointer++;\n } else {\n state = RELATIVE;\n continue;\n } break;\n\n case PATH_OR_AUTHORITY:\n if (char == '/') {\n state = AUTHORITY;\n break;\n } else {\n state = PATH;\n continue;\n }\n\n case RELATIVE:\n url.scheme = base.scheme;\n if (char == EOF) {\n url.username = base.username;\n url.password = base.password;\n url.host = base.host;\n url.port = base.port;\n url.path = base.path.slice();\n url.query = base.query;\n } else if (char == '/' || (char == '\\\\' && isSpecial(url))) {\n state = RELATIVE_SLASH;\n } else if (char == '?') {\n url.username = base.username;\n url.password = base.password;\n url.host = base.host;\n url.port = base.port;\n url.path = base.path.slice();\n url.query = '';\n state = QUERY;\n } else if (char == '#') {\n url.username = base.username;\n url.password = base.password;\n url.host = base.host;\n url.port = base.port;\n url.path = base.path.slice();\n url.query = base.query;\n url.fragment = '';\n state = FRAGMENT;\n } else {\n url.username = base.username;\n url.password = base.password;\n url.host = base.host;\n url.port = base.port;\n url.path = base.path.slice();\n url.path.pop();\n state = PATH;\n continue;\n } break;\n\n case RELATIVE_SLASH:\n if (isSpecial(url) && (char == '/' || char == '\\\\')) {\n state = SPECIAL_AUTHORITY_IGNORE_SLASHES;\n } else if (char == '/') {\n state = AUTHORITY;\n } else {\n url.username = base.username;\n url.password = base.password;\n url.host = base.host;\n url.port = base.port;\n state = PATH;\n continue;\n } break;\n\n case SPECIAL_AUTHORITY_SLASHES:\n state = SPECIAL_AUTHORITY_IGNORE_SLASHES;\n if (char != '/' || buffer.charAt(pointer + 1) != '/') continue;\n pointer++;\n break;\n\n case SPECIAL_AUTHORITY_IGNORE_SLASHES:\n if (char != '/' && char != '\\\\') {\n state = AUTHORITY;\n continue;\n } break;\n\n case AUTHORITY:\n if (char == '@') {\n if (seenAt) buffer = '%40' + buffer;\n seenAt = true;\n bufferCodePoints = arrayFrom(buffer);\n for (var i = 0; i < bufferCodePoints.length; i++) {\n var codePoint = bufferCodePoints[i];\n if (codePoint == ':' && !seenPasswordToken) {\n seenPasswordToken = true;\n continue;\n }\n var encodedCodePoints = percentEncode(codePoint, userinfoPercentEncodeSet);\n if (seenPasswordToken) url.password += encodedCodePoints;\n else url.username += encodedCodePoints;\n }\n buffer = '';\n } else if (\n char == EOF || char == '/' || char == '?' || char == '#' ||\n (char == '\\\\' && isSpecial(url))\n ) {\n if (seenAt && buffer == '') return INVALID_AUTHORITY;\n pointer -= arrayFrom(buffer).length + 1;\n buffer = '';\n state = HOST;\n } else buffer += char;\n break;\n\n case HOST:\n case HOSTNAME:\n if (stateOverride && url.scheme == 'file') {\n state = FILE_HOST;\n continue;\n } else if (char == ':' && !seenBracket) {\n if (buffer == '') return INVALID_HOST;\n failure = parseHost(url, buffer);\n if (failure) return failure;\n buffer = '';\n state = PORT;\n if (stateOverride == HOSTNAME) return;\n } else if (\n char == EOF || char == '/' || char == '?' || char == '#' ||\n (char == '\\\\' && isSpecial(url))\n ) {\n if (isSpecial(url) && buffer == '') return INVALID_HOST;\n if (stateOverride && buffer == '' && (includesCredentials(url) || url.port !== null)) return;\n failure = parseHost(url, buffer);\n if (failure) return failure;\n buffer = '';\n state = PATH_START;\n if (stateOverride) return;\n continue;\n } else {\n if (char == '[') seenBracket = true;\n else if (char == ']') seenBracket = false;\n buffer += char;\n } break;\n\n case PORT:\n if (DIGIT.test(char)) {\n buffer += char;\n } else if (\n char == EOF || char == '/' || char == '?' || char == '#' ||\n (char == '\\\\' && isSpecial(url)) ||\n stateOverride\n ) {\n if (buffer != '') {\n var port = parseInt(buffer, 10);\n if (port > 0xFFFF) return INVALID_PORT;\n url.port = (isSpecial(url) && port === specialSchemes[url.scheme]) ? null : port;\n buffer = '';\n }\n if (stateOverride) return;\n state = PATH_START;\n continue;\n } else return INVALID_PORT;\n break;\n\n case FILE:\n url.scheme = 'file';\n if (char == '/' || char == '\\\\') state = FILE_SLASH;\n else if (base && base.scheme == 'file') {\n if (char == EOF) {\n url.host = base.host;\n url.path = base.path.slice();\n url.query = base.query;\n } else if (char == '?') {\n url.host = base.host;\n url.path = base.path.slice();\n url.query = '';\n state = QUERY;\n } else if (char == '#') {\n url.host = base.host;\n url.path = base.path.slice();\n url.query = base.query;\n url.fragment = '';\n state = FRAGMENT;\n } else {\n if (!startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {\n url.host = base.host;\n url.path = base.path.slice();\n shortenURLsPath(url);\n }\n state = PATH;\n continue;\n }\n } else {\n state = PATH;\n continue;\n } break;\n\n case FILE_SLASH:\n if (char == '/' || char == '\\\\') {\n state = FILE_HOST;\n break;\n }\n if (base && base.scheme == 'file' && !startsWithWindowsDriveLetter(codePoints.slice(pointer).join(''))) {\n if (isWindowsDriveLetter(base.path[0], true)) url.path.push(base.path[0]);\n else url.host = base.host;\n }\n state = PATH;\n continue;\n\n case FILE_HOST:\n if (char == EOF || char == '/' || char == '\\\\' || char == '?' || char == '#') {\n if (!stateOverride && isWindowsDriveLetter(buffer)) {\n state = PATH;\n } else if (buffer == '') {\n url.host = '';\n if (stateOverride) return;\n state = PATH_START;\n } else {\n failure = parseHost(url, buffer);\n if (failure) return failure;\n if (url.host == 'localhost') url.host = '';\n if (stateOverride) return;\n buffer = '';\n state = PATH_START;\n } continue;\n } else buffer += char;\n break;\n\n case PATH_START:\n if (isSpecial(url)) {\n state = PATH;\n if (char != '/' && char != '\\\\') continue;\n } else if (!stateOverride && char == '?') {\n url.query = '';\n state = QUERY;\n } else if (!stateOverride && char == '#') {\n url.fragment = '';\n state = FRAGMENT;\n } else if (char != EOF) {\n state = PATH;\n if (char != '/') continue;\n } break;\n\n case PATH:\n if (\n char == EOF || char == '/' ||\n (char == '\\\\' && isSpecial(url)) ||\n (!stateOverride && (char == '?' || char == '#'))\n ) {\n if (isDoubleDot(buffer)) {\n shortenURLsPath(url);\n if (char != '/' && !(char == '\\\\' && isSpecial(url))) {\n url.path.push('');\n }\n } else if (isSingleDot(buffer)) {\n if (char != '/' && !(char == '\\\\' && isSpecial(url))) {\n url.path.push('');\n }\n } else {\n if (url.scheme == 'file' && !url.path.length && isWindowsDriveLetter(buffer)) {\n if (url.host) url.host = '';\n buffer = buffer.charAt(0) + ':'; // normalize windows drive letter\n }\n url.path.push(buffer);\n }\n buffer = '';\n if (url.scheme == 'file' && (char == EOF || char == '?' || char == '#')) {\n while (url.path.length > 1 && url.path[0] === '') {\n url.path.shift();\n }\n }\n if (char == '?') {\n url.query = '';\n state = QUERY;\n } else if (char == '#') {\n url.fragment = '';\n state = FRAGMENT;\n }\n } else {\n buffer += percentEncode(char, pathPercentEncodeSet);\n } break;\n\n case CANNOT_BE_A_BASE_URL_PATH:\n if (char == '?') {\n url.query = '';\n state = QUERY;\n } else if (char == '#') {\n url.fragment = '';\n state = FRAGMENT;\n } else if (char != EOF) {\n url.path[0] += percentEncode(char, C0ControlPercentEncodeSet);\n } break;\n\n case QUERY:\n if (!stateOverride && char == '#') {\n url.fragment = '';\n state = FRAGMENT;\n } else if (char != EOF) {\n if (char == \"'\" && isSpecial(url)) url.query += '%27';\n else if (char == '#') url.query += '%23';\n else url.query += percentEncode(char, C0ControlPercentEncodeSet);\n } break;\n\n case FRAGMENT:\n if (char != EOF) url.fragment += percentEncode(char, fragmentPercentEncodeSet);\n break;\n }\n\n pointer++;\n }\n};\n\n// `URL` constructor\n// https://url.spec.whatwg.org/#url-class\nvar URLConstructor = function URL(url /* , base */) {\n var that = anInstance(this, URLConstructor, 'URL');\n var base = arguments.length > 1 ? arguments[1] : undefined;\n var urlString = String(url);\n var state = setInternalState(that, { type: 'URL' });\n var baseState, failure;\n if (base !== undefined) {\n if (base instanceof URLConstructor) baseState = getInternalURLState(base);\n else {\n failure = parseURL(baseState = {}, String(base));\n if (failure) throw TypeError(failure);\n }\n }\n failure = parseURL(state, urlString, null, baseState);\n if (failure) throw TypeError(failure);\n var searchParams = state.searchParams = new URLSearchParams();\n var searchParamsState = getInternalSearchParamsState(searchParams);\n searchParamsState.updateSearchParams(state.query);\n searchParamsState.updateURL = function () {\n state.query = String(searchParams) || null;\n };\n if (!DESCRIPTORS) {\n that.href = serializeURL.call(that);\n that.origin = getOrigin.call(that);\n that.protocol = getProtocol.call(that);\n that.username = getUsername.call(that);\n that.password = getPassword.call(that);\n that.host = getHost.call(that);\n that.hostname = getHostname.call(that);\n that.port = getPort.call(that);\n that.pathname = getPathname.call(that);\n that.search = getSearch.call(that);\n that.searchParams = getSearchParams.call(that);\n that.hash = getHash.call(that);\n }\n};\n\nvar URLPrototype = URLConstructor.prototype;\n\nvar serializeURL = function () {\n var url = getInternalURLState(this);\n var scheme = url.scheme;\n var username = url.username;\n var password = url.password;\n var host = url.host;\n var port = url.port;\n var path = url.path;\n var query = url.query;\n var fragment = url.fragment;\n var output = scheme + ':';\n if (host !== null) {\n output += '//';\n if (includesCredentials(url)) {\n output += username + (password ? ':' + password : '') + '@';\n }\n output += serializeHost(host);\n if (port !== null) output += ':' + port;\n } else if (scheme == 'file') output += '//';\n output += url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';\n if (query !== null) output += '?' + query;\n if (fragment !== null) output += '#' + fragment;\n return output;\n};\n\nvar getOrigin = function () {\n var url = getInternalURLState(this);\n var scheme = url.scheme;\n var port = url.port;\n if (scheme == 'blob') try {\n return new URL(scheme.path[0]).origin;\n } catch (error) {\n return 'null';\n }\n if (scheme == 'file' || !isSpecial(url)) return 'null';\n return scheme + '://' + serializeHost(url.host) + (port !== null ? ':' + port : '');\n};\n\nvar getProtocol = function () {\n return getInternalURLState(this).scheme + ':';\n};\n\nvar getUsername = function () {\n return getInternalURLState(this).username;\n};\n\nvar getPassword = function () {\n return getInternalURLState(this).password;\n};\n\nvar getHost = function () {\n var url = getInternalURLState(this);\n var host = url.host;\n var port = url.port;\n return host === null ? ''\n : port === null ? serializeHost(host)\n : serializeHost(host) + ':' + port;\n};\n\nvar getHostname = function () {\n var host = getInternalURLState(this).host;\n return host === null ? '' : serializeHost(host);\n};\n\nvar getPort = function () {\n var port = getInternalURLState(this).port;\n return port === null ? '' : String(port);\n};\n\nvar getPathname = function () {\n var url = getInternalURLState(this);\n var path = url.path;\n return url.cannotBeABaseURL ? path[0] : path.length ? '/' + path.join('/') : '';\n};\n\nvar getSearch = function () {\n var query = getInternalURLState(this).query;\n return query ? '?' + query : '';\n};\n\nvar getSearchParams = function () {\n return getInternalURLState(this).searchParams;\n};\n\nvar getHash = function () {\n var fragment = getInternalURLState(this).fragment;\n return fragment ? '#' + fragment : '';\n};\n\nvar accessorDescriptor = function (getter, setter) {\n return { get: getter, set: setter, configurable: true, enumerable: true };\n};\n\nif (DESCRIPTORS) {\n defineProperties(URLPrototype, {\n // `URL.prototype.href` accessors pair\n // https://url.spec.whatwg.org/#dom-url-href\n href: accessorDescriptor(serializeURL, function (href) {\n var url = getInternalURLState(this);\n var urlString = String(href);\n var failure = parseURL(url, urlString);\n if (failure) throw TypeError(failure);\n getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);\n }),\n // `URL.prototype.origin` getter\n // https://url.spec.whatwg.org/#dom-url-origin\n origin: accessorDescriptor(getOrigin),\n // `URL.prototype.protocol` accessors pair\n // https://url.spec.whatwg.org/#dom-url-protocol\n protocol: accessorDescriptor(getProtocol, function (protocol) {\n var url = getInternalURLState(this);\n parseURL(url, String(protocol) + ':', SCHEME_START);\n }),\n // `URL.prototype.username` accessors pair\n // https://url.spec.whatwg.org/#dom-url-username\n username: accessorDescriptor(getUsername, function (username) {\n var url = getInternalURLState(this);\n var codePoints = arrayFrom(String(username));\n if (cannotHaveUsernamePasswordPort(url)) return;\n url.username = '';\n for (var i = 0; i < codePoints.length; i++) {\n url.username += percentEncode(codePoints[i], userinfoPercentEncodeSet);\n }\n }),\n // `URL.prototype.password` accessors pair\n // https://url.spec.whatwg.org/#dom-url-password\n password: accessorDescriptor(getPassword, function (password) {\n var url = getInternalURLState(this);\n var codePoints = arrayFrom(String(password));\n if (cannotHaveUsernamePasswordPort(url)) return;\n url.password = '';\n for (var i = 0; i < codePoints.length; i++) {\n url.password += percentEncode(codePoints[i], userinfoPercentEncodeSet);\n }\n }),\n // `URL.prototype.host` accessors pair\n // https://url.spec.whatwg.org/#dom-url-host\n host: accessorDescriptor(getHost, function (host) {\n var url = getInternalURLState(this);\n if (url.cannotBeABaseURL) return;\n parseURL(url, String(host), HOST);\n }),\n // `URL.prototype.hostname` accessors pair\n // https://url.spec.whatwg.org/#dom-url-hostname\n hostname: accessorDescriptor(getHostname, function (hostname) {\n var url = getInternalURLState(this);\n if (url.cannotBeABaseURL) return;\n parseURL(url, String(hostname), HOSTNAME);\n }),\n // `URL.prototype.port` accessors pair\n // https://url.spec.whatwg.org/#dom-url-port\n port: accessorDescriptor(getPort, function (port) {\n var url = getInternalURLState(this);\n if (cannotHaveUsernamePasswordPort(url)) return;\n port = String(port);\n if (port == '') url.port = null;\n else parseURL(url, port, PORT);\n }),\n // `URL.prototype.pathname` accessors pair\n // https://url.spec.whatwg.org/#dom-url-pathname\n pathname: accessorDescriptor(getPathname, function (pathname) {\n var url = getInternalURLState(this);\n if (url.cannotBeABaseURL) return;\n url.path = [];\n parseURL(url, pathname + '', PATH_START);\n }),\n // `URL.prototype.search` accessors pair\n // https://url.spec.whatwg.org/#dom-url-search\n search: accessorDescriptor(getSearch, function (search) {\n var url = getInternalURLState(this);\n search = String(search);\n if (search == '') {\n url.query = null;\n } else {\n if ('?' == search.charAt(0)) search = search.slice(1);\n url.query = '';\n parseURL(url, search, QUERY);\n }\n getInternalSearchParamsState(url.searchParams).updateSearchParams(url.query);\n }),\n // `URL.prototype.searchParams` getter\n // https://url.spec.whatwg.org/#dom-url-searchparams\n searchParams: accessorDescriptor(getSearchParams),\n // `URL.prototype.hash` accessors pair\n // https://url.spec.whatwg.org/#dom-url-hash\n hash: accessorDescriptor(getHash, function (hash) {\n var url = getInternalURLState(this);\n hash = String(hash);\n if (hash == '') {\n url.fragment = null;\n return;\n }\n if ('#' == hash.charAt(0)) hash = hash.slice(1);\n url.fragment = '';\n parseURL(url, hash, FRAGMENT);\n })\n });\n}\n\n// `URL.prototype.toJSON` method\n// https://url.spec.whatwg.org/#dom-url-tojson\nredefine(URLPrototype, 'toJSON', function toJSON() {\n return serializeURL.call(this);\n}, { enumerable: true });\n\n// `URL.prototype.toString` method\n// https://url.spec.whatwg.org/#URL-stringification-behavior\nredefine(URLPrototype, 'toString', function toString() {\n return serializeURL.call(this);\n}, { enumerable: true });\n\nif (NativeURL) {\n var nativeCreateObjectURL = NativeURL.createObjectURL;\n var nativeRevokeObjectURL = NativeURL.revokeObjectURL;\n // `URL.createObjectURL` method\n // https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL\n // eslint-disable-next-line no-unused-vars\n if (nativeCreateObjectURL) redefine(URLConstructor, 'createObjectURL', function createObjectURL(blob) {\n return nativeCreateObjectURL.apply(NativeURL, arguments);\n });\n // `URL.revokeObjectURL` method\n // https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL\n // eslint-disable-next-line no-unused-vars\n if (nativeRevokeObjectURL) redefine(URLConstructor, 'revokeObjectURL', function revokeObjectURL(url) {\n return nativeRevokeObjectURL.apply(NativeURL, arguments);\n });\n}\n\nsetToStringTag(URLConstructor, 'URL');\n\n$({ global: true, forced: !USE_NATIVE_URL, sham: !DESCRIPTORS }, {\n URL: URLConstructor\n});\n","import { replaceHtml } from '../utils/util';\r\nimport { modelHTML } from './constant';\r\nimport { selectHightlightShow } from './select';\r\nimport tooltip from '../global/tooltip';\r\nimport editor from '../global/editor';\r\nimport { setcellvalue } from '../global/setdata';\r\nimport { getcellvalue } from '../global/getdata';\r\nimport { jfrefreshgrid } from '../global/refresh';\r\nimport Store from '../store';\r\nimport locale from '../locale/locale';\r\n\r\n//分列\r\nconst luckysheetSplitColumn = {\r\n createDialog: function(){\r\n let _this = this;\r\n\r\n const _locale = locale();\r\n const locale_splitText = _locale.splitText;\r\n const locale_punctuation = _locale.punctuation;\r\n const locale_button = _locale.button;\r\n\r\n $(\"#luckysheet-modal-dialog-mask\").show();\r\n $(\"#luckysheet-splitColumn-dialog\").remove();\r\n\r\n let content = '
' +\r\n '
'+locale_splitText.splitDelimiters+'
' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
'+ locale_splitText.splitDataPreview +'
' +\r\n '
' +\r\n\r\n '
' +\r\n '
';\r\n\r\n $(\"body\").append(replaceHtml(modelHTML, { \r\n \"id\": \"luckysheet-splitColumn-dialog\", \r\n \"addclass\": \"luckysheet-splitColumn-dialog\", \r\n \"title\": locale_splitText.splitTextTitle, \r\n \"content\": content, \r\n \"botton\": '', \r\n \"style\": \"z-index:100003\" \r\n }));\r\n let $t = $(\"#luckysheet-splitColumn-dialog\").find(\".luckysheet-modal-dialog-content\").css(\"min-width\", 400).end(), \r\n myh = $t.outerHeight(), \r\n myw = $t.outerWidth();\r\n let winw = $(window).width(), winh = $(window).height();\r\n let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop();\r\n $(\"#luckysheet-splitColumn-dialog\").css({ \"left\": (winw + scrollLeft - myw) / 2, \"top\": (winh + scrollTop - myh) / 3 }).show();\r\n\r\n let dataArr = _this.getDataArr();\r\n _this.dataPreview(dataArr);\r\n },\r\n init: function(){\r\n let _this = this;\r\n const _locale = locale();\r\n const locale_splitText = _locale.splitText;\r\n\r\n //数据预览\r\n $(document).off(\"change.SPCinpcheckbox\").on(\"change.SPCcheckbox\", \"#luckysheet-splitColumn-dialog .box input[type='checkbox']\", function(){\r\n let regStr = _this.getRegStr();\r\n let dataArr = _this.getDataArr(regStr);\r\n _this.dataPreview(dataArr);\r\n });\r\n $(document).off(\"keyup.SPCinptext\").on(\"keyup.SPCinptext\", \"#luckysheet-splitColumn-dialog .box input[type='text']\", function(){\r\n if($(this).siblings(\"input[type='checkbox']\").is(\":checked\")){\r\n let regStr = _this.getRegStr();\r\n let dataArr = _this.getDataArr(regStr);\r\n _this.dataPreview(dataArr);\r\n }\r\n })\r\n\r\n //确定按钮\r\n $(document).off(\"click.SPCconfirm\").on(\"click.SPCconfirm\", \"#luckysheet-splitColumn-dialog #luckysheet-splitColumn-dialog-confirm\", function(){\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n $(\"#luckysheet-splitColumn-dialog\").hide();\r\n\r\n let regStr = _this.getRegStr();\r\n let dataArr = _this.getDataArr(regStr);\r\n\r\n let r = Store.luckysheet_select_save[0].row[0];\r\n let c = Store.luckysheet_select_save[0].column[0];\r\n\r\n if(dataArr[0].length == 1){\r\n return;\r\n }\r\n\r\n let dataCover = false;\r\n for(let i = 0; i < dataArr.length; i++){\r\n for(let j = 1; j < dataArr[0].length; j++){\r\n let cell = Store.flowdata[r + i][c + j];\r\n\r\n if(cell != null && cell.v != null){\r\n dataCover = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if(dataCover){\r\n let func1 = function(){\r\n _this.update(r, c, dataArr);\r\n } \r\n\r\n tooltip.confirm(\"\", locale_splitText.splitConfirmToExe, func1);\r\n }\r\n else{\r\n _this.update(r, c, dataArr);\r\n }\r\n });\r\n },\r\n update: function(r, c, dataArr){\r\n let d = editor.deepCopyFlowData(Store.flowdata);\r\n\r\n for(let i = 0; i < dataArr.length; i++){\r\n for(let j = 0; j < dataArr[0].length; j++){\r\n let v = dataArr[i][j];\r\n setcellvalue(r + i, c + j, d, v);\r\n }\r\n }\r\n\r\n let st_r = Store.luckysheet_select_save[0].row[0], \r\n st_c = Store.luckysheet_select_save[0].column[0];\r\n\r\n let range = [{ \"row\": [st_r, st_r + dataArr.length - 1], \"column\": [st_c, st_c + dataArr[0].length - 1] }]\r\n\r\n jfrefreshgrid(d, range);\r\n selectHightlightShow();\r\n },\r\n dataPreview: function(dataArr){\r\n $(\"#luckysheet-splitColumn-dialog #splitColumnData\").empty();\r\n\r\n let trHtml = '';\r\n\r\n for(let i = 0; i < dataArr.length; i++){\r\n let tdHtml = '';\r\n\r\n for(let j = 0; j < dataArr[0].length; j++){\r\n tdHtml += '' + dataArr[i][j] + '';\r\n }\r\n\r\n trHtml += '' + tdHtml + '';\r\n }\r\n\r\n let tableHtml = '' + trHtml + '
';\r\n\r\n $(\"#luckysheet-splitColumn-dialog #splitColumnData\").append(tableHtml);\r\n },\r\n getRegStr: function(){\r\n let regStr = '', mark = 0;\r\n\r\n $(\"#luckysheet-splitColumn-dialog .box input[type='checkbox']:checked\").each(function(i, e){\r\n let $id = $(e).attr(\"id\");\r\n\r\n if($id == \"splitColumn_type_01\"){ //Tab键\r\n regStr += \"\\\\t\";\r\n mark++;\r\n }\r\n else if($id == \"splitColumn_type_02\"){ //分号\r\n if(mark > 0){\r\n regStr += \"|\";\r\n }\r\n\r\n regStr += \";\";\r\n mark++;\r\n }\r\n else if($id == \"splitColumn_type_03\"){ //逗号\r\n if(mark > 0){\r\n regStr += \"|\";\r\n }\r\n\r\n regStr += \",\";\r\n mark++;\r\n }\r\n else if($id == \"splitColumn_type_04\"){ //空格\r\n if(mark > 0){\r\n regStr += \"|\";\r\n }\r\n\r\n regStr += \"\\\\s\";\r\n mark++;\r\n }\r\n else if($id == \"splitColumn_type_05\"){ //其它\r\n let txt = $(e).siblings(\"input[type='text']\").val().trim();\r\n\r\n if(txt != \"\"){\r\n if(mark > 0){\r\n regStr += \"|\";\r\n }\r\n\r\n regStr += txt;\r\n }\r\n }\r\n else if($id == \"splitColumn_type_06\"){ //连续分隔符号视为单个处理\r\n regStr = \"[\" + regStr + \"]+\";\r\n }\r\n })\r\n\r\n return regStr;\r\n },\r\n getDataArr: function(regStr){\r\n let _this = this;\r\n\r\n let arr = [];\r\n\r\n let r1 = Store.luckysheet_select_save[0].row[0];\r\n let r2 = Store.luckysheet_select_save[0].row[1];\r\n let c = Store.luckysheet_select_save[0].column[0];\r\n\r\n if(regStr != null && regStr != \"\"){\r\n let reg = new RegExp(regStr, \"g\");\r\n\r\n let dataArr = [];\r\n\r\n for(let r = r1; r <= r2; r++){\r\n let rowArr = [];\r\n\r\n let cell = Store.flowdata[r][c];\r\n\r\n let value;\r\n if(cell != null && cell[\"m\"] != null){\r\n value = cell[\"m\"];\r\n }\r\n else{\r\n value = getcellvalue(r, c, Store.flowdata);\r\n }\r\n\r\n if(value == null){\r\n value = \"\";\r\n }\r\n\r\n rowArr = value.toString().split(reg);\r\n\r\n dataArr.push(rowArr);\r\n }\r\n\r\n let rlen = dataArr.length;\r\n let clen = 0;\r\n\r\n for(let i = 0; i < rlen; i++){\r\n if(dataArr[i].length > clen){\r\n clen = dataArr[i].length;\r\n }\r\n }\r\n\r\n arr = _this.getNullData(rlen, clen);\r\n\r\n for(let i = 0; i < arr.length; i++){\r\n for(let j = 0; j < arr[0].length; j++){\r\n if(dataArr[i][j] != null){\r\n arr[i][j] = dataArr[i][j];\r\n }\r\n }\r\n }\r\n }\r\n else{\r\n for(let r = r1; r <= r2; r++){\r\n let rowArr = [];\r\n\r\n let cell = Store.flowdata[r][c];\r\n\r\n let value;\r\n if(cell != null && cell[\"m\"] != null){\r\n value = cell[\"m\"];\r\n }\r\n else{\r\n value = getcellvalue(r, c, Store.flowdata);\r\n }\r\n\r\n if(value == null){\r\n value = \"\";\r\n }\r\n\r\n rowArr.push(value);\r\n\r\n arr.push(rowArr);\r\n }\r\n }\r\n\r\n return arr;\r\n },\r\n getNullData: function(rlen, clen){\r\n let arr = [];\r\n\r\n for(let r = 0; r < rlen; r++){\r\n let rowArr = [];\r\n\r\n for(let c = 0; c < clen; c++){\r\n rowArr.push(\"\");\r\n }\r\n\r\n arr.push(rowArr);\r\n }\r\n\r\n return arr;\r\n }\r\n}\r\n\r\nexport default luckysheetSplitColumn;","import Store from '../store';\r\nimport { replaceHtml,transformRangeToAbsolute,openSelfModel } from '../utils/util';\r\nimport { modelHTML } from './constant';\r\nimport sheetmanage from './sheetmanage';\r\nimport menuButton from './menuButton';\r\nimport {checkProtectionNotEnable} from './protection';\r\nimport { jfrefreshgrid } from '../global/refresh';\r\nimport locale from '../locale/locale';\r\nimport { setcellvalue } from '../global/setdata';\r\n\r\n\r\nlet isInitialCellFormatModel = false;\r\n\r\nfunction initialCellFormatModelEvent(){\r\n const _locale = locale();\r\n const local_cellFormat = _locale.cellFormat;\r\n\r\n $(\"#luckysheet-cellFormat-confirm\").click(function(){\r\n let locked = $(\"#luckysheet-protection-check-locked\").is(':checked');\r\n let hidden = $(\"#luckysheet-protection-check-hidden\").is(':checked');\r\n \r\n locked = locked==true?1:0;\r\n hidden = hidden==true?1:0;\r\n\r\n let d = recycleSeletion(\r\n function(cell, r, c, data){\r\n if(cell==null){\r\n setcellvalue(r, c, data, {\r\n lo:locked,\r\n hi:hidden\r\n });\r\n }\r\n else{\r\n cell.lo = locked;\r\n cell.hi = hidden;\r\n }\r\n },\r\n function(){\r\n alert(local_cellFormat.sheetDataIsNullAlert);\r\n }\r\n );\r\n\r\n jfrefreshgrid(d, undefined, undefined, false);\r\n\r\n $(\"#luckysheet-cellFormat-config\").hide();\r\n $(\"#luckysheet-modal-dialog-mask\").hide();\r\n });\r\n}\r\n\r\nfunction recycleSeletion(cycleFunction, dataIsNullFunction){\r\n if(Store.luckysheet_select_save != null && Store.luckysheet_select_save.length > 0){\r\n let sheetFile = sheetmanage.getSheetByIndex(), data=sheetFile.data;\r\n if(data!=null){\r\n \r\n for(let i=0;i